@barocss/kit 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1496 -877
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -19
- package/dist/index.d.ts +23 -19
- package/dist/index.js +1495 -878
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -271,250 +271,574 @@ function clearContextCaches(ctx) {
|
|
|
271
271
|
state.failures.clear();
|
|
272
272
|
}
|
|
273
273
|
//#endregion
|
|
274
|
-
//#region src/core/
|
|
275
|
-
var utilityRegistry = [];
|
|
276
|
-
function registerUtility(util, ctx) {
|
|
277
|
-
const state = ctx && getContextState(ctx);
|
|
278
|
-
if (ctx && !state) throw new Error("Utility registration requires a context from createContext");
|
|
279
|
-
(state?.utilities || utilityRegistry).push(util);
|
|
280
|
-
if (ctx) clearContextCaches(ctx);
|
|
281
|
-
else {
|
|
282
|
-
parseResultCache.clear();
|
|
283
|
-
utilityCache.clear();
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
function getUtility(ctx) {
|
|
287
|
-
return ctx && getContextState(ctx)?.utilities || utilityRegistry;
|
|
288
|
-
}
|
|
289
|
-
var modifierRegistry = [];
|
|
274
|
+
//#region src/core/utils.ts
|
|
290
275
|
/**
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
* @example
|
|
294
|
-
* ```
|
|
295
|
-
* staticModifier('disabled', ['&:disabled'], { source: 'pseudo' });
|
|
296
|
-
* ```
|
|
297
|
-
*
|
|
298
|
-
* @param name The name of the modifier
|
|
299
|
-
* @param selectors The selectors of the modifier
|
|
300
|
-
* @param options The options of the modifier
|
|
301
|
-
*
|
|
302
|
-
* @returns {void}
|
|
276
|
+
* Parses a fraction string (e.g., '1/2') and returns a percentage string (e.g., '50%'), or null if not a valid fraction.
|
|
303
277
|
*/
|
|
304
|
-
function
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
modifySelector: ({ ..._rest }) => {
|
|
309
|
-
return selectors.map((sel) => ({
|
|
310
|
-
selector: sel,
|
|
311
|
-
source: options.source
|
|
312
|
-
}));
|
|
313
|
-
},
|
|
314
|
-
...options
|
|
315
|
-
}, ctx);
|
|
316
|
-
}
|
|
317
|
-
function functionalModifier(match, modifySelector, wrap, options = {}, ctx) {
|
|
318
|
-
registerModifier({
|
|
319
|
-
match,
|
|
320
|
-
modifySelector,
|
|
321
|
-
wrap,
|
|
322
|
-
...options
|
|
323
|
-
}, ctx);
|
|
324
|
-
}
|
|
325
|
-
function registerModifier(modifier, ctx) {
|
|
326
|
-
const state = ctx && getContextState(ctx);
|
|
327
|
-
if (ctx && !state) throw new Error("Modifier registration requires a context from createContext");
|
|
328
|
-
(state?.modifiers || modifierRegistry).push(modifier);
|
|
329
|
-
if (ctx) clearContextCaches(ctx);
|
|
330
|
-
}
|
|
331
|
-
function getModifier(ctx) {
|
|
332
|
-
return ctx && getContextState(ctx)?.modifiers || modifierRegistry;
|
|
333
|
-
}
|
|
334
|
-
var ESCAPE_REGEX = /[^A-Za-z0-9_-]/g;
|
|
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));
|
|
278
|
+
function parseFraction(input) {
|
|
279
|
+
if (input.includes("/")) {
|
|
280
|
+
const [num, denom] = input.split("/").map(Number);
|
|
281
|
+
if (!isNaN(num) && !isNaN(denom) && denom !== 0) return `${num / denom * 100}%`;
|
|
341
282
|
}
|
|
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
|
-
return "\\" + c;
|
|
378
|
-
});
|
|
283
|
+
return null;
|
|
379
284
|
}
|
|
380
285
|
/**
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
* @example
|
|
384
|
-
* ```
|
|
385
|
-
* staticUtility('block', [['display', 'block']]);
|
|
386
|
-
* staticUtility('hidden', [['display', 'none']]);
|
|
387
|
-
* staticUtility('space-x-px', [
|
|
388
|
-
* [
|
|
389
|
-
* '& > :not([hidden]) ~ :not([hidden])', // selector
|
|
390
|
-
* [
|
|
391
|
-
* ['margin-inline-start', '1px'], // [prop, value]
|
|
392
|
-
* ['margin-inline-end', '1px'], // [prop, value]
|
|
393
|
-
* ],
|
|
394
|
-
* ],
|
|
395
|
-
* ]);
|
|
396
|
-
* ```
|
|
397
|
-
*
|
|
398
|
-
* @param name The name of the utility
|
|
399
|
-
* @param decls The declarations of the utility
|
|
400
|
-
* @param opts The options of the utility
|
|
286
|
+
* Returns the input if it is a valid non-negative integer string, else null.
|
|
401
287
|
*
|
|
402
|
-
* @
|
|
288
|
+
* @example
|
|
289
|
+
* parseNumber("10") // "10"
|
|
290
|
+
* parseNumber("-10") // "-10"
|
|
291
|
+
* parseNumber("10.5") // "10.5"
|
|
403
292
|
*/
|
|
404
|
-
function
|
|
405
|
-
|
|
406
|
-
name,
|
|
407
|
-
match: (className) => {
|
|
408
|
-
return className === name;
|
|
409
|
-
},
|
|
410
|
-
handler: (value) => {
|
|
411
|
-
return decls.flatMap((params) => {
|
|
412
|
-
if (params.type) return [params];
|
|
413
|
-
if (typeof params === "function") return [params(value)];
|
|
414
|
-
const [a, b] = params;
|
|
415
|
-
if (typeof b === "string") return [decl(a, b)];
|
|
416
|
-
else if (Array.isArray(b)) return [rule(a, b.map(([prop, value]) => decl(prop, value)))];
|
|
417
|
-
return [];
|
|
418
|
-
});
|
|
419
|
-
},
|
|
420
|
-
description: opts?.description,
|
|
421
|
-
category: opts?.category,
|
|
422
|
-
priority: opts?.priority
|
|
423
|
-
}, ctx);
|
|
293
|
+
function parseNumber(input) {
|
|
294
|
+
return /^-?\d+(?:\.\d+)?$/.test(input) ? input : null;
|
|
424
295
|
}
|
|
425
296
|
/**
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
* Example:
|
|
429
|
-
* functionalUtility({
|
|
430
|
-
* name: 'z',
|
|
431
|
-
* supportsNegative: true,
|
|
432
|
-
* themeKeys: ['--z-index'],
|
|
433
|
-
* handleBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
|
|
434
|
-
* handle: (value) => [decl('z-index', value)],
|
|
435
|
-
* description: 'z-index utility',
|
|
436
|
-
* category: 'layout',
|
|
437
|
-
* });
|
|
297
|
+
* Returns the input if it is a valid length string, else null.
|
|
438
298
|
*/
|
|
299
|
+
function parseLength(input) {
|
|
300
|
+
return /^\d+(px|em|rem|vh|vw|vmin|vmax|%|in|cm|mm|pt|pc|ex|ch|fr)$/.test(input) ? input : null;
|
|
301
|
+
}
|
|
439
302
|
/**
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
303
|
+
* Unified parser for fraction or number, with options for percent or repeat syntax.
|
|
304
|
+
* - percent: if true, returns percentage for fraction (e.g., '1/2' -> '50%')
|
|
305
|
+
* - repeat: if true, returns repeat() for number (e.g., '3' -> 'repeat(3, minmax(0, 1fr))')
|
|
443
306
|
*/
|
|
444
|
-
function
|
|
445
|
-
if (
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
return
|
|
458
|
-
}
|
|
459
|
-
/** #261: `var(--spacing-<key>)` for a named (non-numeric) `theme.spacing` key, else null. */
|
|
460
|
-
function spacingKeyValue(ctx, key, negative) {
|
|
461
|
-
if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
|
|
462
|
-
const ref = `var(--spacing-${key})`;
|
|
463
|
-
return negative ? `calc(${ref} * -1)` : ref;
|
|
307
|
+
function parseFractionOrNumber(value, opts = {}) {
|
|
308
|
+
if (/^\d+$/.test(value)) {
|
|
309
|
+
if (opts.repeat) return `repeat(${value}, minmax(0, 1fr))`;
|
|
310
|
+
return value;
|
|
311
|
+
}
|
|
312
|
+
if (value.includes("/")) {
|
|
313
|
+
const [numerator, denominator] = value.split("/").map(Number);
|
|
314
|
+
if (!isNaN(numerator) && !isNaN(denominator) && denominator !== 0) {
|
|
315
|
+
const result = numerator / denominator;
|
|
316
|
+
if (opts.percent) return `${result * 100}%`;
|
|
317
|
+
return result.toString();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
464
321
|
}
|
|
465
|
-
|
|
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
|
-
|
|
516
|
-
|
|
517
|
-
|
|
322
|
+
var CSS_COLOR_NAMES = /* @__PURE__ */ new Set([
|
|
323
|
+
"aliceblue",
|
|
324
|
+
"antiquewhite",
|
|
325
|
+
"aqua",
|
|
326
|
+
"aquamarine",
|
|
327
|
+
"azure",
|
|
328
|
+
"beige",
|
|
329
|
+
"bisque",
|
|
330
|
+
"black",
|
|
331
|
+
"blanchedalmond",
|
|
332
|
+
"blue",
|
|
333
|
+
"blueviolet",
|
|
334
|
+
"brown",
|
|
335
|
+
"burlywood",
|
|
336
|
+
"cadetblue",
|
|
337
|
+
"chartreuse",
|
|
338
|
+
"chocolate",
|
|
339
|
+
"coral",
|
|
340
|
+
"cornflowerblue",
|
|
341
|
+
"cornsilk",
|
|
342
|
+
"crimson",
|
|
343
|
+
"cyan",
|
|
344
|
+
"darkblue",
|
|
345
|
+
"darkcyan",
|
|
346
|
+
"darkgoldenrod",
|
|
347
|
+
"darkgray",
|
|
348
|
+
"darkgreen",
|
|
349
|
+
"darkgrey",
|
|
350
|
+
"darkkhaki",
|
|
351
|
+
"darkmagenta",
|
|
352
|
+
"darkolivegreen",
|
|
353
|
+
"darkorange",
|
|
354
|
+
"darkorchid",
|
|
355
|
+
"darkred",
|
|
356
|
+
"darksalmon",
|
|
357
|
+
"darkseagreen",
|
|
358
|
+
"darkslateblue",
|
|
359
|
+
"darkslategray",
|
|
360
|
+
"darkslategrey",
|
|
361
|
+
"darkturquoise",
|
|
362
|
+
"darkviolet",
|
|
363
|
+
"deeppink",
|
|
364
|
+
"deepskyblue",
|
|
365
|
+
"dimgray",
|
|
366
|
+
"dimgrey",
|
|
367
|
+
"dodgerblue",
|
|
368
|
+
"firebrick",
|
|
369
|
+
"floralwhite",
|
|
370
|
+
"forestgreen",
|
|
371
|
+
"fuchsia",
|
|
372
|
+
"gainsboro",
|
|
373
|
+
"ghostwhite",
|
|
374
|
+
"gold",
|
|
375
|
+
"goldenrod",
|
|
376
|
+
"gray",
|
|
377
|
+
"grey",
|
|
378
|
+
"green",
|
|
379
|
+
"greenyellow",
|
|
380
|
+
"honeydew",
|
|
381
|
+
"hotpink",
|
|
382
|
+
"indianred",
|
|
383
|
+
"indigo",
|
|
384
|
+
"ivory",
|
|
385
|
+
"khaki",
|
|
386
|
+
"lavender",
|
|
387
|
+
"lavenderblush",
|
|
388
|
+
"lawngreen",
|
|
389
|
+
"lemonchiffon",
|
|
390
|
+
"lightblue",
|
|
391
|
+
"lightcoral",
|
|
392
|
+
"lightcyan",
|
|
393
|
+
"lightgoldenrodyellow",
|
|
394
|
+
"lightgray",
|
|
395
|
+
"lightgreen",
|
|
396
|
+
"lightgrey",
|
|
397
|
+
"lightpink",
|
|
398
|
+
"lightsalmon",
|
|
399
|
+
"lightseagreen",
|
|
400
|
+
"lightskyblue",
|
|
401
|
+
"lightslategray",
|
|
402
|
+
"lightslategrey",
|
|
403
|
+
"lightsteelblue",
|
|
404
|
+
"lightyellow",
|
|
405
|
+
"lime",
|
|
406
|
+
"limegreen",
|
|
407
|
+
"linen",
|
|
408
|
+
"magenta",
|
|
409
|
+
"maroon",
|
|
410
|
+
"mediumaquamarine",
|
|
411
|
+
"mediumblue",
|
|
412
|
+
"mediumorchid",
|
|
413
|
+
"mediumpurple",
|
|
414
|
+
"mediumseagreen",
|
|
415
|
+
"mediumslateblue",
|
|
416
|
+
"mediumspringgreen",
|
|
417
|
+
"mediumturquoise",
|
|
418
|
+
"mediumvioletred",
|
|
419
|
+
"midnightblue",
|
|
420
|
+
"mintcream",
|
|
421
|
+
"mistyrose",
|
|
422
|
+
"moccasin",
|
|
423
|
+
"navajowhite",
|
|
424
|
+
"navy",
|
|
425
|
+
"oldlace",
|
|
426
|
+
"olive",
|
|
427
|
+
"olivedrab",
|
|
428
|
+
"orange",
|
|
429
|
+
"orangered",
|
|
430
|
+
"orchid",
|
|
431
|
+
"palegoldenrod",
|
|
432
|
+
"palegreen",
|
|
433
|
+
"paleturquoise",
|
|
434
|
+
"palevioletred",
|
|
435
|
+
"papayawhip",
|
|
436
|
+
"peachpuff",
|
|
437
|
+
"peru",
|
|
438
|
+
"pink",
|
|
439
|
+
"plum",
|
|
440
|
+
"powderblue",
|
|
441
|
+
"purple",
|
|
442
|
+
"red",
|
|
443
|
+
"rosybrown",
|
|
444
|
+
"royalblue",
|
|
445
|
+
"saddlebrown",
|
|
446
|
+
"salmon",
|
|
447
|
+
"sandybrown",
|
|
448
|
+
"seagreen",
|
|
449
|
+
"seashell",
|
|
450
|
+
"sienna",
|
|
451
|
+
"silver",
|
|
452
|
+
"skyblue",
|
|
453
|
+
"slateblue",
|
|
454
|
+
"slategray",
|
|
455
|
+
"slategrey",
|
|
456
|
+
"snow",
|
|
457
|
+
"springgreen",
|
|
458
|
+
"steelblue",
|
|
459
|
+
"tan",
|
|
460
|
+
"teal",
|
|
461
|
+
"thistle",
|
|
462
|
+
"tomato",
|
|
463
|
+
"turquoise",
|
|
464
|
+
"violet",
|
|
465
|
+
"wheat",
|
|
466
|
+
"white",
|
|
467
|
+
"whitesmoke",
|
|
468
|
+
"yellow",
|
|
469
|
+
"yellowgreen"
|
|
470
|
+
]);
|
|
471
|
+
/**
|
|
472
|
+
* Returns the input if it is a valid color string, else null.
|
|
473
|
+
*
|
|
474
|
+
* #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)
|
|
475
|
+
*/
|
|
476
|
+
function parseColor(input) {
|
|
477
|
+
if (CSS_COLOR_NAMES.has(input.toLowerCase())) return input;
|
|
478
|
+
if (input.startsWith("color:var(")) return input.slice(6);
|
|
479
|
+
if (input.startsWith("color:")) return parseColor(input.slice(6));
|
|
480
|
+
if (input.startsWith("#") && input.length === 4) return `#${input.slice(1)}`;
|
|
481
|
+
if (input.startsWith("#") && input.length === 5) return `#${input.slice(1)}`;
|
|
482
|
+
if (input.startsWith("#") && input.length === 7) return `#${input.slice(1)}`;
|
|
483
|
+
if (input.startsWith("#") && input.length === 9) return `#${input.slice(1)}`;
|
|
484
|
+
if (input.startsWith("rgb(")) return input.slice(4, -1);
|
|
485
|
+
if (input.startsWith("rgba(")) return input.slice(5, -1);
|
|
486
|
+
if (input.startsWith("hsl(")) return input.slice(4, -1);
|
|
487
|
+
if (input.startsWith("hsla(")) return input.slice(5, -1);
|
|
488
|
+
if (input.startsWith("hwb(")) return input.slice(4, -1);
|
|
489
|
+
if (input.startsWith("lab(")) return input.slice(4, -1);
|
|
490
|
+
if (input.startsWith("lch(")) return input.slice(4, -1);
|
|
491
|
+
if (input.startsWith("oklab(")) return input.slice(5, -1);
|
|
492
|
+
if (input.startsWith("oklch(")) return input.slice(6, -1);
|
|
493
|
+
if (input.startsWith("color-mix(")) return input.slice(9, -1);
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
var COLOR_KEYWORDS = /* @__PURE__ */ new Set([
|
|
497
|
+
"inherit",
|
|
498
|
+
"currentcolor",
|
|
499
|
+
"transparent"
|
|
500
|
+
]);
|
|
501
|
+
/**
|
|
502
|
+
* Declarations for a theme colour (#228), as Tailwind v4 emits them: `var(--color-<key>)` so runtime theme
|
|
503
|
+
* overrides apply; with an opacity modifier, a literal srgb color-mix fallback plus an oklab color-mix of the var.
|
|
504
|
+
*/
|
|
505
|
+
function themeColorDecls(prop, value, extra) {
|
|
506
|
+
const key = String(extra.realThemeValue);
|
|
507
|
+
const ref = COLOR_KEYWORDS.has(value.toLowerCase()) || value.startsWith("var(") || !/^[\w-]+$/.test(key) ? value : `var(--color-${key})`;
|
|
508
|
+
if (!extra.opacity) return [decl(prop, ref)];
|
|
509
|
+
const alpha = normalizeAlpha(String(extra.opacity));
|
|
510
|
+
if (!alpha) return [];
|
|
511
|
+
const supports = (amount) => atRule("supports", "(color:color-mix(in lab, red, red))", [decl(prop, `color-mix(in oklab, ${ref} ${amount}, transparent)`)]);
|
|
512
|
+
if (alpha.isVar) return [decl(prop, value), supports(alpha.amount)];
|
|
513
|
+
return [decl(prop, `color-mix(in srgb, ${value} ${alpha.amount}, transparent)`), supports(alpha.amount)];
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Opacity modifier → color-mix amount, as Tailwind v4 does: `50` → `50%`, `[37%]` → `37%`, `[0.5]` / `[.8]` → `50%` /
|
|
517
|
+
* `80%` (a bracketed number ≤ 1 is a fraction), `[var(--a)]` / `(--a)` → `var(--a)`.
|
|
518
|
+
*/
|
|
519
|
+
function normalizeAlpha(raw) {
|
|
520
|
+
const v = raw.trim();
|
|
521
|
+
const cp = /^\((--[\w-]+)\)$/.exec(v) ?? /^\[var\((--[\w-]+)\)\]$/.exec(v);
|
|
522
|
+
if (cp) return {
|
|
523
|
+
amount: `var(${cp[1]})`,
|
|
524
|
+
isVar: true
|
|
525
|
+
};
|
|
526
|
+
const m = /^(\[)?(\d+(?:\.\d+)?|\.\d+)(%)?(\])?$/.exec(v);
|
|
527
|
+
if (!m || !!m[1] !== !!m[4] || m[3] && !m[1]) return null;
|
|
528
|
+
const n = Number(m[2]);
|
|
529
|
+
return {
|
|
530
|
+
amount: `${+(m[3] ? n : m[1] && n <= 1 ? n * 100 : n).toFixed(4)}%`,
|
|
531
|
+
isVar: false
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
var MIX_SUPPORTS = "(color:color-mix(in lab, red, red))";
|
|
535
|
+
var COLOR_PROP = /(^|-)color$|^(fill|stroke)$|^--baro-gradient-(from|via|to)$/;
|
|
536
|
+
/**
|
|
537
|
+
* #393: an arbitrary or custom-property colour with an opacity modifier, as Tailwind 4.3.3 emits it: a literal
|
|
538
|
+
* colour with a literal alpha mixes directly (`color-mix(in oklab, #f00 50%, transparent)`); a var colour or a var
|
|
539
|
+
* alpha keeps the plain colour and mixes only under `@supports`. Returns null for an alpha it can't express.
|
|
540
|
+
*/
|
|
541
|
+
function colorAlphaDecls(prop, color, opacity) {
|
|
542
|
+
const alpha = normalizeAlpha(opacity);
|
|
543
|
+
if (!alpha) return null;
|
|
544
|
+
const mix = `color-mix(in oklab, ${color} ${alpha.amount}, transparent)`;
|
|
545
|
+
if (alpha.isVar || color.startsWith("var(")) return [decl(prop, color), atRule("supports", MIX_SUPPORTS, [decl(prop, mix)])];
|
|
546
|
+
return [decl(prop, mix)];
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* #393: applies an opacity modifier to every declaration of `nodes` whose value is one of `colors` (the colour an
|
|
550
|
+
* arbitrary / custom-property utility emitted without the modifier). Returns null when none matched or the alpha
|
|
551
|
+
* is invalid, so the caller emits nothing rather than dropping the modifier or writing a malformed value.
|
|
552
|
+
*/
|
|
553
|
+
function applyColorAlpha(nodes, colors, opacity) {
|
|
554
|
+
let matched = false;
|
|
555
|
+
let invalid = false;
|
|
556
|
+
const walk = (list) => list.flatMap((n) => {
|
|
557
|
+
if (n.type === "decl" && typeof n.value === "string" && colors.includes(n.value)) {
|
|
558
|
+
matched = true;
|
|
559
|
+
const out = COLOR_PROP.test(n.prop) ? colorAlphaDecls(n.prop, n.value, opacity) : null;
|
|
560
|
+
if (!out) invalid = true;
|
|
561
|
+
return out ?? [];
|
|
562
|
+
}
|
|
563
|
+
if (n.type === "at-rule" || n.type === "rule" || n.type === "style-rule" || n.type === "at-root") return [{
|
|
564
|
+
...n,
|
|
565
|
+
nodes: walk(n.nodes)
|
|
566
|
+
}];
|
|
567
|
+
if (n.type === "wrap") return [{
|
|
568
|
+
...n,
|
|
569
|
+
items: walk(n.items)
|
|
570
|
+
}];
|
|
571
|
+
return [n];
|
|
572
|
+
});
|
|
573
|
+
const out = walk(nodes);
|
|
574
|
+
return matched && !invalid ? out : null;
|
|
575
|
+
}
|
|
576
|
+
//#endregion
|
|
577
|
+
//#region src/core/registry.ts
|
|
578
|
+
/** #393: a handler result meaning "this class is invalid": the engine stops trying other registrations. */
|
|
579
|
+
var REJECT_CLASS = Object.freeze([]);
|
|
580
|
+
var utilityRegistry = [];
|
|
581
|
+
function registerUtility(util, ctx) {
|
|
582
|
+
const state = ctx && getContextState(ctx);
|
|
583
|
+
if (ctx && !state) throw new Error("Utility registration requires a context from createContext");
|
|
584
|
+
(state?.utilities || utilityRegistry).push(util);
|
|
585
|
+
if (ctx) clearContextCaches(ctx);
|
|
586
|
+
else {
|
|
587
|
+
parseResultCache.clear();
|
|
588
|
+
utilityCache.clear();
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
function getUtility(ctx) {
|
|
592
|
+
return ctx && getContextState(ctx)?.utilities || utilityRegistry;
|
|
593
|
+
}
|
|
594
|
+
var modifierRegistry = [];
|
|
595
|
+
/**
|
|
596
|
+
* staticModifier: A helper that registers a modifier name and an array of CSS selectors directly to the registry
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* ```
|
|
600
|
+
* staticModifier('disabled', ['&:disabled'], { source: 'pseudo' });
|
|
601
|
+
* ```
|
|
602
|
+
*
|
|
603
|
+
* @param name The name of the modifier
|
|
604
|
+
* @param selectors The selectors of the modifier
|
|
605
|
+
* @param options The options of the modifier
|
|
606
|
+
*
|
|
607
|
+
* @returns {void}
|
|
608
|
+
*/
|
|
609
|
+
function staticModifier(name, selectors, options = {}, ctx) {
|
|
610
|
+
registerModifier({
|
|
611
|
+
name,
|
|
612
|
+
match: (mod) => mod === name,
|
|
613
|
+
modifySelector: ({ ..._rest }) => {
|
|
614
|
+
return selectors.map((sel) => ({
|
|
615
|
+
selector: sel,
|
|
616
|
+
source: options.source
|
|
617
|
+
}));
|
|
618
|
+
},
|
|
619
|
+
...options
|
|
620
|
+
}, ctx);
|
|
621
|
+
}
|
|
622
|
+
function functionalModifier(match, modifySelector, wrap, options = {}, ctx) {
|
|
623
|
+
registerModifier({
|
|
624
|
+
match,
|
|
625
|
+
modifySelector,
|
|
626
|
+
wrap,
|
|
627
|
+
...options
|
|
628
|
+
}, ctx);
|
|
629
|
+
}
|
|
630
|
+
function registerModifier(modifier, ctx) {
|
|
631
|
+
const state = ctx && getContextState(ctx);
|
|
632
|
+
if (ctx && !state) throw new Error("Modifier registration requires a context from createContext");
|
|
633
|
+
(state?.modifiers || modifierRegistry).push(modifier);
|
|
634
|
+
if (ctx) clearContextCaches(ctx);
|
|
635
|
+
}
|
|
636
|
+
function getModifier(ctx) {
|
|
637
|
+
return ctx && getContextState(ctx)?.modifiers || modifierRegistry;
|
|
638
|
+
}
|
|
639
|
+
var ESCAPE_REGEX = /[^A-Za-z0-9_-]/gu;
|
|
640
|
+
var UNSAFE_RAW = /^[\s\p{C}\p{Z}]$/u;
|
|
641
|
+
function escapeClassName(className) {
|
|
642
|
+
if (className === "-") return "\\-";
|
|
643
|
+
const lead = /^-?[0-9]/.exec(className);
|
|
644
|
+
if (lead) {
|
|
645
|
+
const i = lead[0].length - 1;
|
|
646
|
+
return className.slice(0, i) + "\\" + className.charCodeAt(i).toString(16) + " " + escapeRest(className.slice(i + 1));
|
|
647
|
+
}
|
|
648
|
+
return escapeRest(className);
|
|
649
|
+
}
|
|
650
|
+
function escapeRest(className) {
|
|
651
|
+
return className.replace(ESCAPE_REGEX, (c) => {
|
|
652
|
+
if (c === " ") return "\\x20 ";
|
|
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 (c === "\\") return "\\\\";
|
|
683
|
+
if (UNSAFE_RAW.test(c)) return "\\" + c.codePointAt(0).toString(16) + " ";
|
|
684
|
+
return "\\" + c;
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* staticUtility: A helper that registers a utility name and an array of CSS declaration pairs directly to the registry
|
|
689
|
+
*
|
|
690
|
+
* @example
|
|
691
|
+
* ```
|
|
692
|
+
* staticUtility('block', [['display', 'block']]);
|
|
693
|
+
* staticUtility('hidden', [['display', 'none']]);
|
|
694
|
+
* staticUtility('space-x-px', [
|
|
695
|
+
* [
|
|
696
|
+
* '& > :not([hidden]) ~ :not([hidden])', // selector
|
|
697
|
+
* [
|
|
698
|
+
* ['margin-inline-start', '1px'], // [prop, value]
|
|
699
|
+
* ['margin-inline-end', '1px'], // [prop, value]
|
|
700
|
+
* ],
|
|
701
|
+
* ],
|
|
702
|
+
* ]);
|
|
703
|
+
* ```
|
|
704
|
+
*
|
|
705
|
+
* @param name The name of the utility
|
|
706
|
+
* @param decls The declarations of the utility
|
|
707
|
+
* @param opts The options of the utility
|
|
708
|
+
*
|
|
709
|
+
* @returns {void}
|
|
710
|
+
*/
|
|
711
|
+
function staticUtility(name, decls, opts, ctx) {
|
|
712
|
+
registerUtility({
|
|
713
|
+
name,
|
|
714
|
+
match: (className) => {
|
|
715
|
+
return className === name;
|
|
716
|
+
},
|
|
717
|
+
handler: (value) => {
|
|
718
|
+
return decls.flatMap((params) => {
|
|
719
|
+
if (params.type) return [params];
|
|
720
|
+
if (typeof params === "function") return [params(value)];
|
|
721
|
+
const [a, b] = params;
|
|
722
|
+
if (typeof b === "string") return [decl(a, b)];
|
|
723
|
+
else if (Array.isArray(b)) return [rule(a, b.map(([prop, value]) => decl(prop, value)))];
|
|
724
|
+
return [];
|
|
725
|
+
});
|
|
726
|
+
},
|
|
727
|
+
description: opts?.description,
|
|
728
|
+
category: opts?.category,
|
|
729
|
+
priority: opts?.priority
|
|
730
|
+
}, ctx);
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* functionalUtility: A helper that registers dynamic utilities (theme, arbitrary, custom, negative, fraction, etc.) directly
|
|
734
|
+
*
|
|
735
|
+
* Example:
|
|
736
|
+
* functionalUtility({
|
|
737
|
+
* name: 'z',
|
|
738
|
+
* supportsNegative: true,
|
|
739
|
+
* themeKeys: ['--z-index'],
|
|
740
|
+
* handleBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
|
|
741
|
+
* handle: (value) => [decl('z-index', value)],
|
|
742
|
+
* description: 'z-index utility',
|
|
743
|
+
* category: 'layout',
|
|
744
|
+
* });
|
|
745
|
+
*/
|
|
746
|
+
/**
|
|
747
|
+
* #300: a theme key that no built-in utility names (`theme.extend.borderRadius.card`) still resolves, as in
|
|
748
|
+
* Tailwind 4 where `--radius-card` gives `rounded-card`. Only word keys that start with a letter (numbers stay
|
|
749
|
+
* bare values), never `DEFAULT`; unknown keys return null so the utility emits nothing (#213).
|
|
750
|
+
*/
|
|
751
|
+
function themeKeyEntry(ctx, namespace, key) {
|
|
752
|
+
if (key === "DEFAULT" || !/^[a-zA-Z][\w-]*$/.test(key) || typeof ctx?.theme !== "function") return void 0;
|
|
753
|
+
const table = ctx.theme(namespace);
|
|
754
|
+
if (!table || typeof table !== "object" || !Object.prototype.hasOwnProperty.call(table, key)) return void 0;
|
|
755
|
+
return table[key] ?? void 0;
|
|
756
|
+
}
|
|
757
|
+
/** #300: the literal value of `theme.<namespace>.<key>` when it is a string, else null. */
|
|
758
|
+
function themeKeyValue(ctx, namespace, key) {
|
|
759
|
+
const v = themeKeyEntry(ctx, namespace, key);
|
|
760
|
+
return typeof v === "string" ? v : null;
|
|
761
|
+
}
|
|
762
|
+
/** #300: `var(--<varPrefix>-<key>)` when `theme.<namespace>.<key>` exists (the :root var BaroCSS emits for it), else null. */
|
|
763
|
+
function themeKeyVar(ctx, namespace, key, varPrefix) {
|
|
764
|
+
return themeKeyEntry(ctx, namespace, key) === void 0 ? null : `var(--${varPrefix}-${key})`;
|
|
765
|
+
}
|
|
766
|
+
/** #261: `var(--spacing-<key>)` for a named (non-numeric) `theme.spacing` key, else null. */
|
|
767
|
+
function spacingKeyValue(ctx, key, negative) {
|
|
768
|
+
if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
|
|
769
|
+
const ref = `var(--spacing-${key})`;
|
|
770
|
+
return negative ? `calc(${ref} * -1)` : ref;
|
|
771
|
+
}
|
|
772
|
+
function functionalUtility(opts, ctx) {
|
|
773
|
+
registerUtility({
|
|
774
|
+
name: opts.name,
|
|
775
|
+
match: (className) => className.startsWith(opts.name + "-"),
|
|
776
|
+
handler: (value, ctx, token, _options) => {
|
|
777
|
+
let finalValue = value;
|
|
778
|
+
const parsedUtility = token;
|
|
779
|
+
const extra = { opacity: token.opacity };
|
|
780
|
+
if (opts.supportsOpacity && !token.arbitrary && !token.customProperty && value.includes("/")) {
|
|
781
|
+
const list = value.split("/");
|
|
782
|
+
if (list.length >= 2) {
|
|
783
|
+
extra.opacity = list.pop();
|
|
784
|
+
finalValue = list.join("/");
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
const splitModifier = !token.arbitrary && !token.customProperty && value.includes("/");
|
|
788
|
+
if (opts.supportsOpacity && (extra.opacity || splitModifier) && !normalizeAlpha(String(extra.opacity ?? ""))) {
|
|
789
|
+
const v = parsedUtility.arbitrary ? finalValue.replace(/_/g, " ") : finalValue;
|
|
790
|
+
return (parsedUtility.customProperty ? !/^[\w-]+:/.test(v) || v.startsWith("color:") : parsedUtility.arbitrary ? !!parseColor(v) || /^var\(--/.test(v) || v.startsWith("color:") : false) ? REJECT_CLASS : [];
|
|
791
|
+
}
|
|
792
|
+
const direct = (x) => {
|
|
793
|
+
if (opts.supportsArbitrary && parsedUtility.arbitrary) {
|
|
794
|
+
const processedValue = normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " ")));
|
|
795
|
+
if (opts.handle) {
|
|
796
|
+
const result = opts.handle(processedValue, ctx, token, x);
|
|
797
|
+
if (result) return result;
|
|
798
|
+
}
|
|
799
|
+
if (opts.prop) return [decl(opts.prop, processedValue)];
|
|
800
|
+
return [];
|
|
801
|
+
}
|
|
802
|
+
if (opts.supportsCustomProperty && parsedUtility.customProperty) {
|
|
803
|
+
if (opts.handleCustomProperty) return opts.handleCustomProperty(finalValue, ctx, token, x) ?? null;
|
|
804
|
+
const customValue = `var(${finalValue})`;
|
|
805
|
+
if (opts.handle) {
|
|
806
|
+
const result = opts.handle(customValue, ctx, token, x);
|
|
807
|
+
if (result) return result;
|
|
808
|
+
}
|
|
809
|
+
if (opts.prop) return [decl(opts.prop, customValue)];
|
|
810
|
+
return [];
|
|
811
|
+
}
|
|
812
|
+
return null;
|
|
813
|
+
};
|
|
814
|
+
if (opts.supportsArbitrary && parsedUtility.arbitrary || opts.supportsCustomProperty && parsedUtility.customProperty) {
|
|
815
|
+
const result = direct(extra);
|
|
816
|
+
if (opts.supportsOpacity && !opts.ownsOpacity && extra.opacity && result?.length) {
|
|
817
|
+
const raw = parsedUtility.arbitrary ? normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " "))) : `var(${finalValue})`;
|
|
818
|
+
const hint = parsedUtility.arbitrary ? /^color:(.+)$/.exec(raw)?.[1] : /^color:(--.+)$/.exec(finalValue)?.[1];
|
|
819
|
+
return applyColorAlpha(result, [raw, ...hint ? [hint, `var(${hint})`] : []], String(extra.opacity)) ?? [];
|
|
820
|
+
}
|
|
821
|
+
return result;
|
|
822
|
+
}
|
|
823
|
+
let themeValue;
|
|
824
|
+
if (opts.themeKey && ctx.theme) themeValue = themeScalar(ctx.theme(opts.themeKey, finalValue));
|
|
825
|
+
let namespace = themeValue !== void 0 ? opts.themeKey : void 0;
|
|
826
|
+
if (!themeValue && opts.themeKeys && ctx.theme) for (const key of opts.themeKeys) {
|
|
827
|
+
themeValue = themeScalar(ctx.theme(key, finalValue));
|
|
828
|
+
if (themeValue !== void 0) {
|
|
829
|
+
namespace = key;
|
|
830
|
+
break;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
if (themeValue !== void 0) {
|
|
834
|
+
extra.themeNamespace = namespace;
|
|
835
|
+
extra.themeKey = finalValue;
|
|
836
|
+
if (namespace === "colors" || !(opts.themeKeys ?? [opts.themeKey]).includes("colors")) extra.realThemeValue = finalValue;
|
|
837
|
+
finalValue = themeValue;
|
|
838
|
+
if (opts.prop) return [decl(opts.prop, finalValue)];
|
|
839
|
+
if (opts.handle) {
|
|
840
|
+
const result = opts.handle(finalValue, ctx, token, extra);
|
|
841
|
+
if (result) return result;
|
|
518
842
|
}
|
|
519
843
|
return [];
|
|
520
844
|
}
|
|
@@ -912,6 +1236,46 @@ function isBalancedPrelude(text) {
|
|
|
912
1236
|
return stack.length === 0 && !quote;
|
|
913
1237
|
}
|
|
914
1238
|
/**
|
|
1239
|
+
* #392: true when every top-level comma part of an emitted selector names `escapedClass` (a class selector
|
|
1240
|
+
* already escaped with escapeClassName, including its leading dot) as a whole class token, or, when
|
|
1241
|
+
* `allowNesting` is set, uses the nesting selector `&`. Escapes, quoted strings and bracket groups are skipped
|
|
1242
|
+
* when splitting. Used as a defence-in-depth serializer check: a rule scoped to no generating class is dropped.
|
|
1243
|
+
*/
|
|
1244
|
+
function isScopedSelector(selector, escapedClass, allowNesting = false) {
|
|
1245
|
+
const parts = [];
|
|
1246
|
+
let depth = 0;
|
|
1247
|
+
let quote = "";
|
|
1248
|
+
let start = 0;
|
|
1249
|
+
for (let i = 0; i < selector.length; i++) {
|
|
1250
|
+
const c = selector[i];
|
|
1251
|
+
if (c === "\\") {
|
|
1252
|
+
i++;
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
if (quote) {
|
|
1256
|
+
if (c === quote) quote = "";
|
|
1257
|
+
continue;
|
|
1258
|
+
}
|
|
1259
|
+
if (c === "\"" || c === "'") quote = c;
|
|
1260
|
+
else if (c === "(" || c === "[") depth++;
|
|
1261
|
+
else if (c === ")" || c === "]") depth--;
|
|
1262
|
+
else if (c === "," && depth === 0) {
|
|
1263
|
+
parts.push(selector.slice(start, i));
|
|
1264
|
+
start = i + 1;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
parts.push(selector.slice(start));
|
|
1268
|
+
return parts.every((part) => {
|
|
1269
|
+
if (allowNesting && part.includes("&")) return true;
|
|
1270
|
+
for (let at = part.indexOf(escapedClass); at !== -1; at = part.indexOf(escapedClass, at + 1)) {
|
|
1271
|
+
if (at > 0 && part[at - 1] === "\\") continue;
|
|
1272
|
+
const next = part[at + escapedClass.length];
|
|
1273
|
+
if (escapedClass.endsWith(" ") || next === void 0 || !/[\w\-\\\u0080-\uffff]/.test(next)) return true;
|
|
1274
|
+
}
|
|
1275
|
+
return false;
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
915
1279
|
* #323: true when emitted text contains a markup end-tag opener (less-than then slash). Generated CSS can be
|
|
916
1280
|
* placed inside an HTML style element, where that sequence could end the element early. CSS escapes in the
|
|
917
1281
|
* output never form it, and a lone less-than (range media queries) stays allowed.
|
|
@@ -1003,6 +1367,13 @@ function parseModifier(value) {
|
|
|
1003
1367
|
function nameSort(a, b) {
|
|
1004
1368
|
return b.name.length - a.name.length;
|
|
1005
1369
|
}
|
|
1370
|
+
/** #393: index of the `close` that balances the value opened just before `s` (depth starts at 1), or -1. */
|
|
1371
|
+
function matchingClose(s, open, close) {
|
|
1372
|
+
let depth = 1;
|
|
1373
|
+
for (let i = 0; i < s.length; i++) if (s[i] === open) depth++;
|
|
1374
|
+
else if (s[i] === close && --depth === 0) return i;
|
|
1375
|
+
return -1;
|
|
1376
|
+
}
|
|
1006
1377
|
/**
|
|
1007
1378
|
* Parse utility token
|
|
1008
1379
|
*/
|
|
@@ -1031,15 +1402,27 @@ function parseUtility(value, ctx) {
|
|
|
1031
1402
|
if (value.startsWith("-")) negative = true;
|
|
1032
1403
|
if (value.includes("-[")) {
|
|
1033
1404
|
[prefix, utilityValue] = value.split("-[");
|
|
1034
|
-
const closeIdx = utilityValue
|
|
1405
|
+
const closeIdx = matchingClose(utilityValue, "[", "]");
|
|
1035
1406
|
if (closeIdx !== -1 && closeIdx < utilityValue.length - 1 && utilityValue[closeIdx + 1] === "/") {
|
|
1036
1407
|
opacity = utilityValue.slice(closeIdx + 2);
|
|
1408
|
+
if (!opacity) return {
|
|
1409
|
+
prefix: "",
|
|
1410
|
+
value: ""
|
|
1411
|
+
};
|
|
1037
1412
|
utilityValue = utilityValue.slice(0, closeIdx);
|
|
1038
1413
|
} else utilityValue = utilityValue.replace(/]$/, "");
|
|
1039
1414
|
arbitrary = true;
|
|
1040
1415
|
} else if (value.includes("-(")) {
|
|
1041
1416
|
[prefix, utilityValue] = value.split("-(");
|
|
1042
|
-
|
|
1417
|
+
const closeIdx = matchingClose(utilityValue, "(", ")");
|
|
1418
|
+
if (closeIdx !== -1 && closeIdx < utilityValue.length - 1 && utilityValue[closeIdx + 1] === "/") {
|
|
1419
|
+
opacity = utilityValue.slice(closeIdx + 2);
|
|
1420
|
+
if (!opacity) return {
|
|
1421
|
+
prefix: "",
|
|
1422
|
+
value: ""
|
|
1423
|
+
};
|
|
1424
|
+
utilityValue = utilityValue.slice(0, closeIdx);
|
|
1425
|
+
} else utilityValue = utilityValue.replace(/\)$/, "");
|
|
1043
1426
|
customProperty = true;
|
|
1044
1427
|
} else {
|
|
1045
1428
|
const sortedUtilities = [...getUtility(ctx)].sort(nameSort);
|
|
@@ -1091,6 +1474,13 @@ var uniqueDescriptors = (node) => {
|
|
|
1091
1474
|
const seen = /* @__PURE__ */ new Set();
|
|
1092
1475
|
return node.nodes.filter((c) => c.type !== "decl" || !seen.has(c.prop) && !!seen.add(c.prop));
|
|
1093
1476
|
};
|
|
1477
|
+
var NO_IMPORTANT_AT = /* @__PURE__ */ new Set([
|
|
1478
|
+
"property",
|
|
1479
|
+
"font-face",
|
|
1480
|
+
"keyframes",
|
|
1481
|
+
"-webkit-keyframes",
|
|
1482
|
+
"counter-style"
|
|
1483
|
+
]);
|
|
1094
1484
|
var isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? "")) && !hasHtmlEndTagOpener(String(prop)) && !hasHtmlEndTagOpener(String(value ?? ""));
|
|
1095
1485
|
var importantPrefix = "!important";
|
|
1096
1486
|
/**
|
|
@@ -1105,6 +1495,12 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
|
|
|
1105
1495
|
const indent = _indent;
|
|
1106
1496
|
const nextIndent = _indent + " ";
|
|
1107
1497
|
const importantString = opts?.important ?? false ? ` ${importantPrefix}` : "";
|
|
1498
|
+
const nestedOpts = opts ? {
|
|
1499
|
+
...opts,
|
|
1500
|
+
nested: true
|
|
1501
|
+
} : opts;
|
|
1502
|
+
const scopeClass = opts?.scope ? "." + escapeClassName(opts.scope) : "";
|
|
1503
|
+
const inScope = (sel) => !scopeClass || isScopedSelector(sel, scopeClass, !!opts?.nested);
|
|
1108
1504
|
if (!ast || ast.length === 0) {
|
|
1109
1505
|
debugWarn("[astToCss] Empty AST received:", {
|
|
1110
1506
|
ast,
|
|
@@ -1147,18 +1543,23 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
|
|
|
1147
1543
|
else return escBase + (sel.startsWith(".") ? "" : " ") + sel;
|
|
1148
1544
|
}).join(", ");
|
|
1149
1545
|
}
|
|
1150
|
-
if (!isSafePrelude(selector)) return "";
|
|
1151
|
-
if (minify) return `${indent}${selector}{${astToCss(node.nodes, baseSelector,
|
|
1152
|
-
else return `${indent}${selector} {\n${astToCss(node.nodes, baseSelector,
|
|
1546
|
+
if (!isSafePrelude(selector) || !inScope(selector)) return "";
|
|
1547
|
+
if (minify) return `${indent}${selector}{${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}}`;
|
|
1548
|
+
else return `${indent}${selector} {\n${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}${indent}}`;
|
|
1153
1549
|
}
|
|
1154
1550
|
case "style-rule":
|
|
1155
|
-
if (!isSafePrelude(node.selector)) return "";
|
|
1156
|
-
if (minify) return `${indent}${node.selector} {${astToCss(node.nodes, baseSelector,
|
|
1157
|
-
else return `${indent}${node.selector} {\n${astToCss(node.nodes, baseSelector,
|
|
1158
|
-
case "at-rule":
|
|
1551
|
+
if (!isSafePrelude(node.selector) || !inScope(node.selector)) return "";
|
|
1552
|
+
if (minify) return `${indent}${node.selector} {${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}}`;
|
|
1553
|
+
else return `${indent}${node.selector} {\n${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}${indent}}`;
|
|
1554
|
+
case "at-rule": {
|
|
1159
1555
|
if (!isSafePrelude(node.name) || !isSafePrelude(node.params)) return "";
|
|
1160
|
-
|
|
1161
|
-
|
|
1556
|
+
const atOpts = opts?.important && NO_IMPORTANT_AT.has(node.name) ? {
|
|
1557
|
+
...opts,
|
|
1558
|
+
important: false
|
|
1559
|
+
} : opts;
|
|
1560
|
+
if (minify) return `${indent}@${node.name} ${node.params}{${astToCss(node.nodes, baseSelector, atOpts, nextIndent)}}`;
|
|
1561
|
+
else return `${indent}@${node.name} ${node.params} {\n${astToCss(node.nodes, baseSelector, atOpts, nextIndent)}${indent}}`;
|
|
1562
|
+
}
|
|
1162
1563
|
case "comment": return minify ? "" : `${indent}/* ${node.text} */`;
|
|
1163
1564
|
case "raw": return `${indent}${node.value}`;
|
|
1164
1565
|
default:
|
|
@@ -1517,6 +1918,552 @@ function applyVarPrefix(ast, ctx) {
|
|
|
1517
1918
|
return walk(ast);
|
|
1518
1919
|
}
|
|
1519
1920
|
//#endregion
|
|
1921
|
+
//#region src/core/tw-property-order.ts
|
|
1922
|
+
var TW_PROPERTY_ORDER = [
|
|
1923
|
+
"container-type",
|
|
1924
|
+
"pointer-events",
|
|
1925
|
+
"visibility",
|
|
1926
|
+
"position",
|
|
1927
|
+
"inset",
|
|
1928
|
+
"inset-inline",
|
|
1929
|
+
"inset-block",
|
|
1930
|
+
"inset-inline-start",
|
|
1931
|
+
"inset-inline-end",
|
|
1932
|
+
"inset-block-start",
|
|
1933
|
+
"inset-block-end",
|
|
1934
|
+
"top",
|
|
1935
|
+
"right",
|
|
1936
|
+
"bottom",
|
|
1937
|
+
"left",
|
|
1938
|
+
"isolation",
|
|
1939
|
+
"z-index",
|
|
1940
|
+
"order",
|
|
1941
|
+
"grid-column",
|
|
1942
|
+
"grid-column-start",
|
|
1943
|
+
"grid-column-end",
|
|
1944
|
+
"grid-row",
|
|
1945
|
+
"grid-row-start",
|
|
1946
|
+
"grid-row-end",
|
|
1947
|
+
"float",
|
|
1948
|
+
"clear",
|
|
1949
|
+
"--tw-container-component",
|
|
1950
|
+
"margin",
|
|
1951
|
+
"margin-inline",
|
|
1952
|
+
"margin-block",
|
|
1953
|
+
"margin-inline-start",
|
|
1954
|
+
"margin-inline-end",
|
|
1955
|
+
"margin-block-start",
|
|
1956
|
+
"margin-block-end",
|
|
1957
|
+
"margin-top",
|
|
1958
|
+
"margin-right",
|
|
1959
|
+
"margin-bottom",
|
|
1960
|
+
"margin-left",
|
|
1961
|
+
"box-sizing",
|
|
1962
|
+
"display",
|
|
1963
|
+
"field-sizing",
|
|
1964
|
+
"aspect-ratio",
|
|
1965
|
+
"height",
|
|
1966
|
+
"max-height",
|
|
1967
|
+
"min-height",
|
|
1968
|
+
"width",
|
|
1969
|
+
"max-width",
|
|
1970
|
+
"min-width",
|
|
1971
|
+
"flex",
|
|
1972
|
+
"flex-shrink",
|
|
1973
|
+
"flex-grow",
|
|
1974
|
+
"flex-basis",
|
|
1975
|
+
"table-layout",
|
|
1976
|
+
"caption-side",
|
|
1977
|
+
"border-collapse",
|
|
1978
|
+
"border-spacing",
|
|
1979
|
+
"transform-origin",
|
|
1980
|
+
"translate",
|
|
1981
|
+
"--tw-translate-x",
|
|
1982
|
+
"--tw-translate-y",
|
|
1983
|
+
"--tw-translate-z",
|
|
1984
|
+
"scale",
|
|
1985
|
+
"--tw-scale-x",
|
|
1986
|
+
"--tw-scale-y",
|
|
1987
|
+
"--tw-scale-z",
|
|
1988
|
+
"rotate",
|
|
1989
|
+
"--tw-rotate-x",
|
|
1990
|
+
"--tw-rotate-y",
|
|
1991
|
+
"--tw-rotate-z",
|
|
1992
|
+
"--tw-skew-x",
|
|
1993
|
+
"--tw-skew-y",
|
|
1994
|
+
"transform",
|
|
1995
|
+
"zoom",
|
|
1996
|
+
"animation",
|
|
1997
|
+
"cursor",
|
|
1998
|
+
"touch-action",
|
|
1999
|
+
"--tw-pan-x",
|
|
2000
|
+
"--tw-pan-y",
|
|
2001
|
+
"--tw-pinch-zoom",
|
|
2002
|
+
"resize",
|
|
2003
|
+
"scroll-snap-type",
|
|
2004
|
+
"--tw-scroll-snap-strictness",
|
|
2005
|
+
"scroll-snap-align",
|
|
2006
|
+
"scroll-snap-stop",
|
|
2007
|
+
"scroll-margin",
|
|
2008
|
+
"scroll-margin-inline",
|
|
2009
|
+
"scroll-margin-block",
|
|
2010
|
+
"scroll-margin-inline-start",
|
|
2011
|
+
"scroll-margin-inline-end",
|
|
2012
|
+
"scroll-margin-block-start",
|
|
2013
|
+
"scroll-margin-block-end",
|
|
2014
|
+
"scroll-margin-top",
|
|
2015
|
+
"scroll-margin-right",
|
|
2016
|
+
"scroll-margin-bottom",
|
|
2017
|
+
"scroll-margin-left",
|
|
2018
|
+
"scroll-padding",
|
|
2019
|
+
"scroll-padding-inline",
|
|
2020
|
+
"scroll-padding-block",
|
|
2021
|
+
"scroll-padding-inline-start",
|
|
2022
|
+
"scroll-padding-inline-end",
|
|
2023
|
+
"scroll-padding-block-start",
|
|
2024
|
+
"scroll-padding-block-end",
|
|
2025
|
+
"scroll-padding-top",
|
|
2026
|
+
"scroll-padding-right",
|
|
2027
|
+
"scroll-padding-bottom",
|
|
2028
|
+
"scroll-padding-left",
|
|
2029
|
+
"scrollbar-width",
|
|
2030
|
+
"scrollbar-color",
|
|
2031
|
+
"scrollbar-gutter",
|
|
2032
|
+
"list-style-position",
|
|
2033
|
+
"list-style-type",
|
|
2034
|
+
"list-style-image",
|
|
2035
|
+
"appearance",
|
|
2036
|
+
"columns",
|
|
2037
|
+
"break-before",
|
|
2038
|
+
"break-inside",
|
|
2039
|
+
"break-after",
|
|
2040
|
+
"grid-auto-columns",
|
|
2041
|
+
"grid-auto-flow",
|
|
2042
|
+
"grid-auto-rows",
|
|
2043
|
+
"grid-template-columns",
|
|
2044
|
+
"grid-template-rows",
|
|
2045
|
+
"flex-direction",
|
|
2046
|
+
"flex-wrap",
|
|
2047
|
+
"place-content",
|
|
2048
|
+
"place-items",
|
|
2049
|
+
"align-content",
|
|
2050
|
+
"align-items",
|
|
2051
|
+
"justify-content",
|
|
2052
|
+
"justify-items",
|
|
2053
|
+
"gap",
|
|
2054
|
+
"column-gap",
|
|
2055
|
+
"row-gap",
|
|
2056
|
+
"--tw-space-x-reverse",
|
|
2057
|
+
"--tw-space-y-reverse",
|
|
2058
|
+
"divide-x-width",
|
|
2059
|
+
"divide-y-width",
|
|
2060
|
+
"--tw-divide-y-reverse",
|
|
2061
|
+
"divide-style",
|
|
2062
|
+
"divide-color",
|
|
2063
|
+
"place-self",
|
|
2064
|
+
"align-self",
|
|
2065
|
+
"justify-self",
|
|
2066
|
+
"overflow",
|
|
2067
|
+
"overflow-x",
|
|
2068
|
+
"overflow-y",
|
|
2069
|
+
"overscroll-behavior",
|
|
2070
|
+
"overscroll-behavior-x",
|
|
2071
|
+
"overscroll-behavior-y",
|
|
2072
|
+
"scroll-behavior",
|
|
2073
|
+
"border-radius",
|
|
2074
|
+
"border-start-radius",
|
|
2075
|
+
"border-end-radius",
|
|
2076
|
+
"border-top-radius",
|
|
2077
|
+
"border-right-radius",
|
|
2078
|
+
"border-bottom-radius",
|
|
2079
|
+
"border-left-radius",
|
|
2080
|
+
"border-start-start-radius",
|
|
2081
|
+
"border-start-end-radius",
|
|
2082
|
+
"border-end-end-radius",
|
|
2083
|
+
"border-end-start-radius",
|
|
2084
|
+
"border-top-left-radius",
|
|
2085
|
+
"border-top-right-radius",
|
|
2086
|
+
"border-bottom-right-radius",
|
|
2087
|
+
"border-bottom-left-radius",
|
|
2088
|
+
"border-width",
|
|
2089
|
+
"border-inline-width",
|
|
2090
|
+
"border-block-width",
|
|
2091
|
+
"border-inline-start-width",
|
|
2092
|
+
"border-inline-end-width",
|
|
2093
|
+
"border-block-start-width",
|
|
2094
|
+
"border-block-end-width",
|
|
2095
|
+
"border-top-width",
|
|
2096
|
+
"border-right-width",
|
|
2097
|
+
"border-bottom-width",
|
|
2098
|
+
"border-left-width",
|
|
2099
|
+
"border-style",
|
|
2100
|
+
"border-inline-style",
|
|
2101
|
+
"border-block-style",
|
|
2102
|
+
"border-inline-start-style",
|
|
2103
|
+
"border-inline-end-style",
|
|
2104
|
+
"border-block-start-style",
|
|
2105
|
+
"border-block-end-style",
|
|
2106
|
+
"border-top-style",
|
|
2107
|
+
"border-right-style",
|
|
2108
|
+
"border-bottom-style",
|
|
2109
|
+
"border-left-style",
|
|
2110
|
+
"border-color",
|
|
2111
|
+
"border-inline-color",
|
|
2112
|
+
"border-block-color",
|
|
2113
|
+
"border-inline-start-color",
|
|
2114
|
+
"border-inline-end-color",
|
|
2115
|
+
"border-block-start-color",
|
|
2116
|
+
"border-block-end-color",
|
|
2117
|
+
"border-top-color",
|
|
2118
|
+
"border-right-color",
|
|
2119
|
+
"border-bottom-color",
|
|
2120
|
+
"border-left-color",
|
|
2121
|
+
"background-color",
|
|
2122
|
+
"background-image",
|
|
2123
|
+
"--tw-gradient-position",
|
|
2124
|
+
"--tw-gradient-stops",
|
|
2125
|
+
"--tw-gradient-via-stops",
|
|
2126
|
+
"--tw-gradient-from",
|
|
2127
|
+
"--tw-gradient-from-position",
|
|
2128
|
+
"--tw-gradient-via",
|
|
2129
|
+
"--tw-gradient-via-position",
|
|
2130
|
+
"--tw-gradient-to",
|
|
2131
|
+
"--tw-gradient-to-position",
|
|
2132
|
+
"mask-image",
|
|
2133
|
+
"--tw-mask-top",
|
|
2134
|
+
"--tw-mask-top-from-color",
|
|
2135
|
+
"--tw-mask-top-from-position",
|
|
2136
|
+
"--tw-mask-top-to-color",
|
|
2137
|
+
"--tw-mask-top-to-position",
|
|
2138
|
+
"--tw-mask-right",
|
|
2139
|
+
"--tw-mask-right-from-color",
|
|
2140
|
+
"--tw-mask-right-from-position",
|
|
2141
|
+
"--tw-mask-right-to-color",
|
|
2142
|
+
"--tw-mask-right-to-position",
|
|
2143
|
+
"--tw-mask-bottom",
|
|
2144
|
+
"--tw-mask-bottom-from-color",
|
|
2145
|
+
"--tw-mask-bottom-from-position",
|
|
2146
|
+
"--tw-mask-bottom-to-color",
|
|
2147
|
+
"--tw-mask-bottom-to-position",
|
|
2148
|
+
"--tw-mask-left",
|
|
2149
|
+
"--tw-mask-left-from-color",
|
|
2150
|
+
"--tw-mask-left-from-position",
|
|
2151
|
+
"--tw-mask-left-to-color",
|
|
2152
|
+
"--tw-mask-left-to-position",
|
|
2153
|
+
"--tw-mask-linear",
|
|
2154
|
+
"--tw-mask-linear-position",
|
|
2155
|
+
"--tw-mask-linear-from-color",
|
|
2156
|
+
"--tw-mask-linear-from-position",
|
|
2157
|
+
"--tw-mask-linear-to-color",
|
|
2158
|
+
"--tw-mask-linear-to-position",
|
|
2159
|
+
"--tw-mask-radial",
|
|
2160
|
+
"--tw-mask-radial-shape",
|
|
2161
|
+
"--tw-mask-radial-size",
|
|
2162
|
+
"--tw-mask-radial-position",
|
|
2163
|
+
"--tw-mask-radial-from-color",
|
|
2164
|
+
"--tw-mask-radial-from-position",
|
|
2165
|
+
"--tw-mask-radial-to-color",
|
|
2166
|
+
"--tw-mask-radial-to-position",
|
|
2167
|
+
"--tw-mask-conic",
|
|
2168
|
+
"--tw-mask-conic-position",
|
|
2169
|
+
"--tw-mask-conic-from-color",
|
|
2170
|
+
"--tw-mask-conic-from-position",
|
|
2171
|
+
"--tw-mask-conic-to-color",
|
|
2172
|
+
"--tw-mask-conic-to-position",
|
|
2173
|
+
"box-decoration-break",
|
|
2174
|
+
"background-size",
|
|
2175
|
+
"background-attachment",
|
|
2176
|
+
"background-clip",
|
|
2177
|
+
"background-position",
|
|
2178
|
+
"background-repeat",
|
|
2179
|
+
"background-origin",
|
|
2180
|
+
"mask-composite",
|
|
2181
|
+
"mask-mode",
|
|
2182
|
+
"mask-type",
|
|
2183
|
+
"mask-size",
|
|
2184
|
+
"mask-clip",
|
|
2185
|
+
"mask-position",
|
|
2186
|
+
"mask-repeat",
|
|
2187
|
+
"mask-origin",
|
|
2188
|
+
"fill",
|
|
2189
|
+
"stroke",
|
|
2190
|
+
"stroke-width",
|
|
2191
|
+
"object-fit",
|
|
2192
|
+
"object-position",
|
|
2193
|
+
"padding",
|
|
2194
|
+
"padding-inline",
|
|
2195
|
+
"padding-block",
|
|
2196
|
+
"padding-inline-start",
|
|
2197
|
+
"padding-inline-end",
|
|
2198
|
+
"padding-block-start",
|
|
2199
|
+
"padding-block-end",
|
|
2200
|
+
"padding-top",
|
|
2201
|
+
"padding-right",
|
|
2202
|
+
"padding-bottom",
|
|
2203
|
+
"padding-left",
|
|
2204
|
+
"text-align",
|
|
2205
|
+
"text-indent",
|
|
2206
|
+
"vertical-align",
|
|
2207
|
+
"font-family",
|
|
2208
|
+
"font-feature-settings",
|
|
2209
|
+
"font-size",
|
|
2210
|
+
"line-height",
|
|
2211
|
+
"font-weight",
|
|
2212
|
+
"letter-spacing",
|
|
2213
|
+
"text-wrap",
|
|
2214
|
+
"overflow-wrap",
|
|
2215
|
+
"word-break",
|
|
2216
|
+
"text-overflow",
|
|
2217
|
+
"hyphens",
|
|
2218
|
+
"white-space",
|
|
2219
|
+
"tab-size",
|
|
2220
|
+
"color",
|
|
2221
|
+
"text-transform",
|
|
2222
|
+
"font-style",
|
|
2223
|
+
"font-stretch",
|
|
2224
|
+
"font-variant-numeric",
|
|
2225
|
+
"text-decoration-line",
|
|
2226
|
+
"text-decoration-color",
|
|
2227
|
+
"text-decoration-style",
|
|
2228
|
+
"text-decoration-thickness",
|
|
2229
|
+
"text-underline-offset",
|
|
2230
|
+
"-webkit-font-smoothing",
|
|
2231
|
+
"placeholder-color",
|
|
2232
|
+
"caret-color",
|
|
2233
|
+
"accent-color",
|
|
2234
|
+
"color-scheme",
|
|
2235
|
+
"opacity",
|
|
2236
|
+
"background-blend-mode",
|
|
2237
|
+
"mix-blend-mode",
|
|
2238
|
+
"box-shadow",
|
|
2239
|
+
"--tw-shadow",
|
|
2240
|
+
"--tw-shadow-color",
|
|
2241
|
+
"--tw-ring-shadow",
|
|
2242
|
+
"--tw-ring-color",
|
|
2243
|
+
"--tw-inset-shadow",
|
|
2244
|
+
"--tw-inset-shadow-color",
|
|
2245
|
+
"--tw-inset-ring-shadow",
|
|
2246
|
+
"--tw-inset-ring-color",
|
|
2247
|
+
"--tw-ring-offset-width",
|
|
2248
|
+
"--tw-ring-offset-color",
|
|
2249
|
+
"outline",
|
|
2250
|
+
"outline-width",
|
|
2251
|
+
"outline-offset",
|
|
2252
|
+
"outline-color",
|
|
2253
|
+
"--tw-blur",
|
|
2254
|
+
"--tw-brightness",
|
|
2255
|
+
"--tw-contrast",
|
|
2256
|
+
"--tw-drop-shadow",
|
|
2257
|
+
"--tw-grayscale",
|
|
2258
|
+
"--tw-hue-rotate",
|
|
2259
|
+
"--tw-invert",
|
|
2260
|
+
"--tw-saturate",
|
|
2261
|
+
"--tw-sepia",
|
|
2262
|
+
"filter",
|
|
2263
|
+
"--tw-backdrop-blur",
|
|
2264
|
+
"--tw-backdrop-brightness",
|
|
2265
|
+
"--tw-backdrop-contrast",
|
|
2266
|
+
"--tw-backdrop-grayscale",
|
|
2267
|
+
"--tw-backdrop-hue-rotate",
|
|
2268
|
+
"--tw-backdrop-invert",
|
|
2269
|
+
"--tw-backdrop-opacity",
|
|
2270
|
+
"--tw-backdrop-saturate",
|
|
2271
|
+
"--tw-backdrop-sepia",
|
|
2272
|
+
"backdrop-filter",
|
|
2273
|
+
"transition-property",
|
|
2274
|
+
"transition-behavior",
|
|
2275
|
+
"transition-delay",
|
|
2276
|
+
"transition-duration",
|
|
2277
|
+
"transition-timing-function",
|
|
2278
|
+
"will-change",
|
|
2279
|
+
"contain",
|
|
2280
|
+
"content",
|
|
2281
|
+
"forced-color-adjust"
|
|
2282
|
+
];
|
|
2283
|
+
//#endregion
|
|
2284
|
+
//#region src/core/rule-order.ts
|
|
2285
|
+
/**
|
|
2286
|
+
* Tailwind-compatible cascade order for runtime-inserted rules (#254); shared by @barocss/server (#267).
|
|
2287
|
+
*
|
|
2288
|
+
* The runtime discovers classes in DOM order, so without sorting `lg:px-8`
|
|
2289
|
+
* seen before `sm:px-6` would land earlier and lose at >= 1024px. Each rule
|
|
2290
|
+
* gets a sort key derived from its leading `@media` / `@container` preludes:
|
|
2291
|
+
*
|
|
2292
|
+
* 0 base, negated media (`not-md:` → `@media not (…)`, as Tailwind 4.3.3 orders them, #352),
|
|
2293
|
+
* state media (hover), motion/contrast, unknown
|
|
2294
|
+
* 1 max-* breakpoints (larger width first)
|
|
2295
|
+
* 2 min-* breakpoints (smaller width first)
|
|
2296
|
+
* 3 @max-* container queries (larger width first)
|
|
2297
|
+
* 4 @min-* container queries (smaller width first)
|
|
2298
|
+
* 5 orientation, dark (prefers-color-scheme), print, forced-colors
|
|
2299
|
+
*
|
|
2300
|
+
* Nested at-rules (e.g. `sm:dark:`) contribute one key pair per level, so
|
|
2301
|
+
* `sm:` < `sm:dark:` < `md:`.
|
|
2302
|
+
*
|
|
2303
|
+
* #401: within one variant key, rules follow Tailwind 4's property order (the candidate sort of
|
|
2304
|
+
* Tailwind 4.3.3's `compile()`): compare the sorted TW property indices of each rule's declarations up
|
|
2305
|
+
* to the first difference (a rule that runs out of indices sorts last), then more declarations first,
|
|
2306
|
+
* then the class name (Tailwind's numeric-aware compare). Equal keys keep discovery order.
|
|
2307
|
+
*/
|
|
2308
|
+
var LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
|
|
2309
|
+
var LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
|
|
2310
|
+
var MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
|
|
2311
|
+
var MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
|
|
2312
|
+
/** Separates the variant pairs (whose first slot is >= 0) from the property part of a key. */
|
|
2313
|
+
var PROPERTY_PART = -1;
|
|
2314
|
+
/** A rule that has run out of property indices sorts after every real index (TW: `?? Infinity`). */
|
|
2315
|
+
var NO_MORE = Number.MAX_SAFE_INTEGER;
|
|
2316
|
+
var PROPERTY_INDEX = new Map(TW_PROPERTY_ORDER.map((p, i) => [p, i]));
|
|
2317
|
+
var DECL = /(?:^|[{;])\s*(-{0,2}[a-zA-Z][\w-]*)\s*:[^;{}]*(?=[;}])/g;
|
|
2318
|
+
var AT_PRELUDE = /^\s*@[\w-]+[^{]*\{/;
|
|
2319
|
+
var CLASS = /\.((?:\\.|[\w-])+)/;
|
|
2320
|
+
function toPx(n, unit) {
|
|
2321
|
+
const v = parseFloat(n);
|
|
2322
|
+
return unit === "rem" || unit === "em" ? v * 16 : v;
|
|
2323
|
+
}
|
|
2324
|
+
function preludeKey(kind, prelude) {
|
|
2325
|
+
const container = kind === "container";
|
|
2326
|
+
if (!container && /^\s*not\b/i.test(prelude)) return [0, 0];
|
|
2327
|
+
const min = MIN_W.exec(prelude);
|
|
2328
|
+
if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
|
|
2329
|
+
const max = MAX_W.exec(prelude);
|
|
2330
|
+
if (max) return [container ? 3 : 1, -toPx(max[1], max[2])];
|
|
2331
|
+
if (!container && LATE_MEDIA.test(prelude)) return [5, 0];
|
|
2332
|
+
return [0, 0];
|
|
2333
|
+
}
|
|
2334
|
+
/** The rule text after its leading at-rule preludes, up to its first `{` (the selector). */
|
|
2335
|
+
function ruleSelector(rule) {
|
|
2336
|
+
let rest = rule;
|
|
2337
|
+
let m;
|
|
2338
|
+
while (m = AT_PRELUDE.exec(rest)) rest = rest.slice(m[0].length);
|
|
2339
|
+
const end = rest.indexOf("{");
|
|
2340
|
+
return end === -1 ? "" : rest.slice(0, end);
|
|
2341
|
+
}
|
|
2342
|
+
/**
|
|
2343
|
+
* Tailwind's `--tw-sort` overrides (a utility sorts as one pseudo-property), recognised from BaroCSS's
|
|
2344
|
+
* output for the same utilities: space-x/y, divide-*, placeholder colour, gradient stops, container.
|
|
2345
|
+
* (TW's `size-*` override names no listed property, so Tailwind ignores it, and so does this.)
|
|
2346
|
+
*/
|
|
2347
|
+
function sortOverride(selector, props, candidate) {
|
|
2348
|
+
const first = props[0];
|
|
2349
|
+
if (first === "--tw-space-x-reverse") return "row-gap";
|
|
2350
|
+
if (first === "--tw-space-y-reverse") return "column-gap";
|
|
2351
|
+
if (first === "--tw-divide-x-reverse") return "divide-x-width";
|
|
2352
|
+
if (first === "--tw-divide-y-reverse") return "divide-y-width";
|
|
2353
|
+
if (selector.includes(":not(:last-child)")) {
|
|
2354
|
+
if (props.includes("border-color")) return "divide-color";
|
|
2355
|
+
if (props.includes("border-style")) return "divide-style";
|
|
2356
|
+
}
|
|
2357
|
+
if (selector.includes("::placeholder") && props.includes("color")) return "placeholder-color";
|
|
2358
|
+
for (const stop of [
|
|
2359
|
+
"from",
|
|
2360
|
+
"via",
|
|
2361
|
+
"to"
|
|
2362
|
+
]) if (props.includes(`--tw-gradient-${stop}`)) return `--tw-gradient-${stop}`;
|
|
2363
|
+
if (candidate.slice(candidate.lastIndexOf(":") + 1) === "container") return "--tw-container-component";
|
|
2364
|
+
return null;
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Tailwind's per-candidate property sort (#401): the sorted, de-duplicated TW property-order indices of
|
|
2368
|
+
* the rule's declarations (at any depth), and the declaration count. `--baro-*` vars count as `--tw-*`.
|
|
2369
|
+
*/
|
|
2370
|
+
/** @internal (#401) */ function rulePropertySort(rule, candidate = ruleCandidate(rule)) {
|
|
2371
|
+
const props = [];
|
|
2372
|
+
for (const d of rule.matchAll(DECL)) props.push(d[1].startsWith("--baro-") ? "--tw-" + d[1].slice(7) : d[1]);
|
|
2373
|
+
const override = sortOverride(ruleSelector(rule), props, candidate);
|
|
2374
|
+
const overrideIndex = override === null ? void 0 : PROPERTY_INDEX.get(override);
|
|
2375
|
+
if (overrideIndex !== void 0) return {
|
|
2376
|
+
order: [overrideIndex],
|
|
2377
|
+
count: props.length + 1
|
|
2378
|
+
};
|
|
2379
|
+
const set = /* @__PURE__ */ new Set();
|
|
2380
|
+
for (const p of props) {
|
|
2381
|
+
const i = PROPERTY_INDEX.get(p);
|
|
2382
|
+
if (i !== void 0) set.add(i);
|
|
2383
|
+
}
|
|
2384
|
+
return {
|
|
2385
|
+
order: Array.from(set).sort((a, b) => a - b),
|
|
2386
|
+
count: props.length
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
/** The (unescaped) first class in the rule's selector, e.g. `sm:px-2`. */
|
|
2390
|
+
/** @internal (#401) */ function ruleCandidate(rule) {
|
|
2391
|
+
const c = CLASS.exec(ruleSelector(rule));
|
|
2392
|
+
return c ? c[1].replace(/\\(.)/g, "$1") : "";
|
|
2393
|
+
}
|
|
2394
|
+
/** Tailwind's candidate compare: runs of digits compare by value, other chars by code. */
|
|
2395
|
+
/** @internal (#401) */ function compareCandidates(a, b) {
|
|
2396
|
+
const n = Math.min(a.length, b.length);
|
|
2397
|
+
for (let i = 0; i < n; i++) {
|
|
2398
|
+
let x = a.charCodeAt(i);
|
|
2399
|
+
let y = b.charCodeAt(i);
|
|
2400
|
+
if (x >= 48 && x <= 57 && y >= 48 && y <= 57) {
|
|
2401
|
+
let ae = i + 1;
|
|
2402
|
+
let be = i + 1;
|
|
2403
|
+
for (x = a.charCodeAt(ae); x >= 48 && x <= 57;) x = a.charCodeAt(++ae);
|
|
2404
|
+
for (y = b.charCodeAt(be); y >= 48 && y <= 57;) y = b.charCodeAt(++be);
|
|
2405
|
+
const as = a.slice(i, ae);
|
|
2406
|
+
const bs = b.slice(i, be);
|
|
2407
|
+
const diff = Number(as) - Number(bs);
|
|
2408
|
+
if (diff) return diff;
|
|
2409
|
+
if (as < bs) return -1;
|
|
2410
|
+
if (as > bs) return 1;
|
|
2411
|
+
continue;
|
|
2412
|
+
}
|
|
2413
|
+
if (x !== y) return x - y;
|
|
2414
|
+
}
|
|
2415
|
+
return a.length - b.length;
|
|
2416
|
+
}
|
|
2417
|
+
/** The #254 variant part of the key (leading `@media` / `@container` preludes). */
|
|
2418
|
+
/** @internal (#401) */ function ruleVariantKey(rule) {
|
|
2419
|
+
const key = [];
|
|
2420
|
+
let rest = rule;
|
|
2421
|
+
let m;
|
|
2422
|
+
while (m = LEADING_AT.exec(rest)) {
|
|
2423
|
+
const [g, v] = preludeKey(m[1], m[2]);
|
|
2424
|
+
key.push(g, v);
|
|
2425
|
+
rest = rest.slice(m[0].length);
|
|
2426
|
+
}
|
|
2427
|
+
return key;
|
|
2428
|
+
}
|
|
2429
|
+
/**
|
|
2430
|
+
* Full sort key: the #254 variant pairs, then (#401) Tailwind's property sort and the class name.
|
|
2431
|
+
* `candidate` defaults to the rule's first class.
|
|
2432
|
+
*/
|
|
2433
|
+
function ruleSortKey(rule, candidate) {
|
|
2434
|
+
const name = candidate ?? ruleCandidate(rule);
|
|
2435
|
+
const { order, count } = rulePropertySort(rule, name);
|
|
2436
|
+
const key = ruleVariantKey(rule);
|
|
2437
|
+
key.push(PROPERTY_PART, ...order, NO_MORE, -count, name);
|
|
2438
|
+
return key;
|
|
2439
|
+
}
|
|
2440
|
+
function compareKeys(a, b) {
|
|
2441
|
+
const n = Math.min(a.length, b.length);
|
|
2442
|
+
for (let i = 0; i < n; i++) {
|
|
2443
|
+
const x = a[i];
|
|
2444
|
+
const y = b[i];
|
|
2445
|
+
if (x === y) continue;
|
|
2446
|
+
if (typeof x === "string" || typeof y === "string") {
|
|
2447
|
+
const d = compareCandidates(String(x), String(y));
|
|
2448
|
+
if (d) return d;
|
|
2449
|
+
continue;
|
|
2450
|
+
}
|
|
2451
|
+
return x - y;
|
|
2452
|
+
}
|
|
2453
|
+
return a.length - b.length;
|
|
2454
|
+
}
|
|
2455
|
+
/** Index after the last key <= `key` (stable upper bound) in sorted `keys`. */
|
|
2456
|
+
function upperBound(keys, key) {
|
|
2457
|
+
let lo = 0;
|
|
2458
|
+
let hi = keys.length;
|
|
2459
|
+
while (lo < hi) {
|
|
2460
|
+
const mid = lo + hi >> 1;
|
|
2461
|
+
if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
|
|
2462
|
+
else hi = mid;
|
|
2463
|
+
}
|
|
2464
|
+
return lo;
|
|
2465
|
+
}
|
|
2466
|
+
//#endregion
|
|
1520
2467
|
//#region src/core/engine.ts
|
|
1521
2468
|
var failureCache = /* @__PURE__ */ new Set();
|
|
1522
2469
|
/**
|
|
@@ -1715,6 +2662,10 @@ function parseClassToAst(fullClassName, ctx) {
|
|
|
1715
2662
|
let ast = [];
|
|
1716
2663
|
for (const utilReg of utilRegs) {
|
|
1717
2664
|
ast = utilReg.handler(value, ctx, utility, utilReg) || [];
|
|
2665
|
+
if (ast === REJECT_CLASS) {
|
|
2666
|
+
ast = [];
|
|
2667
|
+
break;
|
|
2668
|
+
}
|
|
1718
2669
|
if (ast.length > 0) break;
|
|
1719
2670
|
}
|
|
1720
2671
|
const wrappers = [];
|
|
@@ -1839,7 +2790,7 @@ var CLASS_SEPARATOR = /[ \t\n\f\r]+/;
|
|
|
1839
2790
|
function generateCss(classList, ctx, opts) {
|
|
1840
2791
|
const seen = /* @__PURE__ */ new Set();
|
|
1841
2792
|
const allAtRootNodes = [];
|
|
1842
|
-
const
|
|
2793
|
+
const generated = classList.split(CLASS_SEPARATOR).filter((cls) => {
|
|
1843
2794
|
if (!cls) return false;
|
|
1844
2795
|
if (opts?.dedup) {
|
|
1845
2796
|
if (seen.has(cls)) return false;
|
|
@@ -1848,12 +2799,31 @@ function generateCss(classList, ctx, opts) {
|
|
|
1848
2799
|
return true;
|
|
1849
2800
|
}).map((cls) => {
|
|
1850
2801
|
try {
|
|
1851
|
-
return
|
|
2802
|
+
return {
|
|
2803
|
+
cls,
|
|
2804
|
+
css: generateOne(cls)
|
|
2805
|
+
};
|
|
1852
2806
|
} catch (err) {
|
|
1853
2807
|
debugWarn("[generateCss] class generation failed:", cls, err);
|
|
1854
|
-
return
|
|
2808
|
+
return {
|
|
2809
|
+
cls,
|
|
2810
|
+
css: ""
|
|
2811
|
+
};
|
|
1855
2812
|
}
|
|
1856
|
-
})
|
|
2813
|
+
});
|
|
2814
|
+
const slots = generated.flatMap((g, i) => g.css ? [i] : []);
|
|
2815
|
+
const sorted = slots.map((i) => ({
|
|
2816
|
+
i,
|
|
2817
|
+
css: generated[i].css,
|
|
2818
|
+
key: ruleSortKey(generated[i].css, generated[i].cls)
|
|
2819
|
+
})).sort((a, b) => compareKeys(a.key, b.key) || a.i - b.i);
|
|
2820
|
+
slots.forEach((slot, j) => {
|
|
2821
|
+
generated[slot] = {
|
|
2822
|
+
cls: generated[slot].cls,
|
|
2823
|
+
css: sorted[j].css
|
|
2824
|
+
};
|
|
2825
|
+
});
|
|
2826
|
+
const results = generated.map((g) => g.css).join(opts?.minify ? "" : "\n");
|
|
1857
2827
|
function generateOne(cls) {
|
|
1858
2828
|
const ast = parseClassToAst(cls, ctx);
|
|
1859
2829
|
const parsedResult = (getContextState(ctx)?.parseResultCache || parseResultCache).get(cls);
|
|
@@ -1864,7 +2834,8 @@ function generateCss(classList, ctx, opts) {
|
|
|
1864
2834
|
const hasStyleRule = cleanAst.some((node) => node.type === "style-rule");
|
|
1865
2835
|
const css = astToCss(cleanAst.filter((node) => node.type !== "at-root"), hasStyleRule ? void 0 : cls, {
|
|
1866
2836
|
minify: opts?.minify,
|
|
1867
|
-
important: parsedResult?.utility?.important ?? false
|
|
2837
|
+
important: parsedResult?.utility?.important ?? false,
|
|
2838
|
+
scope: cls
|
|
1868
2839
|
});
|
|
1869
2840
|
const result = css;
|
|
1870
2841
|
if (!result || result.trim() === "") debugWarn("[generateCss] Empty CSS generated for class:", {
|
|
@@ -1922,7 +2893,10 @@ function generateCssRules(classList, ctx, opts) {
|
|
|
1922
2893
|
cssList.push(css);
|
|
1923
2894
|
});
|
|
1924
2895
|
else {
|
|
1925
|
-
const css = astToCss([node], cls,
|
|
2896
|
+
const css = astToCss([node], cls, {
|
|
2897
|
+
...options,
|
|
2898
|
+
scope: cls
|
|
2899
|
+
});
|
|
1926
2900
|
cssList.push(css);
|
|
1927
2901
|
}
|
|
1928
2902
|
const rootCssList = [];
|
|
@@ -2998,500 +3972,232 @@ function configGetter(config, ...path) {
|
|
|
2998
3972
|
else keys = path;
|
|
2999
3973
|
return keys.reduce((acc, key) => acc ? acc[key] : void 0, config);
|
|
3000
3974
|
}
|
|
3001
|
-
function hasPreset(themeObj, category, preset) {
|
|
3002
|
-
return themeObj[category]?.includes?.(preset);
|
|
3003
|
-
}
|
|
3004
|
-
function resolveTheme(config) {
|
|
3005
|
-
let theme = {};
|
|
3006
|
-
if (config.presets) {
|
|
3007
|
-
for (const preset of config.presets) if (preset.theme) theme = deepMerge(theme, preset.theme);
|
|
3008
|
-
}
|
|
3009
|
-
if (config.theme) {
|
|
3010
|
-
const { extend, ...overrideTheme } = config.theme;
|
|
3011
|
-
theme = deepMerge(theme, overrideTheme);
|
|
3012
|
-
if (extend) theme = deepMerge(theme, extend);
|
|
3013
|
-
}
|
|
3014
|
-
return theme;
|
|
3015
|
-
}
|
|
3016
|
-
function themeToCssVars(theme) {
|
|
3017
|
-
return toCssVarsBlock(themeToCssVarsAll(theme));
|
|
3018
|
-
}
|
|
3019
|
-
function createContext(configObj) {
|
|
3020
|
-
if (configObj.debug !== void 0) setDebug(!!configObj.debug);
|
|
3021
|
-
const configWithDefaults = {
|
|
3022
|
-
presets: [{ theme: require_theme.defaultTheme }, ...configObj.presets || []],
|
|
3023
|
-
...configObj
|
|
3024
|
-
};
|
|
3025
|
-
const themeObj = resolveTheme(configWithDefaults);
|
|
3026
|
-
const ctx = {
|
|
3027
|
-
hasPreset: (category, preset) => {
|
|
3028
|
-
return hasPreset(themeObj, category, preset);
|
|
3029
|
-
},
|
|
3030
|
-
theme: (...args) => {
|
|
3031
|
-
return themeGetter(themeObj, ...args);
|
|
3032
|
-
},
|
|
3033
|
-
config: (...args) => {
|
|
3034
|
-
return configGetter(configWithDefaults, ...args);
|
|
3035
|
-
},
|
|
3036
|
-
themeToCssVars: () => themeToCssVars(themeObj),
|
|
3037
|
-
extendTheme: (category, values) => {
|
|
3038
|
-
if (typeof values === "function") {
|
|
3039
|
-
const result = values(ctx.theme);
|
|
3040
|
-
if (result && typeof result === "object") {
|
|
3041
|
-
const existingValues = themeObj[category] || {};
|
|
3042
|
-
themeObj[category] = {
|
|
3043
|
-
...existingValues,
|
|
3044
|
-
...result
|
|
3045
|
-
};
|
|
3046
|
-
}
|
|
3047
|
-
} else if (typeof values === "object" && values !== null && !Array.isArray(values)) {
|
|
3048
|
-
const existingValues = themeObj[category] || {};
|
|
3049
|
-
themeObj[category] = {
|
|
3050
|
-
...existingValues,
|
|
3051
|
-
...values
|
|
3052
|
-
};
|
|
3053
|
-
}
|
|
3054
|
-
clearContextCaches(ctx);
|
|
3055
|
-
},
|
|
3056
|
-
getPreflightCSS: (level = true) => {
|
|
3057
|
-
return getPreflightCSS(level);
|
|
3058
|
-
}
|
|
3059
|
-
};
|
|
3060
|
-
initializeContextState(ctx, getUtility(), getModifier());
|
|
3061
|
-
registerCustomUtilities(ctx, configObj.utilities);
|
|
3062
|
-
return ctx;
|
|
3063
|
-
}
|
|
3064
|
-
//#endregion
|
|
3065
|
-
//#region src/core/jsonToAst.ts
|
|
3066
|
-
/**
|
|
3067
|
-
* Converts a single BaroJsonInput object into an AST tree.
|
|
3068
|
-
* Bypasses string parsing and directly invokes utility/modifier handlers.
|
|
3069
|
-
*
|
|
3070
|
-
* @param input BaroJsonInput object
|
|
3071
|
-
* @param ctx Context
|
|
3072
|
-
* @returns AstNode[]
|
|
3073
|
-
*/
|
|
3074
|
-
function jsonToAst(input, ctx) {
|
|
3075
|
-
if ((input.variants || []).some((v) => typeof v === "string" ? !isSafeVariantToken(v) : !isSafeVariantValue(v.name || "") || !isSafeVariantValue(v.value || "") || hasCommentToken(v.name || "") || hasCommentToken(v.value || ""))) return [];
|
|
3076
|
-
let utilReg = getUtility(ctx).find((u) => u.name === input.utility.name);
|
|
3077
|
-
if (input.utility.value && !input.utility.arbitrary && !input.utility.customProperty) {
|
|
3078
|
-
const fullName = `${input.utility.name}-${input.utility.value}`;
|
|
3079
|
-
const exactMatch = getUtility(ctx).find((u) => u.name === fullName);
|
|
3080
|
-
if (exactMatch) utilReg = exactMatch;
|
|
3081
|
-
}
|
|
3082
|
-
if (!utilReg) {
|
|
3083
|
-
debugWarn(`[jsonToAst] Unknown utility: "${input.utility.name}"`);
|
|
3084
|
-
return [];
|
|
3085
|
-
}
|
|
3086
|
-
const parsedUtility = {
|
|
3087
|
-
prefix: input.utility.name,
|
|
3088
|
-
value: input.utility.value,
|
|
3089
|
-
arbitrary: input.utility.arbitrary,
|
|
3090
|
-
negative: input.utility.negative,
|
|
3091
|
-
opacity: input.utility.opacity,
|
|
3092
|
-
important: input.utility.important,
|
|
3093
|
-
customProperty: input.utility.customProperty,
|
|
3094
|
-
category: utilReg.category,
|
|
3095
|
-
priority: utilReg.priority
|
|
3096
|
-
};
|
|
3097
|
-
let value = input.utility.value;
|
|
3098
|
-
if (input.utility.negative && value) value = "-" + value;
|
|
3099
|
-
let ast = utilReg.handler(value || "", ctx, parsedUtility, utilReg) || [];
|
|
3100
|
-
if (input.variants && input.variants.length > 0) {
|
|
3101
|
-
const wrappers = [];
|
|
3102
|
-
const selector = "&";
|
|
3103
|
-
for (let i = input.variants.length - 1; i >= 0; i--) {
|
|
3104
|
-
const variantInput = input.variants[i];
|
|
3105
|
-
const variantName = typeof variantInput === "string" ? variantInput : variantInput.name;
|
|
3106
|
-
const variantValue = typeof variantInput === "string" ? void 0 : variantInput.value;
|
|
3107
|
-
const variantArbitrary = typeof variantInput === "string" ? false : variantInput.arbitrary;
|
|
3108
|
-
const parsedModifier = {
|
|
3109
|
-
type: variantName,
|
|
3110
|
-
value: variantValue,
|
|
3111
|
-
arbitrary: variantArbitrary
|
|
3112
|
-
};
|
|
3113
|
-
let matchKey = variantName;
|
|
3114
|
-
if (variantArbitrary && variantValue) {
|
|
3115
|
-
if (variantName) {
|
|
3116
|
-
matchKey = `${variantName}-[${variantValue}]`;
|
|
3117
|
-
parsedModifier.type = matchKey;
|
|
3118
|
-
} else {
|
|
3119
|
-
matchKey = `[${variantValue}]`;
|
|
3120
|
-
parsedModifier.type = matchKey;
|
|
3121
|
-
}
|
|
3122
|
-
} else if (variantValue) {
|
|
3123
|
-
matchKey = `${variantName}-[${variantValue}]`;
|
|
3124
|
-
parsedModifier.type = matchKey;
|
|
3125
|
-
}
|
|
3126
|
-
const plugin = getModifier(ctx).find((p) => p.match(matchKey, ctx));
|
|
3127
|
-
if (!plugin) {
|
|
3128
|
-
debugWarn(`[jsonToAst] Unknown variant: "${matchKey}"`);
|
|
3129
|
-
continue;
|
|
3130
|
-
}
|
|
3131
|
-
if (plugin.astHandler) ast = plugin.astHandler(ast, parsedModifier, ctx, [], i);
|
|
3132
|
-
if (plugin.modifySelector) {
|
|
3133
|
-
const result = plugin.modifySelector({
|
|
3134
|
-
selector,
|
|
3135
|
-
fullClassName: "JSON_GENERATED",
|
|
3136
|
-
mod: parsedModifier,
|
|
3137
|
-
context: ctx,
|
|
3138
|
-
variantChain: [],
|
|
3139
|
-
index: i
|
|
3140
|
-
});
|
|
3141
|
-
if (result == null) continue;
|
|
3142
|
-
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({
|
|
3143
|
-
type: "rule",
|
|
3144
|
-
selector: result
|
|
3145
|
-
});
|
|
3146
|
-
else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
|
|
3147
|
-
const r = result;
|
|
3148
|
-
const wrappingType = r.wrappingType || "rule";
|
|
3149
|
-
wrappers.push({
|
|
3150
|
-
type: wrappingType,
|
|
3151
|
-
selector: r.selector,
|
|
3152
|
-
flatten: r.flatten,
|
|
3153
|
-
source: r.source
|
|
3154
|
-
});
|
|
3155
|
-
} else if (Array.isArray(result)) wrappers.push({
|
|
3156
|
-
type: "wrap",
|
|
3157
|
-
items: result.map((r) => ({
|
|
3158
|
-
type: r.wrappingType || "rule",
|
|
3159
|
-
selector: r.selector,
|
|
3160
|
-
source: r.source,
|
|
3161
|
-
nodes: []
|
|
3162
|
-
}))
|
|
3163
|
-
});
|
|
3164
|
-
}
|
|
3165
|
-
if (plugin.wrap) wrappers.push({
|
|
3166
|
-
type: "wrap",
|
|
3167
|
-
items: plugin.wrap(parsedModifier, ctx)
|
|
3168
|
-
});
|
|
3169
|
-
}
|
|
3170
|
-
for (let i = 0; i < wrappers.length; i++) {
|
|
3171
|
-
const wrap = wrappers[i];
|
|
3172
|
-
if (wrap.type === "wrap") ast = wrap.items.map((item) => item.type === "rule" || item.type === "style-rule" || item.type === "at-rule" || item.type === "at-root" ? {
|
|
3173
|
-
...item,
|
|
3174
|
-
nodes: [...item.nodes || [], ...ast]
|
|
3175
|
-
} : item);
|
|
3176
|
-
else if (wrap.type === "style-rule") ast = [{
|
|
3177
|
-
type: "style-rule",
|
|
3178
|
-
selector: wrap.selector,
|
|
3179
|
-
source: wrap.source,
|
|
3180
|
-
nodes: Array.isArray(ast) ? ast : [ast]
|
|
3181
|
-
}];
|
|
3182
|
-
else if (wrap.type === "at-rule") ast = [{
|
|
3183
|
-
type: "at-rule",
|
|
3184
|
-
name: wrap.name || "media",
|
|
3185
|
-
params: wrap.params,
|
|
3186
|
-
source: wrap.source,
|
|
3187
|
-
nodes: Array.isArray(ast) ? ast : [ast]
|
|
3188
|
-
}];
|
|
3189
|
-
else if (wrap.type === "rule") ast = [{
|
|
3190
|
-
type: "rule",
|
|
3191
|
-
selector: wrap.selector,
|
|
3192
|
-
source: wrap.source,
|
|
3193
|
-
nodes: Array.isArray(ast) ? ast : [ast]
|
|
3194
|
-
}];
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3197
|
-
return applyVarPrefix(ast, ctx);
|
|
3198
|
-
}
|
|
3199
|
-
/**
|
|
3200
|
-
* Generates CSS from a list of BaroJsonInput objects.
|
|
3201
|
-
*
|
|
3202
|
-
* @param inputs Array of BaroJsonInput
|
|
3203
|
-
* @param ctx Context
|
|
3204
|
-
* @param opts Options (minify, etc.)
|
|
3205
|
-
* @returns CSS string
|
|
3206
|
-
*/
|
|
3207
|
-
function generateCssFromJson(inputs, ctx, opts) {
|
|
3208
|
-
const allAtRootNodes = [];
|
|
3209
|
-
const cssList = [];
|
|
3210
|
-
inputs.forEach((input) => {
|
|
3211
|
-
const cleanAst = optimizeAst(jsonToAst(input, ctx));
|
|
3212
|
-
cleanAst.forEach((node) => {
|
|
3213
|
-
if (node.type === "at-root") allAtRootNodes.push(...node.nodes);
|
|
3214
|
-
});
|
|
3215
|
-
let reconstructedName = input.utility.name;
|
|
3216
|
-
if (input.utility.value) reconstructedName += `-${input.utility.value}`;
|
|
3217
|
-
if (input.utility.arbitrary) reconstructedName = `${input.utility.name}-[${input.utility.value}]`;
|
|
3218
|
-
if (input.variants) reconstructedName = `${input.variants.map((v) => typeof v === "string" ? v : v.name).join(":")}:${reconstructedName}`;
|
|
3219
|
-
const css = astToCss(cleanAst, cleanAst.some((node) => node.type === "style-rule") ? void 0 : `.${reconstructedName.replace(/[^a-zA-Z0-9-_]/g, "\\$&")}`, {
|
|
3220
|
-
minify: opts?.minify,
|
|
3221
|
-
important: input.utility.important ?? false
|
|
3222
|
-
});
|
|
3223
|
-
if (css) cssList.push(css);
|
|
3224
|
-
});
|
|
3225
|
-
const rootCss = rootToCss(allAtRootNodes);
|
|
3226
|
-
return `${rootCss ? `:root,:host {${rootCss}}` : ""}${cssList.join(opts?.minify ? "" : "\n")}`;
|
|
3227
|
-
}
|
|
3228
|
-
//#endregion
|
|
3229
|
-
//#region src/core/utils.ts
|
|
3230
|
-
/**
|
|
3231
|
-
* Parses a fraction string (e.g., '1/2') and returns a percentage string (e.g., '50%'), or null if not a valid fraction.
|
|
3232
|
-
*/
|
|
3233
|
-
function parseFraction(input) {
|
|
3234
|
-
if (input.includes("/")) {
|
|
3235
|
-
const [num, denom] = input.split("/").map(Number);
|
|
3236
|
-
if (!isNaN(num) && !isNaN(denom) && denom !== 0) return `${num / denom * 100}%`;
|
|
3237
|
-
}
|
|
3238
|
-
return null;
|
|
3239
|
-
}
|
|
3240
|
-
/**
|
|
3241
|
-
* Returns the input if it is a valid non-negative integer string, else null.
|
|
3242
|
-
*
|
|
3243
|
-
* @example
|
|
3244
|
-
* parseNumber("10") // "10"
|
|
3245
|
-
* parseNumber("-10") // "-10"
|
|
3246
|
-
* parseNumber("10.5") // "10.5"
|
|
3247
|
-
*/
|
|
3248
|
-
function parseNumber(input) {
|
|
3249
|
-
return /^-?\d+(?:\.\d+)?$/.test(input) ? input : null;
|
|
3250
|
-
}
|
|
3251
|
-
/**
|
|
3252
|
-
* Returns the input if it is a valid length string, else null.
|
|
3253
|
-
*/
|
|
3254
|
-
function parseLength(input) {
|
|
3255
|
-
return /^\d+(px|em|rem|vh|vw|vmin|vmax|%|in|cm|mm|pt|pc|ex|ch|fr)$/.test(input) ? input : null;
|
|
3256
|
-
}
|
|
3257
|
-
/**
|
|
3258
|
-
* Unified parser for fraction or number, with options for percent or repeat syntax.
|
|
3259
|
-
* - percent: if true, returns percentage for fraction (e.g., '1/2' -> '50%')
|
|
3260
|
-
* - repeat: if true, returns repeat() for number (e.g., '3' -> 'repeat(3, minmax(0, 1fr))')
|
|
3261
|
-
*/
|
|
3262
|
-
function parseFractionOrNumber(value, opts = {}) {
|
|
3263
|
-
if (/^\d+$/.test(value)) {
|
|
3264
|
-
if (opts.repeat) return `repeat(${value}, minmax(0, 1fr))`;
|
|
3265
|
-
return value;
|
|
3975
|
+
function hasPreset(themeObj, category, preset) {
|
|
3976
|
+
return themeObj[category]?.includes?.(preset);
|
|
3977
|
+
}
|
|
3978
|
+
function resolveTheme(config) {
|
|
3979
|
+
let theme = {};
|
|
3980
|
+
if (config.presets) {
|
|
3981
|
+
for (const preset of config.presets) if (preset.theme) theme = deepMerge(theme, preset.theme);
|
|
3266
3982
|
}
|
|
3267
|
-
if (
|
|
3268
|
-
const
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
if (opts.percent) return `${result * 100}%`;
|
|
3272
|
-
return result.toString();
|
|
3273
|
-
}
|
|
3983
|
+
if (config.theme) {
|
|
3984
|
+
const { extend, ...overrideTheme } = config.theme;
|
|
3985
|
+
theme = deepMerge(theme, overrideTheme);
|
|
3986
|
+
if (extend) theme = deepMerge(theme, extend);
|
|
3274
3987
|
}
|
|
3275
|
-
return
|
|
3988
|
+
return theme;
|
|
3276
3989
|
}
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
"antiquewhite",
|
|
3280
|
-
"aqua",
|
|
3281
|
-
"aquamarine",
|
|
3282
|
-
"azure",
|
|
3283
|
-
"beige",
|
|
3284
|
-
"bisque",
|
|
3285
|
-
"black",
|
|
3286
|
-
"blanchedalmond",
|
|
3287
|
-
"blue",
|
|
3288
|
-
"blueviolet",
|
|
3289
|
-
"brown",
|
|
3290
|
-
"burlywood",
|
|
3291
|
-
"cadetblue",
|
|
3292
|
-
"chartreuse",
|
|
3293
|
-
"chocolate",
|
|
3294
|
-
"coral",
|
|
3295
|
-
"cornflowerblue",
|
|
3296
|
-
"cornsilk",
|
|
3297
|
-
"crimson",
|
|
3298
|
-
"cyan",
|
|
3299
|
-
"darkblue",
|
|
3300
|
-
"darkcyan",
|
|
3301
|
-
"darkgoldenrod",
|
|
3302
|
-
"darkgray",
|
|
3303
|
-
"darkgreen",
|
|
3304
|
-
"darkgrey",
|
|
3305
|
-
"darkkhaki",
|
|
3306
|
-
"darkmagenta",
|
|
3307
|
-
"darkolivegreen",
|
|
3308
|
-
"darkorange",
|
|
3309
|
-
"darkorchid",
|
|
3310
|
-
"darkred",
|
|
3311
|
-
"darksalmon",
|
|
3312
|
-
"darkseagreen",
|
|
3313
|
-
"darkslateblue",
|
|
3314
|
-
"darkslategray",
|
|
3315
|
-
"darkslategrey",
|
|
3316
|
-
"darkturquoise",
|
|
3317
|
-
"darkviolet",
|
|
3318
|
-
"deeppink",
|
|
3319
|
-
"deepskyblue",
|
|
3320
|
-
"dimgray",
|
|
3321
|
-
"dimgrey",
|
|
3322
|
-
"dodgerblue",
|
|
3323
|
-
"firebrick",
|
|
3324
|
-
"floralwhite",
|
|
3325
|
-
"forestgreen",
|
|
3326
|
-
"fuchsia",
|
|
3327
|
-
"gainsboro",
|
|
3328
|
-
"ghostwhite",
|
|
3329
|
-
"gold",
|
|
3330
|
-
"goldenrod",
|
|
3331
|
-
"gray",
|
|
3332
|
-
"grey",
|
|
3333
|
-
"green",
|
|
3334
|
-
"greenyellow",
|
|
3335
|
-
"honeydew",
|
|
3336
|
-
"hotpink",
|
|
3337
|
-
"indianred",
|
|
3338
|
-
"indigo",
|
|
3339
|
-
"ivory",
|
|
3340
|
-
"khaki",
|
|
3341
|
-
"lavender",
|
|
3342
|
-
"lavenderblush",
|
|
3343
|
-
"lawngreen",
|
|
3344
|
-
"lemonchiffon",
|
|
3345
|
-
"lightblue",
|
|
3346
|
-
"lightcoral",
|
|
3347
|
-
"lightcyan",
|
|
3348
|
-
"lightgoldenrodyellow",
|
|
3349
|
-
"lightgray",
|
|
3350
|
-
"lightgreen",
|
|
3351
|
-
"lightgrey",
|
|
3352
|
-
"lightpink",
|
|
3353
|
-
"lightsalmon",
|
|
3354
|
-
"lightseagreen",
|
|
3355
|
-
"lightskyblue",
|
|
3356
|
-
"lightslategray",
|
|
3357
|
-
"lightslategrey",
|
|
3358
|
-
"lightsteelblue",
|
|
3359
|
-
"lightyellow",
|
|
3360
|
-
"lime",
|
|
3361
|
-
"limegreen",
|
|
3362
|
-
"linen",
|
|
3363
|
-
"magenta",
|
|
3364
|
-
"maroon",
|
|
3365
|
-
"mediumaquamarine",
|
|
3366
|
-
"mediumblue",
|
|
3367
|
-
"mediumorchid",
|
|
3368
|
-
"mediumpurple",
|
|
3369
|
-
"mediumseagreen",
|
|
3370
|
-
"mediumslateblue",
|
|
3371
|
-
"mediumspringgreen",
|
|
3372
|
-
"mediumturquoise",
|
|
3373
|
-
"mediumvioletred",
|
|
3374
|
-
"midnightblue",
|
|
3375
|
-
"mintcream",
|
|
3376
|
-
"mistyrose",
|
|
3377
|
-
"moccasin",
|
|
3378
|
-
"navajowhite",
|
|
3379
|
-
"navy",
|
|
3380
|
-
"oldlace",
|
|
3381
|
-
"olive",
|
|
3382
|
-
"olivedrab",
|
|
3383
|
-
"orange",
|
|
3384
|
-
"orangered",
|
|
3385
|
-
"orchid",
|
|
3386
|
-
"palegoldenrod",
|
|
3387
|
-
"palegreen",
|
|
3388
|
-
"paleturquoise",
|
|
3389
|
-
"palevioletred",
|
|
3390
|
-
"papayawhip",
|
|
3391
|
-
"peachpuff",
|
|
3392
|
-
"peru",
|
|
3393
|
-
"pink",
|
|
3394
|
-
"plum",
|
|
3395
|
-
"powderblue",
|
|
3396
|
-
"purple",
|
|
3397
|
-
"red",
|
|
3398
|
-
"rosybrown",
|
|
3399
|
-
"royalblue",
|
|
3400
|
-
"saddlebrown",
|
|
3401
|
-
"salmon",
|
|
3402
|
-
"sandybrown",
|
|
3403
|
-
"seagreen",
|
|
3404
|
-
"seashell",
|
|
3405
|
-
"sienna",
|
|
3406
|
-
"silver",
|
|
3407
|
-
"skyblue",
|
|
3408
|
-
"slateblue",
|
|
3409
|
-
"slategray",
|
|
3410
|
-
"slategrey",
|
|
3411
|
-
"snow",
|
|
3412
|
-
"springgreen",
|
|
3413
|
-
"steelblue",
|
|
3414
|
-
"tan",
|
|
3415
|
-
"teal",
|
|
3416
|
-
"thistle",
|
|
3417
|
-
"tomato",
|
|
3418
|
-
"turquoise",
|
|
3419
|
-
"violet",
|
|
3420
|
-
"wheat",
|
|
3421
|
-
"white",
|
|
3422
|
-
"whitesmoke",
|
|
3423
|
-
"yellow",
|
|
3424
|
-
"yellowgreen"
|
|
3425
|
-
]);
|
|
3426
|
-
/**
|
|
3427
|
-
* Returns the input if it is a valid color string, else null.
|
|
3428
|
-
*
|
|
3429
|
-
* #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)
|
|
3430
|
-
*/
|
|
3431
|
-
function parseColor(input) {
|
|
3432
|
-
if (CSS_COLOR_NAMES.has(input.toLowerCase())) return input;
|
|
3433
|
-
if (input.startsWith("color:var(")) return input.slice(6);
|
|
3434
|
-
if (input.startsWith("color:")) return parseColor(input.slice(6));
|
|
3435
|
-
if (input.startsWith("#") && input.length === 4) return `#${input.slice(1)}`;
|
|
3436
|
-
if (input.startsWith("#") && input.length === 5) return `#${input.slice(1)}`;
|
|
3437
|
-
if (input.startsWith("#") && input.length === 7) return `#${input.slice(1)}`;
|
|
3438
|
-
if (input.startsWith("#") && input.length === 9) return `#${input.slice(1)}`;
|
|
3439
|
-
if (input.startsWith("rgb(")) return input.slice(4, -1);
|
|
3440
|
-
if (input.startsWith("rgba(")) return input.slice(5, -1);
|
|
3441
|
-
if (input.startsWith("hsl(")) return input.slice(4, -1);
|
|
3442
|
-
if (input.startsWith("hsla(")) return input.slice(5, -1);
|
|
3443
|
-
if (input.startsWith("hwb(")) return input.slice(4, -1);
|
|
3444
|
-
if (input.startsWith("lab(")) return input.slice(4, -1);
|
|
3445
|
-
if (input.startsWith("lch(")) return input.slice(4, -1);
|
|
3446
|
-
if (input.startsWith("oklab(")) return input.slice(5, -1);
|
|
3447
|
-
if (input.startsWith("oklch(")) return input.slice(6, -1);
|
|
3448
|
-
if (input.startsWith("color-mix(")) return input.slice(9, -1);
|
|
3449
|
-
return null;
|
|
3990
|
+
function themeToCssVars(theme) {
|
|
3991
|
+
return toCssVarsBlock(themeToCssVarsAll(theme));
|
|
3450
3992
|
}
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3993
|
+
function createContext(configObj) {
|
|
3994
|
+
if (configObj.debug !== void 0) setDebug(!!configObj.debug);
|
|
3995
|
+
const configWithDefaults = {
|
|
3996
|
+
presets: [{ theme: require_theme.defaultTheme }, ...configObj.presets || []],
|
|
3997
|
+
...configObj
|
|
3998
|
+
};
|
|
3999
|
+
const themeObj = resolveTheme(configWithDefaults);
|
|
4000
|
+
const ctx = {
|
|
4001
|
+
hasPreset: (category, preset) => {
|
|
4002
|
+
return hasPreset(themeObj, category, preset);
|
|
4003
|
+
},
|
|
4004
|
+
theme: (...args) => {
|
|
4005
|
+
return themeGetter(themeObj, ...args);
|
|
4006
|
+
},
|
|
4007
|
+
config: (...args) => {
|
|
4008
|
+
return configGetter(configWithDefaults, ...args);
|
|
4009
|
+
},
|
|
4010
|
+
themeToCssVars: () => themeToCssVars(themeObj),
|
|
4011
|
+
extendTheme: (category, values) => {
|
|
4012
|
+
if (typeof values === "function") {
|
|
4013
|
+
const result = values(ctx.theme);
|
|
4014
|
+
if (result && typeof result === "object") {
|
|
4015
|
+
const existingValues = themeObj[category] || {};
|
|
4016
|
+
themeObj[category] = {
|
|
4017
|
+
...existingValues,
|
|
4018
|
+
...result
|
|
4019
|
+
};
|
|
4020
|
+
}
|
|
4021
|
+
} else if (typeof values === "object" && values !== null && !Array.isArray(values)) {
|
|
4022
|
+
const existingValues = themeObj[category] || {};
|
|
4023
|
+
themeObj[category] = {
|
|
4024
|
+
...existingValues,
|
|
4025
|
+
...values
|
|
4026
|
+
};
|
|
4027
|
+
}
|
|
4028
|
+
clearContextCaches(ctx);
|
|
4029
|
+
},
|
|
4030
|
+
getPreflightCSS: (level = true) => {
|
|
4031
|
+
return getPreflightCSS(level);
|
|
4032
|
+
}
|
|
4033
|
+
};
|
|
4034
|
+
initializeContextState(ctx, getUtility(), getModifier());
|
|
4035
|
+
registerCustomUtilities(ctx, configObj.utilities);
|
|
4036
|
+
return ctx;
|
|
4037
|
+
}
|
|
4038
|
+
//#endregion
|
|
4039
|
+
//#region src/core/jsonToAst.ts
|
|
3456
4040
|
/**
|
|
3457
|
-
*
|
|
3458
|
-
*
|
|
4041
|
+
* Converts a single BaroJsonInput object into an AST tree.
|
|
4042
|
+
* Bypasses string parsing and directly invokes utility/modifier handlers.
|
|
4043
|
+
*
|
|
4044
|
+
* @param input BaroJsonInput object
|
|
4045
|
+
* @param ctx Context
|
|
4046
|
+
* @returns AstNode[]
|
|
3459
4047
|
*/
|
|
3460
|
-
function
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
if (!
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
4048
|
+
function jsonToAst(input, ctx) {
|
|
4049
|
+
if ((input.variants || []).some((v) => typeof v === "string" ? !isSafeVariantToken(v) : !isSafeVariantValue(v.name || "") || !isSafeVariantValue(v.value || "") || hasCommentToken(v.name || "") || hasCommentToken(v.value || ""))) return [];
|
|
4050
|
+
let utilReg = getUtility(ctx).find((u) => u.name === input.utility.name);
|
|
4051
|
+
if (input.utility.value && !input.utility.arbitrary && !input.utility.customProperty) {
|
|
4052
|
+
const fullName = `${input.utility.name}-${input.utility.value}`;
|
|
4053
|
+
const exactMatch = getUtility(ctx).find((u) => u.name === fullName);
|
|
4054
|
+
if (exactMatch) utilReg = exactMatch;
|
|
4055
|
+
}
|
|
4056
|
+
if (!utilReg) {
|
|
4057
|
+
debugWarn(`[jsonToAst] Unknown utility: "${input.utility.name}"`);
|
|
4058
|
+
return [];
|
|
4059
|
+
}
|
|
4060
|
+
const parsedUtility = {
|
|
4061
|
+
prefix: input.utility.name,
|
|
4062
|
+
value: input.utility.value,
|
|
4063
|
+
arbitrary: input.utility.arbitrary,
|
|
4064
|
+
negative: input.utility.negative,
|
|
4065
|
+
opacity: input.utility.opacity,
|
|
4066
|
+
important: input.utility.important,
|
|
4067
|
+
customProperty: input.utility.customProperty,
|
|
4068
|
+
category: utilReg.category,
|
|
4069
|
+
priority: utilReg.priority
|
|
4070
|
+
};
|
|
4071
|
+
let value = input.utility.value;
|
|
4072
|
+
if (input.utility.negative && value) value = "-" + value;
|
|
4073
|
+
let ast = utilReg.handler(value || "", ctx, parsedUtility, utilReg) || [];
|
|
4074
|
+
if (input.variants && input.variants.length > 0) {
|
|
4075
|
+
const wrappers = [];
|
|
4076
|
+
const selector = "&";
|
|
4077
|
+
for (let i = input.variants.length - 1; i >= 0; i--) {
|
|
4078
|
+
const variantInput = input.variants[i];
|
|
4079
|
+
const variantName = typeof variantInput === "string" ? variantInput : variantInput.name;
|
|
4080
|
+
const variantValue = typeof variantInput === "string" ? void 0 : variantInput.value;
|
|
4081
|
+
const variantArbitrary = typeof variantInput === "string" ? false : variantInput.arbitrary;
|
|
4082
|
+
const parsedModifier = {
|
|
4083
|
+
type: variantName,
|
|
4084
|
+
value: variantValue,
|
|
4085
|
+
arbitrary: variantArbitrary
|
|
4086
|
+
};
|
|
4087
|
+
let matchKey = variantName;
|
|
4088
|
+
if (variantArbitrary && variantValue) {
|
|
4089
|
+
if (variantName) {
|
|
4090
|
+
matchKey = `${variantName}-[${variantValue}]`;
|
|
4091
|
+
parsedModifier.type = matchKey;
|
|
4092
|
+
} else {
|
|
4093
|
+
matchKey = `[${variantValue}]`;
|
|
4094
|
+
parsedModifier.type = matchKey;
|
|
4095
|
+
}
|
|
4096
|
+
} else if (variantValue) {
|
|
4097
|
+
matchKey = `${variantName}-[${variantValue}]`;
|
|
4098
|
+
parsedModifier.type = matchKey;
|
|
4099
|
+
}
|
|
4100
|
+
const plugin = getModifier(ctx).find((p) => p.match(matchKey, ctx));
|
|
4101
|
+
if (!plugin) {
|
|
4102
|
+
debugWarn(`[jsonToAst] Unknown variant: "${matchKey}"`);
|
|
4103
|
+
continue;
|
|
4104
|
+
}
|
|
4105
|
+
if (plugin.astHandler) ast = plugin.astHandler(ast, parsedModifier, ctx, [], i);
|
|
4106
|
+
if (plugin.modifySelector) {
|
|
4107
|
+
const result = plugin.modifySelector({
|
|
4108
|
+
selector,
|
|
4109
|
+
fullClassName: "JSON_GENERATED",
|
|
4110
|
+
mod: parsedModifier,
|
|
4111
|
+
context: ctx,
|
|
4112
|
+
variantChain: [],
|
|
4113
|
+
index: i
|
|
4114
|
+
});
|
|
4115
|
+
if (result == null) continue;
|
|
4116
|
+
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({
|
|
4117
|
+
type: "rule",
|
|
4118
|
+
selector: result
|
|
4119
|
+
});
|
|
4120
|
+
else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
|
|
4121
|
+
const r = result;
|
|
4122
|
+
const wrappingType = r.wrappingType || "rule";
|
|
4123
|
+
wrappers.push({
|
|
4124
|
+
type: wrappingType,
|
|
4125
|
+
selector: r.selector,
|
|
4126
|
+
flatten: r.flatten,
|
|
4127
|
+
source: r.source
|
|
4128
|
+
});
|
|
4129
|
+
} else if (Array.isArray(result)) wrappers.push({
|
|
4130
|
+
type: "wrap",
|
|
4131
|
+
items: result.map((r) => ({
|
|
4132
|
+
type: r.wrappingType || "rule",
|
|
4133
|
+
selector: r.selector,
|
|
4134
|
+
source: r.source,
|
|
4135
|
+
nodes: []
|
|
4136
|
+
}))
|
|
4137
|
+
});
|
|
4138
|
+
}
|
|
4139
|
+
if (plugin.wrap) wrappers.push({
|
|
4140
|
+
type: "wrap",
|
|
4141
|
+
items: plugin.wrap(parsedModifier, ctx)
|
|
4142
|
+
});
|
|
4143
|
+
}
|
|
4144
|
+
for (let i = 0; i < wrappers.length; i++) {
|
|
4145
|
+
const wrap = wrappers[i];
|
|
4146
|
+
if (wrap.type === "wrap") ast = wrap.items.map((item) => item.type === "rule" || item.type === "style-rule" || item.type === "at-rule" || item.type === "at-root" ? {
|
|
4147
|
+
...item,
|
|
4148
|
+
nodes: [...item.nodes || [], ...ast]
|
|
4149
|
+
} : item);
|
|
4150
|
+
else if (wrap.type === "style-rule") ast = [{
|
|
4151
|
+
type: "style-rule",
|
|
4152
|
+
selector: wrap.selector,
|
|
4153
|
+
source: wrap.source,
|
|
4154
|
+
nodes: Array.isArray(ast) ? ast : [ast]
|
|
4155
|
+
}];
|
|
4156
|
+
else if (wrap.type === "at-rule") ast = [{
|
|
4157
|
+
type: "at-rule",
|
|
4158
|
+
name: wrap.name || "media",
|
|
4159
|
+
params: wrap.params,
|
|
4160
|
+
source: wrap.source,
|
|
4161
|
+
nodes: Array.isArray(ast) ? ast : [ast]
|
|
4162
|
+
}];
|
|
4163
|
+
else if (wrap.type === "rule") ast = [{
|
|
4164
|
+
type: "rule",
|
|
4165
|
+
selector: wrap.selector,
|
|
4166
|
+
source: wrap.source,
|
|
4167
|
+
nodes: Array.isArray(ast) ? ast : [ast]
|
|
4168
|
+
}];
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
return applyVarPrefix(ast, ctx);
|
|
3468
4172
|
}
|
|
3469
4173
|
/**
|
|
3470
|
-
*
|
|
3471
|
-
*
|
|
4174
|
+
* Generates CSS from a list of BaroJsonInput objects.
|
|
4175
|
+
*
|
|
4176
|
+
* @param inputs Array of BaroJsonInput
|
|
4177
|
+
* @param ctx Context
|
|
4178
|
+
* @param opts Options (minify, etc.)
|
|
4179
|
+
* @returns CSS string
|
|
3472
4180
|
*/
|
|
3473
|
-
function
|
|
3474
|
-
|
|
3475
|
-
const
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
};
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
isVar: false
|
|
3494
|
-
};
|
|
4181
|
+
function generateCssFromJson(inputs, ctx, opts) {
|
|
4182
|
+
const allAtRootNodes = [];
|
|
4183
|
+
const cssList = [];
|
|
4184
|
+
inputs.forEach((input) => {
|
|
4185
|
+
const cleanAst = optimizeAst(jsonToAst(input, ctx));
|
|
4186
|
+
cleanAst.forEach((node) => {
|
|
4187
|
+
if (node.type === "at-root") allAtRootNodes.push(...node.nodes);
|
|
4188
|
+
});
|
|
4189
|
+
let reconstructedName = input.utility.name;
|
|
4190
|
+
if (input.utility.value) reconstructedName += `-${input.utility.value}`;
|
|
4191
|
+
if (input.utility.arbitrary) reconstructedName = `${input.utility.name}-[${input.utility.value}]`;
|
|
4192
|
+
if (input.variants) reconstructedName = `${input.variants.map((v) => typeof v === "string" ? v : v.name).join(":")}:${reconstructedName}`;
|
|
4193
|
+
const css = astToCss(cleanAst, cleanAst.some((node) => node.type === "style-rule") ? void 0 : `.${reconstructedName.replace(/[^a-zA-Z0-9-_]/g, "\\$&")}`, {
|
|
4194
|
+
minify: opts?.minify,
|
|
4195
|
+
important: input.utility.important ?? false
|
|
4196
|
+
});
|
|
4197
|
+
if (css) cssList.push(css);
|
|
4198
|
+
});
|
|
4199
|
+
const rootCss = rootToCss(allAtRootNodes);
|
|
4200
|
+
return `${rootCss ? `:root,:host {${rootCss}}` : ""}${cssList.join(opts?.minify ? "" : "\n")}`;
|
|
3495
4201
|
}
|
|
3496
4202
|
//#endregion
|
|
3497
4203
|
//#region src/presets/interactivity.ts
|
|
@@ -3505,10 +4211,7 @@ functionalUtility({
|
|
|
3505
4211
|
supportsArbitrary: true,
|
|
3506
4212
|
supportsCustomProperty: true,
|
|
3507
4213
|
handle: (value, _ctx, _token, extra) => {
|
|
3508
|
-
if (extra?.realThemeValue)
|
|
3509
|
-
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)];
|
|
3510
|
-
return [decl("accent-color", `var(--color-${extra.realThemeValue})`)];
|
|
3511
|
-
}
|
|
4214
|
+
if (extra?.realThemeValue) return themeColorDecls("accent-color", value, extra);
|
|
3512
4215
|
return [decl("accent-color", value)];
|
|
3513
4216
|
},
|
|
3514
4217
|
handleCustomProperty: (value) => [decl("accent-color", `var(${value})`)],
|
|
@@ -3527,10 +4230,7 @@ functionalUtility({
|
|
|
3527
4230
|
supportsArbitrary: true,
|
|
3528
4231
|
supportsCustomProperty: true,
|
|
3529
4232
|
handle: (value, ctx, token, extra) => {
|
|
3530
|
-
if (extra?.realThemeValue)
|
|
3531
|
-
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)];
|
|
3532
|
-
return [decl("caret-color", `var(--color-${extra.realThemeValue})`)];
|
|
3533
|
-
}
|
|
4233
|
+
if (extra?.realThemeValue) return themeColorDecls("caret-color", value, extra);
|
|
3534
4234
|
return [decl("caret-color", value)];
|
|
3535
4235
|
},
|
|
3536
4236
|
handleCustomProperty: (value) => [decl("caret-color", `var(${value})`)],
|
|
@@ -3895,22 +4595,11 @@ staticUtility("caption-bottom", [["caption-side", "bottom"]], { category: "table
|
|
|
3895
4595
|
//#region src/presets/shadow-color.ts
|
|
3896
4596
|
/** Opacity modifier to an alpha: `50` → 50%, `[20%]` → 20%, `(--o)` → var(--o); anything else is invalid. */
|
|
3897
4597
|
function parseAlpha(op) {
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
alpha:
|
|
3901
|
-
isVar:
|
|
3902
|
-
};
|
|
3903
|
-
const pct = /^\[(\d+(?:\.\d+)?)%\]$/.exec(op);
|
|
3904
|
-
if (pct) return {
|
|
3905
|
-
alpha: `${pct[1]}%`,
|
|
3906
|
-
isVar: false
|
|
3907
|
-
};
|
|
3908
|
-
const cp = /^\((--[\w-]+)\)$/.exec(op);
|
|
3909
|
-
if (cp) return {
|
|
3910
|
-
alpha: `var(${cp[1]})`,
|
|
3911
|
-
isVar: true
|
|
4598
|
+
const a = op ? normalizeAlpha(op) : null;
|
|
4599
|
+
return a && {
|
|
4600
|
+
alpha: a.amount,
|
|
4601
|
+
isVar: a.isVar
|
|
3912
4602
|
};
|
|
3913
|
-
return null;
|
|
3914
4603
|
}
|
|
3915
4604
|
function splitTop(value, sep) {
|
|
3916
4605
|
const out = [];
|
|
@@ -4419,6 +5108,11 @@ function layerColor(layer, main, opacity, token, realThemeValue) {
|
|
|
4419
5108
|
if (main.startsWith("color:")) return shadowColorDecls(layer, `var(${main.slice(6)})`, opacity);
|
|
4420
5109
|
if (token.arbitrary && parseColor(main)) return shadowColorDecls(layer, main, opacity);
|
|
4421
5110
|
}
|
|
5111
|
+
function customShadowAlpha(layer, opacity) {
|
|
5112
|
+
if (!opacity) return [];
|
|
5113
|
+
const a = parseAlpha(opacity);
|
|
5114
|
+
return a ? [decl(`--baro-${layer}-alpha`, a.alpha)] : null;
|
|
5115
|
+
}
|
|
4422
5116
|
for (const layer of ["shadow", "inset-shadow"]) functionalUtility({
|
|
4423
5117
|
name: layer,
|
|
4424
5118
|
supportsArbitrary: true,
|
|
@@ -4435,11 +5129,17 @@ for (const layer of ["shadow", "inset-shadow"]) functionalUtility({
|
|
|
4435
5129
|
if (token.arbitrary) return boxShadowLayer(layer, layer === "inset-shadow" ? insetEach(value) : value, opacity);
|
|
4436
5130
|
return null;
|
|
4437
5131
|
},
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
5132
|
+
ownsOpacity: true,
|
|
5133
|
+
handleCustomProperty: (value, _ctx, _token, extra) => {
|
|
5134
|
+
if (value.startsWith("color:")) return shadowColorDecls(layer, `var(${value.slice(6)})`, extra?.opacity) ?? [];
|
|
5135
|
+
const alpha = customShadowAlpha(layer, extra?.opacity);
|
|
5136
|
+
return alpha ? [
|
|
5137
|
+
ringShadowProperties(),
|
|
5138
|
+
...alpha,
|
|
5139
|
+
decl(`--baro-${layer}`, layer === "inset-shadow" ? `inset var(${value})` : `var(${value})`),
|
|
5140
|
+
decl("box-shadow", SHADOW_COMPOSITE)
|
|
5141
|
+
] : [];
|
|
5142
|
+
}
|
|
4443
5143
|
});
|
|
4444
5144
|
var textShadowProperties = () => atRoot([property("--baro-text-shadow-color"), property("--baro-text-shadow-alpha", "100%", "<percentage>")]);
|
|
4445
5145
|
var namedTextShadow = (ctx, name) => {
|
|
@@ -4469,7 +5169,19 @@ functionalUtility({
|
|
|
4469
5169
|
if (token.arbitrary) return textShadowValue(value, opacity);
|
|
4470
5170
|
return null;
|
|
4471
5171
|
},
|
|
4472
|
-
|
|
5172
|
+
ownsOpacity: true,
|
|
5173
|
+
handleCustomProperty: (value, _ctx, _token, extra) => {
|
|
5174
|
+
if (value.startsWith("color:")) {
|
|
5175
|
+
const color = shadowColorDecls("text-shadow", `var(${value.slice(6)})`, extra?.opacity);
|
|
5176
|
+
return color ? [textShadowProperties(), ...color] : [];
|
|
5177
|
+
}
|
|
5178
|
+
const alpha = customShadowAlpha("text-shadow", extra?.opacity);
|
|
5179
|
+
return alpha ? [
|
|
5180
|
+
textShadowProperties(),
|
|
5181
|
+
...alpha,
|
|
5182
|
+
decl("text-shadow", `var(${value})`)
|
|
5183
|
+
] : [];
|
|
5184
|
+
},
|
|
4473
5185
|
category: "effects"
|
|
4474
5186
|
});
|
|
4475
5187
|
[
|
|
@@ -4533,17 +5245,6 @@ functionalUtility({
|
|
|
4533
5245
|
], { category: "effects" });
|
|
4534
5246
|
});
|
|
4535
5247
|
staticUtility("ring-inset", [["--baro-ring-inset", "inset"]], { category: "effects" });
|
|
4536
|
-
function createRingColorDecls(key, main, opacity, realThemeValue) {
|
|
4537
|
-
const colorVar = `var(--color-${realThemeValue})`;
|
|
4538
|
-
let colorMix = colorVar;
|
|
4539
|
-
let fallback = colorVar;
|
|
4540
|
-
if (opacity) {
|
|
4541
|
-
colorMix = `color-mix(in oklab, ${colorVar} ${opacity}%, transparent)`;
|
|
4542
|
-
if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
|
|
4543
|
-
else fallback = colorMix;
|
|
4544
|
-
}
|
|
4545
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl(key, colorMix)]), decl(key, fallback)];
|
|
4546
|
-
}
|
|
4547
5248
|
functionalUtility({
|
|
4548
5249
|
name: "ring",
|
|
4549
5250
|
supportsArbitrary: true,
|
|
@@ -4557,28 +5258,9 @@ functionalUtility({
|
|
|
4557
5258
|
decl("--baro-ring-shadow", ringShadowValue(value)),
|
|
4558
5259
|
decl("box-shadow", SHADOW_COMPOSITE)
|
|
4559
5260
|
];
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
if (realThemeValue) return createRingColorDecls("--baro-ring-color", main, opacity, realThemeValue);
|
|
4563
|
-
if (main.startsWith("color:")) {
|
|
4564
|
-
const cp = main.replace("color:", "");
|
|
4565
|
-
let colorMix = `var(${cp})`;
|
|
4566
|
-
let fallback = colorMix;
|
|
4567
|
-
if (opacity) {
|
|
4568
|
-
colorMix = `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`;
|
|
4569
|
-
fallback = colorMix;
|
|
4570
|
-
}
|
|
4571
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-ring-color", colorMix)]), decl("--baro-ring-color", fallback)];
|
|
4572
|
-
}
|
|
5261
|
+
if (extra?.realThemeValue) return themeColorDecls("--baro-ring-color", main, extra);
|
|
5262
|
+
if (main.startsWith("color:")) return [decl("--baro-ring-color", `var(${main.slice(6)})`)];
|
|
4573
5263
|
if (token.arbitrary) {
|
|
4574
|
-
let colorMix = main;
|
|
4575
|
-
let fallback = main;
|
|
4576
|
-
if (opacity) {
|
|
4577
|
-
colorMix = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
|
|
4578
|
-
if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
|
|
4579
|
-
else fallback = colorMix;
|
|
4580
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-ring-color", colorMix)]), decl("--baro-ring-color", fallback)];
|
|
4581
|
-
}
|
|
4582
5264
|
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)) {
|
|
4583
5265
|
const width = main.startsWith("length:") ? main.slice(7) : main;
|
|
4584
5266
|
return [
|
|
@@ -4587,7 +5269,7 @@ functionalUtility({
|
|
|
4587
5269
|
decl("box-shadow", SHADOW_COMPOSITE)
|
|
4588
5270
|
];
|
|
4589
5271
|
}
|
|
4590
|
-
return [parseColor(main) ? decl("--baro-ring-color", main) : decl("box-shadow", main)];
|
|
5272
|
+
return [parseColor(main) || /^var\(--[^)]+\)$/.test(main) ? decl("--baro-ring-color", main) : decl("box-shadow", main)];
|
|
4591
5273
|
}
|
|
4592
5274
|
if (main === "inherit" || main === "current" || main === "transparent") return [decl("--baro-ring-color", main === "current" ? "currentColor" : main)];
|
|
4593
5275
|
return null;
|
|
@@ -4605,30 +5287,9 @@ functionalUtility({
|
|
|
4605
5287
|
themeKeys: ["colors", "shadows"],
|
|
4606
5288
|
handle: (value, ctx, token, extra) => {
|
|
4607
5289
|
const main = value;
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
if (
|
|
4611
|
-
if (main.startsWith("color:")) {
|
|
4612
|
-
const cp = main.replace("color:", "");
|
|
4613
|
-
let colorMix = `var(${cp})`;
|
|
4614
|
-
let fallback = colorMix;
|
|
4615
|
-
if (opacity) {
|
|
4616
|
-
colorMix = `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`;
|
|
4617
|
-
fallback = colorMix;
|
|
4618
|
-
}
|
|
4619
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-inset-ring-color", colorMix)]), decl("--baro-inset-ring-color", fallback)];
|
|
4620
|
-
}
|
|
4621
|
-
if (token.arbitrary) {
|
|
4622
|
-
let colorMix = main;
|
|
4623
|
-
let fallback = main;
|
|
4624
|
-
if (opacity) {
|
|
4625
|
-
colorMix = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
|
|
4626
|
-
if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
|
|
4627
|
-
else fallback = colorMix;
|
|
4628
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-inset-ring-color", colorMix)]), decl("--baro-inset-ring-color", fallback)];
|
|
4629
|
-
}
|
|
4630
|
-
return [decl("box-shadow", `inset ${main}`)];
|
|
4631
|
-
}
|
|
5290
|
+
if (extra?.realThemeValue) return themeColorDecls("--baro-inset-ring-color", main, extra);
|
|
5291
|
+
if (main.startsWith("color:")) return [decl("--baro-inset-ring-color", `var(${main.slice(6)})`)];
|
|
5292
|
+
if (token.arbitrary) return [parseColor(main) || /^var\(--[^)]+\)$/.test(main) ? decl("--baro-inset-ring-color", main) : decl("box-shadow", `inset ${main}`)];
|
|
4632
5293
|
if (main === "inherit" || main === "current" || main === "transparent") return [decl("--baro-inset-ring-color", main === "current" ? "currentColor" : main)];
|
|
4633
5294
|
return null;
|
|
4634
5295
|
},
|
|
@@ -6453,7 +7114,7 @@ functionalUtility({
|
|
|
6453
7114
|
supportsOpacity: true,
|
|
6454
7115
|
handle: (value, _ctx, _token, extra) => {
|
|
6455
7116
|
if (extra?.realThemeValue) return [rule("&::placeholder", themeColorDecls("color", value, extra))];
|
|
6456
|
-
if (parseColor(value)) return placeholderColor(value);
|
|
7117
|
+
if (parseColor(value) || /^var\(--[\w-]+\)$/.test(value)) return placeholderColor(value);
|
|
6457
7118
|
return null;
|
|
6458
7119
|
},
|
|
6459
7120
|
handleCustomProperty: (value) => placeholderColor(`var(${value})`),
|
|
@@ -6659,7 +7320,7 @@ var stopsDecls = (stop, color) => {
|
|
|
6659
7320
|
if (parseColor(value)) return stopsDecls(stop, value);
|
|
6660
7321
|
return null;
|
|
6661
7322
|
},
|
|
6662
|
-
handleCustomProperty: (value) => [decl(`--baro-gradient-${stop}`, `var(${value})`)],
|
|
7323
|
+
handleCustomProperty: (value) => value.startsWith("color:") ? stopsDecls(stop, `var(${value.slice(6)})`) : [decl(`--baro-gradient-${stop}`, `var(${value})`)],
|
|
6663
7324
|
description: `${stop} gradient stop utility (color, percent, custom property, arbitrary supported)`,
|
|
6664
7325
|
category: "background"
|
|
6665
7326
|
});
|
|
@@ -6713,6 +7374,7 @@ functionalUtility({
|
|
|
6713
7374
|
return [decl("background-color", value)];
|
|
6714
7375
|
}
|
|
6715
7376
|
if (parseLength(value)) return [decl("background-size", value)];
|
|
7377
|
+
if (/^var\(--[^)]+\)$/.test(value)) return [decl("background-color", value)];
|
|
6716
7378
|
return null;
|
|
6717
7379
|
},
|
|
6718
7380
|
handleCustomProperty: (value) => {
|
|
@@ -6840,11 +7502,11 @@ var withBorderStyle = (props, width) => [
|
|
|
6840
7502
|
...propList.map((prop) => [prop.replace("width", "style"), "var(--baro-border-style)"]),
|
|
6841
7503
|
...propList.map((prop) => [prop, width])
|
|
6842
7504
|
];
|
|
6843
|
-
staticUtility(`${name}-0`, styled("0px"));
|
|
6844
|
-
staticUtility(`${name}-2`, styled("2px"));
|
|
6845
|
-
staticUtility(`${name}-4`, styled("4px"));
|
|
6846
|
-
staticUtility(`${name}-8`, styled("8px"));
|
|
6847
|
-
staticUtility(`${name}`, styled("1px"));
|
|
7505
|
+
staticUtility(`${name}-0`, styled("0px"), { category: "borders" });
|
|
7506
|
+
staticUtility(`${name}-2`, styled("2px"), { category: "borders" });
|
|
7507
|
+
staticUtility(`${name}-4`, styled("4px"), { category: "borders" });
|
|
7508
|
+
staticUtility(`${name}-8`, styled("8px"), { category: "borders" });
|
|
7509
|
+
staticUtility(`${name}`, styled("1px"), { category: "borders" });
|
|
6848
7510
|
functionalUtility({
|
|
6849
7511
|
name,
|
|
6850
7512
|
themeKeys: ["colors", "borderWidth"],
|
|
@@ -7014,7 +7676,7 @@ functionalUtility({
|
|
|
7014
7676
|
return null;
|
|
7015
7677
|
},
|
|
7016
7678
|
handleCustomProperty: (value) => {
|
|
7017
|
-
if (value.startsWith("color:")) return [decl("outline-color", value.
|
|
7679
|
+
if (value.startsWith("color:")) return [decl("outline-color", `var(${value.slice(6)})`)];
|
|
7018
7680
|
if (value.startsWith("length:")) return withOutlineStyle(`var(${value.replace("length:", "")})`);
|
|
7019
7681
|
return [decl("outline-color", `var(${value})`)];
|
|
7020
7682
|
},
|
|
@@ -7046,7 +7708,7 @@ functionalUtility({
|
|
|
7046
7708
|
handle: (value, _ctx, token, extra) => {
|
|
7047
7709
|
if (token.prefix !== "divide") return null;
|
|
7048
7710
|
if (extra?.realThemeValue) return [rule(":where(& > :not(:last-child))", themeColorDecls("border-color", value, extra))];
|
|
7049
|
-
if (parseColor(value)) return divideColor(value);
|
|
7711
|
+
if (parseColor(value) || /^var\(--[\w-]+\)$/.test(value)) return divideColor(value);
|
|
7050
7712
|
return null;
|
|
7051
7713
|
},
|
|
7052
7714
|
handleCustomProperty: (value, _ctx, token) => token.prefix === "divide" ? divideColor(`var(${value})`) : [],
|
|
@@ -7465,8 +8127,9 @@ functionalUtility({
|
|
|
7465
8127
|
themeKeys: ["colors"],
|
|
7466
8128
|
supportsArbitrary: true,
|
|
7467
8129
|
supportsCustomProperty: true,
|
|
8130
|
+
supportsOpacity: true,
|
|
7468
8131
|
handle: (value, ctx, token, extra) => {
|
|
7469
|
-
if (extra?.realThemeValue) return
|
|
8132
|
+
if (extra?.realThemeValue) return themeColorDecls("fill", value, extra);
|
|
7470
8133
|
return [decl("fill", value)];
|
|
7471
8134
|
},
|
|
7472
8135
|
description: "fill utility (static, theme, arbitrary, custom property supported)",
|
|
@@ -7482,6 +8145,7 @@ functionalUtility({
|
|
|
7482
8145
|
themeKeys: ["colors", "strokeWidth"],
|
|
7483
8146
|
supportsArbitrary: true,
|
|
7484
8147
|
supportsCustomProperty: true,
|
|
8148
|
+
supportsOpacity: true,
|
|
7485
8149
|
handle: (value, ctx, token, extra) => {
|
|
7486
8150
|
if (parseNumber(value) || extra?.themeNamespace === "strokeWidth") return [decl("stroke-width", value)];
|
|
7487
8151
|
if (token.arbitrary) {
|
|
@@ -7489,7 +8153,7 @@ functionalUtility({
|
|
|
7489
8153
|
if (hint) return [decl("stroke-width", hint[2])];
|
|
7490
8154
|
if (!parseColor(value) && (STROKE_LENGTH.test(value) || /^calc\(/.test(value))) return [decl("stroke-width", value)];
|
|
7491
8155
|
}
|
|
7492
|
-
if (extra?.realThemeValue) return
|
|
8156
|
+
if (extra?.realThemeValue) return themeColorDecls("stroke", value, extra);
|
|
7493
8157
|
return [decl("stroke", value)];
|
|
7494
8158
|
},
|
|
7495
8159
|
handleCustomProperty: (value) => {
|
|
@@ -8498,56 +9162,10 @@ functionalModifier((mod) => /^child-(.+)$/.test(mod), ({ selector, mod }) => {
|
|
|
8498
9162
|
};
|
|
8499
9163
|
}, void 0);
|
|
8500
9164
|
//#endregion
|
|
8501
|
-
//#region src/core/rule-order.ts
|
|
8502
|
-
var LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
|
|
8503
|
-
var LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
|
|
8504
|
-
var MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
|
|
8505
|
-
var MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
|
|
8506
|
-
function toPx(n, unit) {
|
|
8507
|
-
const v = parseFloat(n);
|
|
8508
|
-
return unit === "rem" || unit === "em" ? v * 16 : v;
|
|
8509
|
-
}
|
|
8510
|
-
function preludeKey(kind, prelude) {
|
|
8511
|
-
const container = kind === "container";
|
|
8512
|
-
if (!container && /^\s*not\b/i.test(prelude)) return [0, 0];
|
|
8513
|
-
const min = MIN_W.exec(prelude);
|
|
8514
|
-
if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
|
|
8515
|
-
const max = MAX_W.exec(prelude);
|
|
8516
|
-
if (max) return [container ? 3 : 1, -toPx(max[1], max[2])];
|
|
8517
|
-
if (!container && LATE_MEDIA.test(prelude)) return [5, 0];
|
|
8518
|
-
return [0, 0];
|
|
8519
|
-
}
|
|
8520
|
-
function ruleSortKey(rule) {
|
|
8521
|
-
const key = [];
|
|
8522
|
-
let rest = rule;
|
|
8523
|
-
let m;
|
|
8524
|
-
while (m = LEADING_AT.exec(rest)) {
|
|
8525
|
-
const [g, v] = preludeKey(m[1], m[2]);
|
|
8526
|
-
key.push(g, v);
|
|
8527
|
-
rest = rest.slice(m[0].length);
|
|
8528
|
-
}
|
|
8529
|
-
return key;
|
|
8530
|
-
}
|
|
8531
|
-
function compareKeys(a, b) {
|
|
8532
|
-
const n = Math.min(a.length, b.length);
|
|
8533
|
-
for (let i = 0; i < n; i++) if (a[i] !== b[i]) return a[i] - b[i];
|
|
8534
|
-
return a.length - b.length;
|
|
8535
|
-
}
|
|
8536
|
-
/** Index after the last key <= `key` (stable upper bound) in sorted `keys`. */
|
|
8537
|
-
function upperBound(keys, key) {
|
|
8538
|
-
let lo = 0;
|
|
8539
|
-
let hi = keys.length;
|
|
8540
|
-
while (lo < hi) {
|
|
8541
|
-
const mid = lo + hi >> 1;
|
|
8542
|
-
if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
|
|
8543
|
-
else hi = mid;
|
|
8544
|
-
}
|
|
8545
|
-
return lo;
|
|
8546
|
-
}
|
|
8547
|
-
//#endregion
|
|
8548
9165
|
exports.AstCache = AstCache;
|
|
8549
9166
|
exports.IncrementalParser = IncrementalParser;
|
|
8550
9167
|
exports.ParseResultCache = ParseResultCache;
|
|
9168
|
+
exports.REJECT_CLASS = REJECT_CLASS;
|
|
8551
9169
|
exports.UtilityCache = UtilityCache;
|
|
8552
9170
|
exports.WeakCache = WeakCache;
|
|
8553
9171
|
exports.arbitraryPropertyRegistration = arbitraryPropertyRegistration;
|
|
@@ -8585,6 +9203,7 @@ exports.isBalancedPrelude = isBalancedPrelude;
|
|
|
8585
9203
|
exports.isDebug = isDebug;
|
|
8586
9204
|
exports.isSafeVariantToken = isSafeVariantToken;
|
|
8587
9205
|
exports.isSafeVariantValue = isSafeVariantValue;
|
|
9206
|
+
exports.isScopedSelector = isScopedSelector;
|
|
8588
9207
|
exports.isStructureSafeValue = isStructureSafeValue;
|
|
8589
9208
|
exports.isWellFormedVariantBrackets = isWellFormedVariantBrackets;
|
|
8590
9209
|
exports.jsonToAst = jsonToAst;
|