@barocss/kit 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +212 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +61 -14
- package/dist/index.js +212 -32
- package/dist/index.js.map +1 -1
- package/dist/theme/default.cjs +6 -9
- package/dist/theme/default.cjs.map +1 -1
- package/dist/theme/default.js +6 -9
- package/dist/theme/default.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -181,6 +181,8 @@ export declare type AstNode = {
|
|
|
181
181
|
|
|
182
182
|
export declare function comment(text: string, source?: string): AstNode;
|
|
183
183
|
|
|
184
|
+
export declare function compareKeys(a: RuleKey, b: RuleKey): number;
|
|
185
|
+
|
|
184
186
|
export declare interface Config {
|
|
185
187
|
prefix?: string;
|
|
186
188
|
cssVarPrefix?: string;
|
|
@@ -217,6 +219,15 @@ export declare type AstNode = {
|
|
|
217
219
|
* clear caches that belong to another context.
|
|
218
220
|
*/
|
|
219
221
|
clearCacheOnContextChange?: boolean;
|
|
222
|
+
/**
|
|
223
|
+
* #287: static custom utilities, the runtime mirror of a stylesheet's static `@utility name { ... }`.
|
|
224
|
+
* Name → declarations (property → value; CSS custom properties allowed). Each one is registered on
|
|
225
|
+
* this context only; variants and `!` apply as usual. A name equal to a built-in extends it like
|
|
226
|
+
* `@utility` in Tailwind 4: the built-in declarations are emitted first, then the custom ones (a later
|
|
227
|
+
* duplicate property wins). An entry with an invalid name, property or value is skipped whole.
|
|
228
|
+
* @example utilities: { 'max-w-app': { 'max-width': '72rem', 'margin-inline': 'auto' } }
|
|
229
|
+
*/
|
|
230
|
+
utilities?: CustomUtilities;
|
|
220
231
|
[key: string]: unknown;
|
|
221
232
|
}
|
|
222
233
|
|
|
@@ -235,6 +246,12 @@ export declare type AstNode = {
|
|
|
235
246
|
|
|
236
247
|
export declare function createContext(configObj: Config): Context;
|
|
237
248
|
|
|
249
|
+
/** #287: static custom utilities by class name. */
|
|
250
|
+
export declare type CustomUtilities = Record<string, CustomUtilityDeclarations>;
|
|
251
|
+
|
|
252
|
+
/** #287: declarations of one static custom utility (property → value). */
|
|
253
|
+
export declare type CustomUtilityDeclarations = Record<string, string | number>;
|
|
254
|
+
|
|
238
255
|
export declare function decl(prop: string, value: string | [string, string][], source?: string): AstNode;
|
|
239
256
|
|
|
240
257
|
export declare type DeclPath = PathNode[];
|
|
@@ -268,20 +285,6 @@ export declare type AstNode = {
|
|
|
268
285
|
|
|
269
286
|
export declare function functionalModifier(match: ModifierRegistration['match'], modifySelector: ModifierRegistration['modifySelector'], wrap?: ModifierRegistration['wrap'], options?: Partial<ModifierRegistration>, ctx?: Context): void;
|
|
270
287
|
|
|
271
|
-
/**
|
|
272
|
-
* functionalUtility: A helper that registers dynamic utilities (theme, arbitrary, custom, negative, fraction, etc.) directly
|
|
273
|
-
*
|
|
274
|
-
* Example:
|
|
275
|
-
* functionalUtility({
|
|
276
|
-
* name: 'z',
|
|
277
|
-
* supportsNegative: true,
|
|
278
|
-
* themeKeys: ['--z-index'],
|
|
279
|
-
* handleBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
|
|
280
|
-
* handle: (value) => [decl('z-index', value)],
|
|
281
|
-
* description: 'z-index utility',
|
|
282
|
-
* category: 'layout',
|
|
283
|
-
* });
|
|
284
|
-
*/
|
|
285
288
|
export declare function functionalUtility(opts: FunctionalUtilityOptions, ctx?: Context): void;
|
|
286
289
|
|
|
287
290
|
export declare type FunctionalUtilityExtra = {
|
|
@@ -420,6 +423,12 @@ export declare type AstNode = {
|
|
|
420
423
|
* handleNegativeBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
|
|
421
424
|
* ```
|
|
422
425
|
*/
|
|
426
|
+
/**
|
|
427
|
+
* #261: the utility uses the spacing scale, so a named `theme.spacing` key (`p-gutter`) resolves to
|
|
428
|
+
* `var(--spacing-<key>)` (negative: `calc(var(--spacing-<key>) * -1)`), as in Tailwind 4. Only tried
|
|
429
|
+
* after the bare-value handler rejects the value, so built-in keywords keep precedence.
|
|
430
|
+
*/
|
|
431
|
+
spacingKeys?: boolean;
|
|
423
432
|
handleNegativeBareValue?: (args: {
|
|
424
433
|
value: string;
|
|
425
434
|
ctx: Context;
|
|
@@ -552,6 +561,13 @@ export declare type AstNode = {
|
|
|
552
561
|
|
|
553
562
|
export declare function getUtility(ctx?: Context): UtilityRegistration[];
|
|
554
563
|
|
|
564
|
+
/**
|
|
565
|
+
* #273: true when an emitted selector or at-rule prelude contains a comment opener or closer outside a CSS escape.
|
|
566
|
+
* Backslash-escape pairs are skipped, so an escaped `\/` or `\*` from a class name never counts. Used by the
|
|
567
|
+
* serializer on the final, composed string, where adjacent pieces that were each safe alone can join into one.
|
|
568
|
+
*/
|
|
569
|
+
export declare function hasCommentDelimiter(text: string): boolean;
|
|
570
|
+
|
|
555
571
|
/**
|
|
556
572
|
* #224: true when a utility value (or a whole utility token) cannot change the structure of the declaration block it
|
|
557
573
|
* is pasted into. Rejects, outside quotes: `{`, `}`, `;`, unbalanced or mismatched ()/[], and a quote left open.
|
|
@@ -771,6 +787,13 @@ export declare type AstNode = {
|
|
|
771
787
|
* @param cls - The CSS class name to mark as processed
|
|
772
788
|
*/
|
|
773
789
|
markProcessed(cls: string): void;
|
|
790
|
+
/**
|
|
791
|
+
* Forgets that a class was processed, so a later request generates it again
|
|
792
|
+
* (used when the browser runtime reclaims an unused class's rules, #269).
|
|
793
|
+
*
|
|
794
|
+
* @param cls - The CSS class name to forget
|
|
795
|
+
*/
|
|
796
|
+
unmarkProcessed(cls: string): void;
|
|
774
797
|
/**
|
|
775
798
|
* Process classes synchronously and update BrowserRuntime cache
|
|
776
799
|
* This method is used by ChangeDetector for scan operations
|
|
@@ -973,6 +996,27 @@ export declare type AstNode = {
|
|
|
973
996
|
|
|
974
997
|
export declare function rule(selector: string, nodes: AstNode[], source?: string): AstNode;
|
|
975
998
|
|
|
999
|
+
/**
|
|
1000
|
+
* Tailwind-compatible cascade order for runtime-inserted rules (#254); shared by @barocss/server (#267).
|
|
1001
|
+
*
|
|
1002
|
+
* The runtime discovers classes in DOM order, so without sorting `lg:px-8`
|
|
1003
|
+
* seen before `sm:px-6` would land earlier and lose at >= 1024px. Each rule
|
|
1004
|
+
* gets a sort key derived from its leading `@media` / `@container` preludes:
|
|
1005
|
+
*
|
|
1006
|
+
* 0 base, state media (hover), motion/contrast, unknown
|
|
1007
|
+
* 1 max-* breakpoints (larger width first)
|
|
1008
|
+
* 2 min-* breakpoints (smaller width first)
|
|
1009
|
+
* 3 @max-* container queries (larger width first)
|
|
1010
|
+
* 4 @min-* container queries (smaller width first)
|
|
1011
|
+
* 5 orientation, dark (prefers-color-scheme), print, forced-colors
|
|
1012
|
+
*
|
|
1013
|
+
* Nested at-rules (e.g. `sm:dark:`) contribute one key pair per level, so
|
|
1014
|
+
* `sm:` < `sm:dark:` < `md:`. Equal keys keep discovery order.
|
|
1015
|
+
*/
|
|
1016
|
+
export declare type RuleKey = number[];
|
|
1017
|
+
|
|
1018
|
+
export declare function ruleSortKey(rule: string): RuleKey;
|
|
1019
|
+
|
|
976
1020
|
/** Internal hook for caches owned by contexts. */
|
|
977
1021
|
export declare function setContextCacheReset(reset: () => void): void;
|
|
978
1022
|
|
|
@@ -1087,6 +1131,9 @@ export declare type AstNode = {
|
|
|
1087
1131
|
*/
|
|
1088
1132
|
export declare function tokenize(className: string): Token[];
|
|
1089
1133
|
|
|
1134
|
+
/** Index after the last key <= `key` (stable upper bound) in sorted `keys`. */
|
|
1135
|
+
export declare function upperBound(keys: RuleKey[], key: RuleKey): number;
|
|
1136
|
+
|
|
1090
1137
|
/**
|
|
1091
1138
|
* Utility cache management
|
|
1092
1139
|
*/
|
package/dist/index.js
CHANGED
|
@@ -337,6 +337,11 @@ function staticUtility(name, decls, opts, ctx) {
|
|
|
337
337
|
priority: opts?.priority
|
|
338
338
|
}, ctx);
|
|
339
339
|
}
|
|
340
|
+
function spacingKeyValue(ctx, key, negative) {
|
|
341
|
+
if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
|
|
342
|
+
const ref = `var(--spacing-${key})`;
|
|
343
|
+
return negative ? `calc(${ref} * -1)` : ref;
|
|
344
|
+
}
|
|
340
345
|
function functionalUtility(opts, ctx) {
|
|
341
346
|
registerUtility({
|
|
342
347
|
name: opts.name,
|
|
@@ -405,14 +410,17 @@ function functionalUtility(opts, ctx) {
|
|
|
405
410
|
if (opts.supportsFraction && /^-?\d+\/\d+$/.test(value)) {
|
|
406
411
|
finalValue = value;
|
|
407
412
|
}
|
|
413
|
+
const spacingKey = opts.spacingKeys ? spacingKeyValue(ctx2, String(finalValue).replace(/^-/, ""), !!parsedUtility.negative) : null;
|
|
408
414
|
if (parsedUtility.negative && opts.supportsNegative && opts.handleNegativeBareValue) {
|
|
409
|
-
const bare = opts.handleNegativeBareValue({ value: String(finalValue).replace(/^-/, ""), ctx: ctx2, token, extra });
|
|
415
|
+
const bare = opts.handleNegativeBareValue({ value: String(finalValue).replace(/^-/, ""), ctx: ctx2, token, extra }) ?? spacingKey;
|
|
410
416
|
if (bare == null) return [];
|
|
411
417
|
finalValue = bare;
|
|
412
418
|
} else if (opts.handleBareValue) {
|
|
413
|
-
const bare = opts.handleBareValue({ value: finalValue, ctx: ctx2, token, extra });
|
|
419
|
+
const bare = opts.handleBareValue({ value: finalValue, ctx: ctx2, token, extra }) ?? spacingKey;
|
|
414
420
|
if (bare == null) return [];
|
|
415
421
|
finalValue = bare;
|
|
422
|
+
} else if (spacingKey) {
|
|
423
|
+
finalValue = spacingKey;
|
|
416
424
|
} else if (!/^-?(\d|\.\d)/.test(String(finalValue))) {
|
|
417
425
|
return [];
|
|
418
426
|
}
|
|
@@ -547,14 +555,23 @@ function parseClassName(className, ctx) {
|
|
|
547
555
|
if (cache.has(className)) {
|
|
548
556
|
return cache.get(className);
|
|
549
557
|
}
|
|
550
|
-
let important = false;
|
|
551
558
|
let realClassName = className;
|
|
552
|
-
|
|
559
|
+
const classPrefix = ctx ? configuredClassPrefix(ctx) : "";
|
|
560
|
+
if (classPrefix) {
|
|
561
|
+
if (!className.startsWith(classPrefix + ":")) {
|
|
562
|
+
const none = { modifiers: [], utility: null };
|
|
563
|
+
cache.set(className, none);
|
|
564
|
+
return none;
|
|
565
|
+
}
|
|
566
|
+
realClassName = className.slice(classPrefix.length + 1);
|
|
567
|
+
}
|
|
568
|
+
let important = false;
|
|
569
|
+
if (realClassName.startsWith("!")) {
|
|
553
570
|
important = true;
|
|
554
|
-
realClassName =
|
|
555
|
-
} else if (
|
|
571
|
+
realClassName = realClassName.slice(1);
|
|
572
|
+
} else if (realClassName.length > 1 && realClassName.endsWith("!")) {
|
|
556
573
|
important = true;
|
|
557
|
-
realClassName =
|
|
574
|
+
realClassName = realClassName.slice(0, -1);
|
|
558
575
|
}
|
|
559
576
|
const tokens = tokenize(realClassName);
|
|
560
577
|
const result = parseTokens(tokens, ctx);
|
|
@@ -564,6 +581,10 @@ function parseClassName(className, ctx) {
|
|
|
564
581
|
cache.set(className, result);
|
|
565
582
|
return result;
|
|
566
583
|
}
|
|
584
|
+
function configuredClassPrefix(ctx) {
|
|
585
|
+
const configured = ctx.config("prefix");
|
|
586
|
+
return typeof configured === "string" && /^[a-z]+$/.test(configured) ? configured : "";
|
|
587
|
+
}
|
|
567
588
|
function parseTokens(tokens, ctx) {
|
|
568
589
|
const modifiers = [];
|
|
569
590
|
let utility = null;
|
|
@@ -623,6 +644,18 @@ function isSafeVariantToken(value) {
|
|
|
623
644
|
function hasCommentToken(value) {
|
|
624
645
|
return value.includes("/*") || value.includes("*/");
|
|
625
646
|
}
|
|
647
|
+
function hasCommentDelimiter(text) {
|
|
648
|
+
for (let i = 0; i < text.length - 1; i++) {
|
|
649
|
+
const c = text[i];
|
|
650
|
+
if (c === "\\") {
|
|
651
|
+
i++;
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
const n = text[i + 1];
|
|
655
|
+
if (c === "/" && n === "*" || c === "*" && n === "/") return true;
|
|
656
|
+
}
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
626
659
|
function isStructureSafeValue(value) {
|
|
627
660
|
if (hasCommentToken(value)) return false;
|
|
628
661
|
return isSafeVariantValue(value, true);
|
|
@@ -770,6 +803,7 @@ function parseUtility(value, ctx) {
|
|
|
770
803
|
priority
|
|
771
804
|
};
|
|
772
805
|
}
|
|
806
|
+
const isSafePrelude = (text) => !hasCommentDelimiter(String(text ?? ""));
|
|
773
807
|
const isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? ""));
|
|
774
808
|
const importantPrefix = "!important";
|
|
775
809
|
function astToCss(ast, baseSelector, opts, _indent = "") {
|
|
@@ -833,6 +867,7 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
|
|
|
833
867
|
}).join(", ");
|
|
834
868
|
}
|
|
835
869
|
}
|
|
870
|
+
if (!isSafePrelude(selector)) return "";
|
|
836
871
|
if (minify) {
|
|
837
872
|
const css = `${indent}${selector}{${astToCss(
|
|
838
873
|
node.nodes,
|
|
@@ -857,6 +892,7 @@ ${astToCss(
|
|
|
857
892
|
}
|
|
858
893
|
}
|
|
859
894
|
case "style-rule": {
|
|
895
|
+
if (!isSafePrelude(node.selector)) return "";
|
|
860
896
|
if (minify) {
|
|
861
897
|
const css = `${indent}${node.selector} {${astToCss(
|
|
862
898
|
node.nodes,
|
|
@@ -881,6 +917,7 @@ ${astToCss(
|
|
|
881
917
|
}
|
|
882
918
|
}
|
|
883
919
|
case "at-rule": {
|
|
920
|
+
if (!isSafePrelude(node.name) || !isSafePrelude(node.params)) return "";
|
|
884
921
|
if (minify) {
|
|
885
922
|
const css = `${indent}@${node.name} ${node.params}{${astToCss(
|
|
886
923
|
node.nodes,
|
|
@@ -934,7 +971,7 @@ function rootToCss(nodes, opts) {
|
|
|
934
971
|
if (isSafeDecl(node.prop, node.value)) {
|
|
935
972
|
list.push(minify ? `${node.prop}:${node.value};` : `${node.prop}: ${node.value};`);
|
|
936
973
|
}
|
|
937
|
-
} else if (node.type === "at-rule") {
|
|
974
|
+
} else if (node.type === "at-rule" && isSafePrelude(node.name) && isSafePrelude(node.params)) {
|
|
938
975
|
if (minify) {
|
|
939
976
|
const body = node.nodes.filter((child) => child.type === "decl" && isSafeDecl(child.prop, child.value)).map((child) => child.type === "decl" ? `${child.prop}:${child.value};` : "").join("");
|
|
940
977
|
list.push(`@${node.name} ${node.params}{${body}}`);
|
|
@@ -1071,24 +1108,41 @@ function animationToCssVars(animations) {
|
|
|
1071
1108
|
}
|
|
1072
1109
|
return result;
|
|
1073
1110
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1111
|
+
const COMMENT_OR_BLOCK = /\/\*|\*\/|[{};]/;
|
|
1112
|
+
function keyframesBlock(name, frames) {
|
|
1113
|
+
if (!name || COMMENT_OR_BLOCK.test(name) || /\s/.test(name) || !frames || typeof frames !== "object") return "";
|
|
1114
|
+
let body = "";
|
|
1115
|
+
for (const [step, props] of Object.entries(frames)) {
|
|
1116
|
+
if (COMMENT_OR_BLOCK.test(step) || !props || typeof props !== "object") return "";
|
|
1117
|
+
let decls = "";
|
|
1118
|
+
for (const [prop, value] of Object.entries(props)) {
|
|
1119
|
+
const v2 = String(value);
|
|
1120
|
+
if (COMMENT_OR_BLOCK.test(prop) || COMMENT_OR_BLOCK.test(v2)) return "";
|
|
1121
|
+
decls += ` ${prop}: ${v2};
|
|
1080
1122
|
`;
|
|
1081
|
-
for (const step in frames) {
|
|
1082
|
-
css += ` ${step} {`;
|
|
1083
|
-
const props = frames[step];
|
|
1084
|
-
for (const prop in props) {
|
|
1085
|
-
css += ` ${prop}: ${props[prop]};`;
|
|
1086
|
-
}
|
|
1087
|
-
css += " }\n";
|
|
1088
1123
|
}
|
|
1089
|
-
|
|
1124
|
+
body += ` ${step} {
|
|
1125
|
+
${decls} }
|
|
1126
|
+
`;
|
|
1090
1127
|
}
|
|
1091
|
-
return
|
|
1128
|
+
return `@keyframes ${name} {
|
|
1129
|
+
${body}}`;
|
|
1130
|
+
}
|
|
1131
|
+
function referencedKeyframes(css, ctx) {
|
|
1132
|
+
if (!css.includes("animation")) return [];
|
|
1133
|
+
const all = ctx.theme("keyframes");
|
|
1134
|
+
if (!all || typeof all !== "object") return [];
|
|
1135
|
+
const names = /* @__PURE__ */ new Set();
|
|
1136
|
+
for (const m of css.matchAll(/(?:^|[\s;{])animation(?:-name)?\s*:\s*([^;}]+)/g)) {
|
|
1137
|
+
const value = m[1].replace(/var\(--animate-([\w-]+)\)/g, (whole, key) => {
|
|
1138
|
+
const v2 = ctx.theme("animations", key) ?? ctx.theme("animation", key);
|
|
1139
|
+
return typeof v2 === "string" ? v2 : whole;
|
|
1140
|
+
});
|
|
1141
|
+
for (const word of value.split(/[\s,()]+/)) {
|
|
1142
|
+
if (word && Object.prototype.hasOwnProperty.call(all, word)) names.add(word);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
return [...names].map((n) => keyframesBlock(n, all[n])).filter(Boolean);
|
|
1092
1146
|
}
|
|
1093
1147
|
function transitionTimingFunctionToCssVars(transition) {
|
|
1094
1148
|
const result = {};
|
|
@@ -1156,7 +1210,7 @@ function themeToCssVarsAll(theme) {
|
|
|
1156
1210
|
...borderRadiusToCssVars(theme.borderRadius),
|
|
1157
1211
|
...zIndexToCssVars(theme.zIndex),
|
|
1158
1212
|
...opacityToCssVars(theme.opacity),
|
|
1159
|
-
...animationToCssVars(theme.animations),
|
|
1213
|
+
...animationToCssVars({ ...theme.animations, ...theme.animation }),
|
|
1160
1214
|
...transitionTimingFunctionToCssVars(theme.transitionTimingFunction),
|
|
1161
1215
|
...transitionDurationToCssVars(theme.transitionDuration),
|
|
1162
1216
|
...transitionDelayToCssVars(theme.transitionDelay),
|
|
@@ -1165,8 +1219,13 @@ function themeToCssVarsAll(theme) {
|
|
|
1165
1219
|
// keyframes handled separately
|
|
1166
1220
|
};
|
|
1167
1221
|
}
|
|
1222
|
+
function isSelfReferencingVar(name, value) {
|
|
1223
|
+
if (typeof value !== "string") return false;
|
|
1224
|
+
const m = /^var\(\s*(--[\w-]+)\s*(?:,[\s\S]*)?\)$/.exec(value.trim());
|
|
1225
|
+
return !!m && m[1] === name.trim();
|
|
1226
|
+
}
|
|
1168
1227
|
function toCssVarsBlock(vars, extra = "") {
|
|
1169
|
-
return ":root,:host {\n" + Object.entries(vars).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
|
|
1228
|
+
return ":root,:host {\n" + Object.entries(vars).filter(([k, v2]) => !isSelfReferencingVar(k, v2)).map(([k, v2]) => ` ${k}: ${v2};`).join("\n") + "\n}\n" + extra + "\n";
|
|
1170
1229
|
}
|
|
1171
1230
|
const BARO_VAR = /--baro-/g;
|
|
1172
1231
|
const PREFIXED_KEYS = /* @__PURE__ */ new Set(["prop", "value", "params", "selector", "nodes", "items"]);
|
|
@@ -1521,7 +1580,11 @@ function generateCss(classList, ctx, opts) {
|
|
|
1521
1580
|
}
|
|
1522
1581
|
return result;
|
|
1523
1582
|
}).join(opts?.minify ? "" : "\n");
|
|
1524
|
-
const rootRules = [
|
|
1583
|
+
const rootRules = [.../* @__PURE__ */ new Set([
|
|
1584
|
+
...allAtRootNodes.filter((node) => node.type === "at-rule").map((node) => rootToCss([node], { minify: opts?.minify })),
|
|
1585
|
+
// #274: the @keyframes the class rules reference, once per sheet.
|
|
1586
|
+
...referencedKeyframes(results, ctx)
|
|
1587
|
+
])];
|
|
1525
1588
|
const rootDeclarations = [...new Set(allAtRootNodes.filter((node) => node.type === "decl").map((node) => rootToCss([node], { minify: opts?.minify })).filter((decl2) => decl2 !== ""))];
|
|
1526
1589
|
const rootCss = [
|
|
1527
1590
|
...rootRules,
|
|
@@ -1579,6 +1642,7 @@ function generateCssRules(classList, ctx, opts) {
|
|
|
1579
1642
|
const css = rootToCss([node]);
|
|
1580
1643
|
rootCssList.push(css);
|
|
1581
1644
|
}
|
|
1645
|
+
rootCssList.push(...referencedKeyframes(cssList.join("\n"), ctx));
|
|
1582
1646
|
return {
|
|
1583
1647
|
cls,
|
|
1584
1648
|
ast: allCleanAst,
|
|
@@ -1841,6 +1905,15 @@ class IncrementalParser {
|
|
|
1841
1905
|
markProcessed(cls) {
|
|
1842
1906
|
this.processedClasses.add(cls);
|
|
1843
1907
|
}
|
|
1908
|
+
/**
|
|
1909
|
+
* Forgets that a class was processed, so a later request generates it again
|
|
1910
|
+
* (used when the browser runtime reclaims an unused class's rules, #269).
|
|
1911
|
+
*
|
|
1912
|
+
* @param cls - The CSS class name to forget
|
|
1913
|
+
*/
|
|
1914
|
+
unmarkProcessed(cls) {
|
|
1915
|
+
this.processedClasses.delete(cls);
|
|
1916
|
+
}
|
|
1844
1917
|
/**
|
|
1845
1918
|
* Process classes synchronously and update BrowserRuntime cache
|
|
1846
1919
|
* This method is used by ChangeDetector for scan operations
|
|
@@ -1860,6 +1933,48 @@ class IncrementalParser {
|
|
|
1860
1933
|
return Array.from(this.processedClasses);
|
|
1861
1934
|
}
|
|
1862
1935
|
}
|
|
1936
|
+
const customUtilityName = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
1937
|
+
const customUtilityProp = /^(--[A-Za-z0-9_-]+|-?[A-Za-z][A-Za-z0-9-]*)$/;
|
|
1938
|
+
function validateCustomUtility(name, decls) {
|
|
1939
|
+
if (typeof name !== "string" || !customUtilityName.test(name)) return null;
|
|
1940
|
+
if (!decls || typeof decls !== "object" || Array.isArray(decls)) return null;
|
|
1941
|
+
const out = [];
|
|
1942
|
+
for (const [prop, raw2] of Object.entries(decls)) {
|
|
1943
|
+
if (typeof raw2 !== "string" && typeof raw2 !== "number") return null;
|
|
1944
|
+
const value = String(raw2).trim();
|
|
1945
|
+
if (!customUtilityProp.test(prop) || !value || !isStructureSafeValue(value) || hasCommentDelimiter(value)) return null;
|
|
1946
|
+
out.push([prop, value]);
|
|
1947
|
+
}
|
|
1948
|
+
return out.length ? out : null;
|
|
1949
|
+
}
|
|
1950
|
+
function registerCustomUtilities(ctx, utilities) {
|
|
1951
|
+
if (!utilities || typeof utilities !== "object" || Array.isArray(utilities)) return;
|
|
1952
|
+
const list = getUtility(ctx);
|
|
1953
|
+
const builtins = [...list];
|
|
1954
|
+
const before = list.length;
|
|
1955
|
+
for (const [name, decls] of Object.entries(utilities)) {
|
|
1956
|
+
const safe = validateCustomUtility(name, decls);
|
|
1957
|
+
if (!safe) {
|
|
1958
|
+
debugWarn(`[BAROCSS] Ignoring invalid custom utility "${name}"`);
|
|
1959
|
+
continue;
|
|
1960
|
+
}
|
|
1961
|
+
const shadowed = builtins.filter((u) => u.match(name));
|
|
1962
|
+
registerUtility({
|
|
1963
|
+
name,
|
|
1964
|
+
category: "custom",
|
|
1965
|
+
match: (className) => className === name,
|
|
1966
|
+
handler: (value, c, token) => {
|
|
1967
|
+
let base = [];
|
|
1968
|
+
for (const reg of shadowed) {
|
|
1969
|
+
base = reg.handler(value, c, token, reg) || [];
|
|
1970
|
+
if (base.length > 0) break;
|
|
1971
|
+
}
|
|
1972
|
+
return [...base, ...safe.map(([prop, v]) => decl(prop, v))];
|
|
1973
|
+
}
|
|
1974
|
+
}, ctx);
|
|
1975
|
+
}
|
|
1976
|
+
if (list.length > before) list.unshift(...list.splice(before));
|
|
1977
|
+
}
|
|
1863
1978
|
const preflightMinimalCSS = `
|
|
1864
1979
|
/* BaroCSS Preflight - Minimal Reset */
|
|
1865
1980
|
/* ================================= */
|
|
@@ -2645,7 +2760,6 @@ function getPreflightCSS(level = true) {
|
|
|
2645
2760
|
return "";
|
|
2646
2761
|
}
|
|
2647
2762
|
const defaultConfig = {
|
|
2648
|
-
prefix: "barocss-",
|
|
2649
2763
|
darkMode: "media"
|
|
2650
2764
|
// same as default
|
|
2651
2765
|
};
|
|
@@ -2747,9 +2861,7 @@ function resolveTheme(config) {
|
|
|
2747
2861
|
}
|
|
2748
2862
|
function themeToCssVars(theme) {
|
|
2749
2863
|
const vars = themeToCssVarsAll(theme);
|
|
2750
|
-
const result = toCssVarsBlock(vars
|
|
2751
|
-
${keyframesToCss(theme.keyframes || {})}
|
|
2752
|
-
`);
|
|
2864
|
+
const result = toCssVarsBlock(vars);
|
|
2753
2865
|
return result;
|
|
2754
2866
|
}
|
|
2755
2867
|
function createContext(configObj) {
|
|
@@ -2803,6 +2915,7 @@ function createContext(configObj) {
|
|
|
2803
2915
|
}
|
|
2804
2916
|
};
|
|
2805
2917
|
initializeContextState(ctx, getUtility(), getModifier());
|
|
2918
|
+
registerCustomUtilities(ctx, configObj.utilities);
|
|
2806
2919
|
return ctx;
|
|
2807
2920
|
}
|
|
2808
2921
|
function jsonToAst(input, ctx) {
|
|
@@ -3387,6 +3500,7 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
|
|
|
3387
3500
|
].forEach(([name, prop]) => {
|
|
3388
3501
|
functionalUtility({
|
|
3389
3502
|
name: `scroll-${name}`,
|
|
3503
|
+
spacingKeys: true,
|
|
3390
3504
|
prop,
|
|
3391
3505
|
supportsArbitrary: true,
|
|
3392
3506
|
supportsCustomProperty: true,
|
|
@@ -3414,6 +3528,7 @@ staticUtility("snap-proximity", [["--baro-scroll-snap-strictness", "proximity"]]
|
|
|
3414
3528
|
].forEach(([name, prop]) => {
|
|
3415
3529
|
functionalUtility({
|
|
3416
3530
|
name: `scroll-${name}`,
|
|
3531
|
+
spacingKeys: true,
|
|
3417
3532
|
prop,
|
|
3418
3533
|
supportsArbitrary: true,
|
|
3419
3534
|
supportsCustomProperty: true,
|
|
@@ -3572,10 +3687,12 @@ staticUtility("animate-bounce", [["animation", "var(--animate-bounce)"]], { cate
|
|
|
3572
3687
|
staticUtility("animate-none", [["animation", "none"]], { category: "transitions" });
|
|
3573
3688
|
functionalUtility({
|
|
3574
3689
|
name: "animate",
|
|
3575
|
-
|
|
3690
|
+
// #274: theme.animations (and Tailwind's theme.animation) names, e.g. theme.extend.animation.wiggle.
|
|
3691
|
+
themeKeys: ["animations", "animation"],
|
|
3576
3692
|
supportsArbitrary: true,
|
|
3577
3693
|
supportsCustomProperty: true,
|
|
3578
|
-
handle: (value, ctx, token) => {
|
|
3694
|
+
handle: (value, ctx, token, extra) => {
|
|
3695
|
+
if (extra?.realThemeValue) return [decl("animation", `var(--animate-${extra.realThemeValue})`)];
|
|
3579
3696
|
if (token.customProperty) {
|
|
3580
3697
|
return [decl("animation", `var(${value})`)];
|
|
3581
3698
|
}
|
|
@@ -4947,6 +5064,7 @@ staticUtility("sticky", [["position", "sticky"]], { category: "layout" });
|
|
|
4947
5064
|
staticUtility(`-${name}-px`, [[prop, "-1px"]], { category: "layout" });
|
|
4948
5065
|
functionalUtility({
|
|
4949
5066
|
name,
|
|
5067
|
+
spacingKeys: true,
|
|
4950
5068
|
prop,
|
|
4951
5069
|
supportsNegative: true,
|
|
4952
5070
|
supportsFraction: true,
|
|
@@ -4977,6 +5095,7 @@ staticUtility("invisible", [["visibility", "hidden"]], { category: "layout" });
|
|
|
4977
5095
|
staticUtility("collapse", [["visibility", "collapse"]], { category: "layout" });
|
|
4978
5096
|
functionalUtility({
|
|
4979
5097
|
name: "gap-x",
|
|
5098
|
+
spacingKeys: true,
|
|
4980
5099
|
prop: "column-gap",
|
|
4981
5100
|
supportsArbitrary: true,
|
|
4982
5101
|
// gap-x-[10vw]
|
|
@@ -4993,6 +5112,7 @@ functionalUtility({
|
|
|
4993
5112
|
});
|
|
4994
5113
|
functionalUtility({
|
|
4995
5114
|
name: "gap-y",
|
|
5115
|
+
spacingKeys: true,
|
|
4996
5116
|
prop: "row-gap",
|
|
4997
5117
|
supportsArbitrary: true,
|
|
4998
5118
|
// gap-y-[10vw]
|
|
@@ -5009,6 +5129,7 @@ functionalUtility({
|
|
|
5009
5129
|
});
|
|
5010
5130
|
functionalUtility({
|
|
5011
5131
|
name: "gap",
|
|
5132
|
+
spacingKeys: true,
|
|
5012
5133
|
prop: "gap",
|
|
5013
5134
|
supportsArbitrary: true,
|
|
5014
5135
|
// gap-[10vw]
|
|
@@ -5526,6 +5647,7 @@ functionalUtility({
|
|
|
5526
5647
|
].forEach(([name, prop]) => {
|
|
5527
5648
|
staticUtility(`${name}-px`, [[prop, "1px"]], { category: "spacing" });
|
|
5528
5649
|
functionalUtility({
|
|
5650
|
+
spacingKeys: true,
|
|
5529
5651
|
name,
|
|
5530
5652
|
prop,
|
|
5531
5653
|
supportsArbitrary: true,
|
|
@@ -5550,6 +5672,7 @@ functionalUtility({
|
|
|
5550
5672
|
staticUtility(`${name}-px`, [[prop, "1px"]], { category: "spacing" });
|
|
5551
5673
|
staticUtility(`-${name}-px`, [[prop, "-1px"]], { category: "spacing" });
|
|
5552
5674
|
functionalUtility({
|
|
5675
|
+
spacingKeys: true,
|
|
5553
5676
|
name,
|
|
5554
5677
|
prop,
|
|
5555
5678
|
supportsNegative: true,
|
|
@@ -5580,6 +5703,7 @@ const SPACE_SELECTOR = ":where(& > :not(:last-child))";
|
|
|
5580
5703
|
() => rule(SPACE_SELECTOR, [decl(rev, "1")])
|
|
5581
5704
|
], { category: "spacing" });
|
|
5582
5705
|
functionalUtility({
|
|
5706
|
+
spacingKeys: true,
|
|
5583
5707
|
name,
|
|
5584
5708
|
supportsNegative: true,
|
|
5585
5709
|
supportsArbitrary: true,
|
|
@@ -5629,6 +5753,7 @@ const SPACE_SELECTOR = ":where(& > :not(:last-child))";
|
|
|
5629
5753
|
staticUtility(name, [["width", value]]);
|
|
5630
5754
|
});
|
|
5631
5755
|
functionalUtility({
|
|
5756
|
+
spacingKeys: true,
|
|
5632
5757
|
name: "w",
|
|
5633
5758
|
prop: "width",
|
|
5634
5759
|
supportsArbitrary: true,
|
|
@@ -5661,6 +5786,7 @@ functionalUtility({
|
|
|
5661
5786
|
staticUtility(name, [["width", w], ["height", h]]);
|
|
5662
5787
|
});
|
|
5663
5788
|
functionalUtility({
|
|
5789
|
+
spacingKeys: true,
|
|
5664
5790
|
name: "size",
|
|
5665
5791
|
supportsArbitrary: true,
|
|
5666
5792
|
supportsCustomProperty: true,
|
|
@@ -5700,6 +5826,7 @@ functionalUtility({
|
|
|
5700
5826
|
staticUtility(name, [["height", value]]);
|
|
5701
5827
|
});
|
|
5702
5828
|
functionalUtility({
|
|
5829
|
+
spacingKeys: true,
|
|
5703
5830
|
name: "h",
|
|
5704
5831
|
prop: "height",
|
|
5705
5832
|
supportsArbitrary: true,
|
|
@@ -5730,6 +5857,7 @@ functionalUtility({
|
|
|
5730
5857
|
staticUtility(name, [["min-height", value]], { category: "sizing" });
|
|
5731
5858
|
});
|
|
5732
5859
|
functionalUtility({
|
|
5860
|
+
spacingKeys: true,
|
|
5733
5861
|
name: "min-h",
|
|
5734
5862
|
prop: "min-height",
|
|
5735
5863
|
supportsArbitrary: true,
|
|
@@ -5760,6 +5888,7 @@ functionalUtility({
|
|
|
5760
5888
|
staticUtility(name, [["max-height", value]], { category: "sizing" });
|
|
5761
5889
|
});
|
|
5762
5890
|
functionalUtility({
|
|
5891
|
+
spacingKeys: true,
|
|
5763
5892
|
name: "max-h",
|
|
5764
5893
|
prop: "max-height",
|
|
5765
5894
|
supportsArbitrary: true,
|
|
@@ -5806,6 +5935,7 @@ functionalUtility({
|
|
|
5806
5935
|
staticUtility(name, [["min-width", value]], { category: "sizing" });
|
|
5807
5936
|
});
|
|
5808
5937
|
functionalUtility({
|
|
5938
|
+
spacingKeys: true,
|
|
5809
5939
|
name: "min-w",
|
|
5810
5940
|
prop: "min-width",
|
|
5811
5941
|
supportsArbitrary: true,
|
|
@@ -5841,6 +5971,7 @@ functionalUtility({
|
|
|
5841
5971
|
staticUtility(name, [["max-width", value]], { category: "sizing" });
|
|
5842
5972
|
});
|
|
5843
5973
|
functionalUtility({
|
|
5974
|
+
spacingKeys: true,
|
|
5844
5975
|
name: "max-w",
|
|
5845
5976
|
prop: "max-width",
|
|
5846
5977
|
supportsArbitrary: true,
|
|
@@ -8264,6 +8395,51 @@ functionalModifier(
|
|
|
8264
8395
|
},
|
|
8265
8396
|
void 0
|
|
8266
8397
|
);
|
|
8398
|
+
const LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
|
|
8399
|
+
const LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
|
|
8400
|
+
const MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
|
|
8401
|
+
const MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
|
|
8402
|
+
function toPx(n, unit) {
|
|
8403
|
+
const v = parseFloat(n);
|
|
8404
|
+
return unit === "rem" || unit === "em" ? v * 16 : v;
|
|
8405
|
+
}
|
|
8406
|
+
function preludeKey(kind, prelude) {
|
|
8407
|
+
const container = kind === "container";
|
|
8408
|
+
const min = MIN_W.exec(prelude);
|
|
8409
|
+
if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
|
|
8410
|
+
const max = MAX_W.exec(prelude);
|
|
8411
|
+
if (max) return [container ? 3 : 1, -toPx(max[1], max[2])];
|
|
8412
|
+
if (!container && LATE_MEDIA.test(prelude)) return [5, 0];
|
|
8413
|
+
return [0, 0];
|
|
8414
|
+
}
|
|
8415
|
+
function ruleSortKey(rule2) {
|
|
8416
|
+
const key = [];
|
|
8417
|
+
let rest = rule2;
|
|
8418
|
+
let m;
|
|
8419
|
+
while (m = LEADING_AT.exec(rest)) {
|
|
8420
|
+
const [g, v] = preludeKey(m[1], m[2]);
|
|
8421
|
+
key.push(g, v);
|
|
8422
|
+
rest = rest.slice(m[0].length);
|
|
8423
|
+
}
|
|
8424
|
+
return key;
|
|
8425
|
+
}
|
|
8426
|
+
function compareKeys(a, b) {
|
|
8427
|
+
const n = Math.min(a.length, b.length);
|
|
8428
|
+
for (let i = 0; i < n; i++) {
|
|
8429
|
+
if (a[i] !== b[i]) return a[i] - b[i];
|
|
8430
|
+
}
|
|
8431
|
+
return a.length - b.length;
|
|
8432
|
+
}
|
|
8433
|
+
function upperBound(keys, key) {
|
|
8434
|
+
let lo = 0;
|
|
8435
|
+
let hi = keys.length;
|
|
8436
|
+
while (lo < hi) {
|
|
8437
|
+
const mid = lo + hi >> 1;
|
|
8438
|
+
if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
|
|
8439
|
+
else hi = mid;
|
|
8440
|
+
}
|
|
8441
|
+
return lo;
|
|
8442
|
+
}
|
|
8267
8443
|
export {
|
|
8268
8444
|
AstCache,
|
|
8269
8445
|
IncrementalParser,
|
|
@@ -8279,6 +8455,7 @@ export {
|
|
|
8279
8455
|
clearAstCache,
|
|
8280
8456
|
collectDeclPaths,
|
|
8281
8457
|
comment,
|
|
8458
|
+
compareKeys,
|
|
8282
8459
|
configGetter,
|
|
8283
8460
|
createContext,
|
|
8284
8461
|
decl,
|
|
@@ -8296,6 +8473,7 @@ export {
|
|
|
8296
8473
|
getModifier,
|
|
8297
8474
|
getPreflightCSS,
|
|
8298
8475
|
getUtility,
|
|
8476
|
+
hasCommentDelimiter,
|
|
8299
8477
|
hasCommentToken,
|
|
8300
8478
|
hasPreset,
|
|
8301
8479
|
isDebug,
|
|
@@ -8317,6 +8495,7 @@ export {
|
|
|
8317
8495
|
resolveTheme,
|
|
8318
8496
|
rootToCss,
|
|
8319
8497
|
rule,
|
|
8498
|
+
ruleSortKey,
|
|
8320
8499
|
setContextCacheReset,
|
|
8321
8500
|
setDebug,
|
|
8322
8501
|
staticModifier,
|
|
@@ -8325,6 +8504,7 @@ export {
|
|
|
8325
8504
|
themeGetter,
|
|
8326
8505
|
themeToCssVars,
|
|
8327
8506
|
tokenize,
|
|
8507
|
+
upperBound,
|
|
8328
8508
|
utilityCache
|
|
8329
8509
|
};
|
|
8330
8510
|
//# sourceMappingURL=index.js.map
|