rainbowindex 0.6.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/CHANGELOG.md +543 -0
- package/LICENSE +16 -17
- package/NOTICE.md +106 -0
- package/README.md +219 -65
- package/dist/browser.d.ts +4 -2
- package/dist/browser.mjs +12 -4
- package/dist/chunk-2T7V5XLK.mjs +912 -0
- package/dist/chunk-6OORICWF.mjs +16 -0
- package/dist/{chunk-KSNYSR3C.mjs → chunk-FJOZJIKB.mjs} +2499 -329
- package/dist/chunk-L56IRO7A.mjs +491 -0
- package/dist/chunk-PZDVDEZJ.mjs +196 -0
- package/dist/{chunk-3LWJTLOJ.mjs → chunk-RC6DDE4L.mjs} +23 -15
- package/dist/chunk-TQJYVQPE.mjs +217 -0
- package/dist/chunk-W756NVYI.mjs +33 -0
- package/dist/chunk-WBESS2ZD.mjs +598 -0
- package/dist/{chunk-3HRMFZGE.mjs → chunk-X66Z2YHT.mjs} +2 -1
- package/dist/{chunk-6U4IOFOS.mjs → chunk-XQGSG2HK.mjs} +199 -555
- package/dist/cli.mjs +1077 -123
- package/dist/{index-DSgpB6bS.d.ts → context-DcBtnnan.d.ts} +47 -103
- package/dist/editor.d.ts +71 -433
- package/dist/editor.mjs +51 -368
- package/dist/eslint.d.ts +16 -0
- package/dist/eslint.mjs +32 -0
- package/dist/{index-4Kyaq3IZ.d.ts → imports-C9esHd5Q.d.ts} +78 -84
- package/dist/index-CNqdL5U0.d.ts +56 -0
- package/dist/index-Czx-EUwh.d.ts +138 -0
- package/dist/index-DW8YSxTz.d.ts +104 -0
- package/dist/index.d.ts +46 -5
- package/dist/index.mjs +33 -9
- package/dist/oxlint.d.ts +21 -3
- package/dist/oxlint.mjs +19 -1
- package/dist/recipe.d.ts +111 -0
- package/dist/recipe.mjs +71 -0
- package/dist/safelist-CH3_PywB.d.ts +43 -0
- package/dist/session-CMaskdB7.d.ts +543 -0
- package/dist/tailwind.css +644 -0
- package/dist/theme-CIZiGlce.d.ts +115 -0
- package/dist/vite.d.ts +10 -1
- package/dist/vite.mjs +266 -118
- package/package.json +27 -5
- package/dist/chunk-WK6S4HTC.mjs +0 -1921
- package/dist/chunk-ZR7XJMUN.mjs +0 -251
- package/dist/safelist-CGCtF-Fr.d.ts +0 -96
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
-
BORDER_DIR_PROPS,
|
|
3
|
-
BUILTIN_STATIC_KEYS,
|
|
4
|
-
COLOR_FUNCTION_ALTERNATION,
|
|
5
2
|
CORNER_SHAPE_KEYWORDS,
|
|
6
3
|
DEFAULT_COLORS,
|
|
7
4
|
DEFAULT_CORNER_SCALE,
|
|
8
5
|
DEFAULT_DARK_CONFIG,
|
|
9
6
|
DEFAULT_SUPERELLIPSE_SCALE,
|
|
7
|
+
checkPaletteContrast,
|
|
8
|
+
generateAllColorVariables,
|
|
9
|
+
generateThemeOverrides,
|
|
10
|
+
isValidColorSuffix
|
|
11
|
+
} from "./chunk-L56IRO7A.mjs";
|
|
12
|
+
import {
|
|
13
|
+
BACKDROP_FILTER_COMPOSED,
|
|
14
|
+
BORDER_DIR_PROPS,
|
|
15
|
+
BUILTIN_STATIC_KEYS,
|
|
16
|
+
COLOR_FUNCTION_ALTERNATION,
|
|
17
|
+
FILTER_COMPOSED,
|
|
10
18
|
GAP_MAP,
|
|
11
19
|
INSET_MAP,
|
|
12
20
|
IS_DEV,
|
|
@@ -23,13 +31,12 @@ import {
|
|
|
23
31
|
devWarn,
|
|
24
32
|
isFontFamilyValue,
|
|
25
33
|
isMaskRadialSizeValue,
|
|
26
|
-
isValidColorSuffix,
|
|
27
34
|
registerColorNames,
|
|
28
35
|
registerCustomFontFamilies,
|
|
29
36
|
registerCustomTextSizes,
|
|
30
37
|
registerCustomUtility,
|
|
31
38
|
snapshotCompilationContext
|
|
32
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-XQGSG2HK.mjs";
|
|
33
40
|
|
|
34
41
|
// src/shared.ts
|
|
35
42
|
function isRIDebug() {
|
|
@@ -130,6 +137,7 @@ var PARSER_ONLY_STATICS = [
|
|
|
130
137
|
"h-max",
|
|
131
138
|
"h-fit",
|
|
132
139
|
"min-w-0",
|
|
140
|
+
"min-w-auto",
|
|
133
141
|
"min-w-full",
|
|
134
142
|
"min-w-min",
|
|
135
143
|
"min-w-max",
|
|
@@ -141,6 +149,7 @@ var PARSER_ONLY_STATICS = [
|
|
|
141
149
|
"max-w-fit",
|
|
142
150
|
"max-w-prose",
|
|
143
151
|
"min-h-0",
|
|
152
|
+
"min-h-auto",
|
|
144
153
|
"min-h-full",
|
|
145
154
|
"min-h-screen",
|
|
146
155
|
"min-h-min",
|
|
@@ -508,18 +517,16 @@ function findVariantColon(input) {
|
|
|
508
517
|
for (let i = 0; i < input.length; i++) {
|
|
509
518
|
const ch = input[i];
|
|
510
519
|
if (ch === "\\" && i + 1 < input.length) {
|
|
511
|
-
|
|
512
|
-
if (isHexDigit(next)) {
|
|
513
|
-
let hexLen = 0;
|
|
514
|
-
while (hexLen < 6 && i + 1 + hexLen < input.length && isHexDigit(input[i + 1 + hexLen]))
|
|
515
|
-
hexLen++;
|
|
516
|
-
i += hexLen;
|
|
517
|
-
if (i + 1 < input.length && /\s/.test(input[i + 1])) i++;
|
|
518
|
-
} else {
|
|
519
|
-
i++;
|
|
520
|
-
}
|
|
520
|
+
i = endOfEscape(input, i);
|
|
521
521
|
continue;
|
|
522
522
|
}
|
|
523
|
+
if (depth > 0 && (ch === "'" || ch === '"')) {
|
|
524
|
+
const close = endOfQuoted(input, i);
|
|
525
|
+
if (close !== -1) {
|
|
526
|
+
i = close;
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
523
530
|
if (ch === "[" || ch === "(") depth++;
|
|
524
531
|
else if (ch === "]" || ch === ")") depth--;
|
|
525
532
|
else if (ch === ":" && depth === 0) {
|
|
@@ -530,17 +537,74 @@ function findVariantColon(input) {
|
|
|
530
537
|
}
|
|
531
538
|
return -1;
|
|
532
539
|
}
|
|
540
|
+
function endOfEscape(s, i) {
|
|
541
|
+
if (i + 1 >= s.length) return i;
|
|
542
|
+
if (!isHexDigit(s[i + 1])) return i + 1;
|
|
543
|
+
let hexLen = 0;
|
|
544
|
+
while (hexLen < 6 && i + 1 + hexLen < s.length && isHexDigit(s[i + 1 + hexLen])) hexLen++;
|
|
545
|
+
let end = i + hexLen;
|
|
546
|
+
if (end + 1 < s.length && /\s/.test(s[end + 1])) end++;
|
|
547
|
+
return end;
|
|
548
|
+
}
|
|
549
|
+
function endOfQuoted(s, i) {
|
|
550
|
+
const quote = s[i];
|
|
551
|
+
for (let j = i + 1; j < s.length; j++) {
|
|
552
|
+
if (s[j] === "\\" && j + 1 < s.length) {
|
|
553
|
+
j++;
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
if (s[j] === quote) return j;
|
|
557
|
+
}
|
|
558
|
+
return -1;
|
|
559
|
+
}
|
|
560
|
+
function findVariantBracketEnd(s, start) {
|
|
561
|
+
let depth = 0;
|
|
562
|
+
for (let i = start; i < s.length; i++) {
|
|
563
|
+
const ch = s[i];
|
|
564
|
+
if (ch === "\\") {
|
|
565
|
+
i = endOfEscape(s, i);
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
if (ch === "'" || ch === '"') {
|
|
569
|
+
const close = endOfQuoted(s, i);
|
|
570
|
+
if (close !== -1) i = close;
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
573
|
+
if (ch === "[") depth++;
|
|
574
|
+
else if (ch === "]") {
|
|
575
|
+
depth--;
|
|
576
|
+
if (depth === 0) return i;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return -1;
|
|
580
|
+
}
|
|
533
581
|
function isHexDigit(ch) {
|
|
534
582
|
const c = ch.charCodeAt(0);
|
|
535
583
|
return c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102;
|
|
536
584
|
}
|
|
537
|
-
var
|
|
585
|
+
var VARIANT_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
586
|
+
var VARIANT_MODIFIER_RE = /^\/[a-zA-Z0-9_-]+$/;
|
|
538
587
|
function isVariantPrefix(s) {
|
|
539
588
|
if (!s) return false;
|
|
540
589
|
if (s.startsWith("[") && s.endsWith("]")) return true;
|
|
541
590
|
if (s.startsWith("@")) return true;
|
|
542
591
|
if (s === "*" || s === "**") return true;
|
|
543
|
-
|
|
592
|
+
let name = s;
|
|
593
|
+
let tail = "";
|
|
594
|
+
const bracketStart = s.indexOf("[");
|
|
595
|
+
if (bracketStart !== -1) {
|
|
596
|
+
const bracketEnd = findVariantBracketEnd(s, bracketStart);
|
|
597
|
+
if (bracketEnd === -1) return false;
|
|
598
|
+
name = s.slice(0, bracketStart);
|
|
599
|
+
tail = s.slice(bracketEnd + 1);
|
|
600
|
+
} else {
|
|
601
|
+
const slash = s.indexOf("/");
|
|
602
|
+
if (slash !== -1) {
|
|
603
|
+
name = s.slice(0, slash);
|
|
604
|
+
tail = s.slice(slash);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return VARIANT_NAME_RE.test(name) && (tail === "" || VARIANT_MODIFIER_RE.test(tail));
|
|
544
608
|
}
|
|
545
609
|
function findMatchingBracket(input, start) {
|
|
546
610
|
let depth = 0;
|
|
@@ -682,6 +746,53 @@ function diagnosticFromWarning(message, span) {
|
|
|
682
746
|
};
|
|
683
747
|
}
|
|
684
748
|
|
|
749
|
+
// src/css/escape.ts
|
|
750
|
+
function escapeSelector(raw) {
|
|
751
|
+
let out = null;
|
|
752
|
+
let runStart = 0;
|
|
753
|
+
for (let i = 0; i < raw.length; i++) {
|
|
754
|
+
const code = raw.charCodeAt(i);
|
|
755
|
+
if (code >= 97 && code <= 122 || // a-z
|
|
756
|
+
code >= 65 && code <= 90 || // A-Z
|
|
757
|
+
code === 45 || // -
|
|
758
|
+
code === 95 || // _
|
|
759
|
+
code >= 128) {
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
if (code >= 48 && code <= 57 && // 0-9
|
|
763
|
+
i !== 0 && !(i === 1 && raw.charCodeAt(0) === 45)) {
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
let escaped;
|
|
767
|
+
if (code === 0) {
|
|
768
|
+
escaped = "\uFFFD";
|
|
769
|
+
} else if (code >= 48 && code <= 57) {
|
|
770
|
+
escaped = `\\${code.toString(16)} `;
|
|
771
|
+
} else if (code === 9 || code === 10 || code === 12 || code === 13) {
|
|
772
|
+
escaped = `\\${raw[i]}`;
|
|
773
|
+
} else if (code < 32 || code === 127) {
|
|
774
|
+
escaped = `\\${code.toString(16)} `;
|
|
775
|
+
} else {
|
|
776
|
+
escaped = `\\${raw[i]}`;
|
|
777
|
+
}
|
|
778
|
+
if (out === null) out = [];
|
|
779
|
+
out.push(raw.slice(runStart, i), escaped);
|
|
780
|
+
runStart = i + 1;
|
|
781
|
+
}
|
|
782
|
+
if (out === null) return raw;
|
|
783
|
+
out.push(raw.slice(runStart));
|
|
784
|
+
return out.join("");
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// src/utilities/markers.ts
|
|
788
|
+
var RELATIONAL_NAME_RE = /^[a-zA-Z0-9_-]+$/;
|
|
789
|
+
var MARKER_ROOTS = /* @__PURE__ */ new Set(["group", "peer"]);
|
|
790
|
+
function isMarkerUtility(utility) {
|
|
791
|
+
const slash = utility.indexOf("/");
|
|
792
|
+
if (slash === -1) return MARKER_ROOTS.has(utility);
|
|
793
|
+
return MARKER_ROOTS.has(utility.slice(0, slash)) && RELATIONAL_NAME_RE.test(utility.slice(slash + 1));
|
|
794
|
+
}
|
|
795
|
+
|
|
685
796
|
// src/engine/variants.ts
|
|
686
797
|
var MAX_CUSTOM_VARIANT_SELECTOR_LENGTH = 500;
|
|
687
798
|
var SAFE_CSS_LENGTH_RE = /^\d+(\.\d+)?(px|em|rem|ch|vw|vh|svw|svh|dvw|dvh|cqw|cqh)$/;
|
|
@@ -814,10 +925,49 @@ function sanitizeVariantBracket(inner) {
|
|
|
814
925
|
return cleaned;
|
|
815
926
|
}
|
|
816
927
|
var SAFE_AT_RULE_RE = /^@(?:media|supports|container|layer)\b/;
|
|
817
|
-
function
|
|
928
|
+
function splitRelationalName(rest, kind) {
|
|
929
|
+
let depth = 0;
|
|
930
|
+
for (let i = rest.length - 1; i >= 0; i--) {
|
|
931
|
+
const ch = rest[i];
|
|
932
|
+
if (ch === "]" || ch === ")") depth++;
|
|
933
|
+
else if (ch === "[" || ch === "(") depth--;
|
|
934
|
+
else if (ch === "/" && depth === 0) {
|
|
935
|
+
const name = rest.slice(i + 1);
|
|
936
|
+
if (!RELATIONAL_NAME_RE.test(name)) return { state: rest, anchor: null };
|
|
937
|
+
return { state: rest.slice(0, i), anchor: `.${escapeSelector(`${kind}/${name}`)}` };
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
return { state: rest, anchor: `.${kind}` };
|
|
941
|
+
}
|
|
942
|
+
function breakpointValue(name, theme) {
|
|
943
|
+
if (!Object.hasOwn(theme.breakpoints, name)) return null;
|
|
944
|
+
const value = theme.breakpoints[name];
|
|
945
|
+
return SAFE_CSS_LENGTH_RE.test(value) ? value : null;
|
|
946
|
+
}
|
|
947
|
+
function widthBound(rest, theme) {
|
|
948
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
949
|
+
const v = rest.slice(1, -1);
|
|
950
|
+
return SAFE_CSS_LENGTH_RE.test(v) ? v : null;
|
|
951
|
+
}
|
|
952
|
+
return breakpointValue(rest, theme);
|
|
953
|
+
}
|
|
954
|
+
var MAX_VARIANT_NESTING = 6;
|
|
955
|
+
function plainSelectorOf(w) {
|
|
956
|
+
if (!w?.selectorSuffix) return null;
|
|
957
|
+
if (w.replaceAmpersand || w.atRule || w.startingStyle || w.alternate) return null;
|
|
958
|
+
return w.selectorSuffix;
|
|
959
|
+
}
|
|
960
|
+
function resolveRelationalVariant(inner, anchor, combinator, resolveInner) {
|
|
818
961
|
if (inner.startsWith("[") && inner.endsWith("]")) {
|
|
819
962
|
const sel = sanitizeVariantBracket(inner.slice(1, -1));
|
|
820
|
-
|
|
963
|
+
if (!sel) return null;
|
|
964
|
+
if (sel.includes("&")) {
|
|
965
|
+
return {
|
|
966
|
+
selectorSuffix: `${sel.replaceAll("&", anchor)}${combinator}`,
|
|
967
|
+
replaceAmpersand: true
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
return { selectorSuffix: `${anchor}:is(${sel})${combinator}`, replaceAmpersand: true };
|
|
821
971
|
}
|
|
822
972
|
if (Object.hasOwn(PSEUDO_CLASSES, inner)) {
|
|
823
973
|
return {
|
|
@@ -825,6 +975,10 @@ function resolveRelationalVariant(inner, anchor, combinator) {
|
|
|
825
975
|
replaceAmpersand: true
|
|
826
976
|
};
|
|
827
977
|
}
|
|
978
|
+
const nested = plainSelectorOf(resolveInner(inner));
|
|
979
|
+
if (nested !== null) {
|
|
980
|
+
return { selectorSuffix: `${anchor}${nested}${combinator}`, replaceAmpersand: true };
|
|
981
|
+
}
|
|
828
982
|
return void 0;
|
|
829
983
|
}
|
|
830
984
|
var ATTR_NAME_RE = /^[a-z][a-z0-9-]*$/i;
|
|
@@ -905,6 +1059,26 @@ function listVariants(theme) {
|
|
|
905
1059
|
out.push(...VARIANT_PATTERNS);
|
|
906
1060
|
return out;
|
|
907
1061
|
}
|
|
1062
|
+
function appearanceVariant(variant, strategy) {
|
|
1063
|
+
const media = MEDIA_VARIANTS[variant].wrapper;
|
|
1064
|
+
if (strategy.kind === "media") return media;
|
|
1065
|
+
if (strategy.kind === "selector") {
|
|
1066
|
+
const sel = strategy.selector;
|
|
1067
|
+
return Object.freeze(
|
|
1068
|
+
variant === "dark" ? { selectorSuffix: `:where(${sel}, ${sel} *) &`, replaceAmpersand: true } : { selectorSuffix: `:where(:not(${sel}, ${sel} *)) &`, replaceAmpersand: true }
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
const overridden = variant === "dark" ? "light" : "dark";
|
|
1072
|
+
return Object.freeze({
|
|
1073
|
+
selectorSuffix: `:where(html[data-appearance="${variant}"]) &`,
|
|
1074
|
+
replaceAmpersand: true,
|
|
1075
|
+
alternate: Object.freeze({
|
|
1076
|
+
selectorSuffix: `:where(html:not([data-appearance="${overridden}"])) &`,
|
|
1077
|
+
replaceAmpersand: true,
|
|
1078
|
+
atRule: media.atRule
|
|
1079
|
+
})
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
908
1082
|
function resolveVariant(variant, theme, customVariantMap, memo) {
|
|
909
1083
|
if (!memo) return resolveVariantUncached(variant, theme, customVariantMap);
|
|
910
1084
|
const cached = memo.get(variant);
|
|
@@ -913,72 +1087,91 @@ function resolveVariant(variant, theme, customVariantMap, memo) {
|
|
|
913
1087
|
memo.set(variant, wrapper);
|
|
914
1088
|
return wrapper;
|
|
915
1089
|
}
|
|
916
|
-
function resolveVariantUncached(variant, theme, customVariantMap) {
|
|
1090
|
+
function resolveVariantUncached(variant, theme, customVariantMap, depth = 0) {
|
|
1091
|
+
const inner = (v) => depth >= MAX_VARIANT_NESTING ? null : resolveVariantUncached(v, theme, customVariantMap, depth + 1);
|
|
917
1092
|
if (variant.startsWith("[") && variant.endsWith("]")) {
|
|
918
1093
|
return resolveArbitraryVariant(variant);
|
|
919
1094
|
}
|
|
920
|
-
|
|
921
|
-
const bp = theme
|
|
922
|
-
if (
|
|
923
|
-
return { atRule: `@media (min-width: ${bp})` };
|
|
1095
|
+
{
|
|
1096
|
+
const bp = breakpointValue(variant, theme);
|
|
1097
|
+
if (bp !== null) return { atRule: `@media (min-width: ${bp})` };
|
|
924
1098
|
}
|
|
925
|
-
if (variant.startsWith("min-
|
|
926
|
-
const v = variant.slice(
|
|
927
|
-
|
|
1099
|
+
if (variant.startsWith("min-")) {
|
|
1100
|
+
const v = widthBound(variant.slice(4), theme);
|
|
1101
|
+
if (v !== null) return { atRule: `@media (width >= ${v})` };
|
|
928
1102
|
}
|
|
929
|
-
if (variant.startsWith("max-
|
|
930
|
-
const v = variant.slice(
|
|
931
|
-
|
|
1103
|
+
if (variant.startsWith("max-")) {
|
|
1104
|
+
const v = widthBound(variant.slice(4), theme);
|
|
1105
|
+
if (v !== null) return { atRule: `@media (width < ${v})` };
|
|
932
1106
|
}
|
|
933
1107
|
if (variant.startsWith("@")) {
|
|
934
1108
|
const rest = variant.slice(1);
|
|
935
1109
|
const slashIdx = rest.indexOf("/");
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1110
|
+
const named = slashIdx !== -1 && CSS_CUSTOM_IDENT_RE.test(rest.slice(0, slashIdx));
|
|
1111
|
+
if (slashIdx === -1 || named) {
|
|
1112
|
+
const scope = named ? `${rest.slice(0, slashIdx)} ` : "";
|
|
1113
|
+
const size = slashIdx === -1 ? rest : rest.slice(slashIdx + 1);
|
|
1114
|
+
const bp = breakpointValue(size, theme);
|
|
1115
|
+
if (bp !== null) return { atRule: `@container ${scope}(min-width: ${bp})` };
|
|
1116
|
+
if (size.startsWith("min-")) {
|
|
1117
|
+
const v = breakpointValue(size.slice(4), theme);
|
|
1118
|
+
if (v !== null) return { atRule: `@container ${scope}(width >= ${v})` };
|
|
1119
|
+
}
|
|
1120
|
+
if (size.startsWith("max-")) {
|
|
1121
|
+
const v = breakpointValue(size.slice(4), theme);
|
|
1122
|
+
if (v !== null) return { atRule: `@container ${scope}(width < ${v})` };
|
|
943
1123
|
}
|
|
944
|
-
}
|
|
945
|
-
if (Object.hasOwn(theme.breakpoints, rest)) {
|
|
946
|
-
const bpVal = theme.breakpoints[rest];
|
|
947
|
-
if (!SAFE_CSS_LENGTH_RE.test(bpVal)) return null;
|
|
948
|
-
return { atRule: `@container (min-width: ${bpVal})` };
|
|
949
1124
|
}
|
|
950
1125
|
}
|
|
951
1126
|
if (Object.hasOwn(PSEUDO_CLASS_WRAPPERS, variant)) {
|
|
952
1127
|
return PSEUDO_CLASS_WRAPPERS[variant];
|
|
953
1128
|
}
|
|
954
1129
|
if (variant.startsWith("group-")) {
|
|
955
|
-
const
|
|
1130
|
+
const { state, anchor } = splitRelationalName(variant.slice(6), "group");
|
|
1131
|
+
if (anchor === null) return null;
|
|
1132
|
+
const r = resolveRelationalVariant(state, anchor, " &", inner);
|
|
956
1133
|
if (r !== void 0) return r;
|
|
957
1134
|
}
|
|
958
1135
|
if (variant.startsWith("peer-")) {
|
|
959
|
-
const
|
|
1136
|
+
const { state, anchor } = splitRelationalName(variant.slice(5), "peer");
|
|
1137
|
+
if (anchor === null) return null;
|
|
1138
|
+
const r = resolveRelationalVariant(state, anchor, " ~ &", inner);
|
|
960
1139
|
if (r !== void 0) return r;
|
|
961
1140
|
}
|
|
962
1141
|
if (variant.startsWith("in-[") && variant.endsWith("]")) {
|
|
963
1142
|
const sel = sanitizeVariantBracket(variant.slice(4, -1));
|
|
964
|
-
return sel ? { selectorSuffix: `:where(${sel}) &`, replaceAmpersand: true } : null;
|
|
1143
|
+
return sel && !sel.includes("&") ? { selectorSuffix: `:where(${sel}) &`, replaceAmpersand: true } : null;
|
|
1144
|
+
}
|
|
1145
|
+
if (variant.startsWith("in-")) {
|
|
1146
|
+
const nested = plainSelectorOf(inner(variant.slice(3)));
|
|
1147
|
+
if (nested !== null) {
|
|
1148
|
+
return { selectorSuffix: `:where(*${nested}) &`, replaceAmpersand: true };
|
|
1149
|
+
}
|
|
965
1150
|
}
|
|
966
1151
|
if (Object.hasOwn(PSEUDO_ELEMENT_WRAPPERS, variant)) {
|
|
967
1152
|
return PSEUDO_ELEMENT_WRAPPERS[variant];
|
|
968
1153
|
}
|
|
1154
|
+
if (variant === "dark" || variant === "light") {
|
|
1155
|
+
return appearanceVariant(variant, theme.darkConfig.variant);
|
|
1156
|
+
}
|
|
969
1157
|
if (Object.hasOwn(MEDIA_VARIANTS, variant)) return MEDIA_VARIANTS[variant].wrapper;
|
|
970
1158
|
if (Object.hasOwn(SPECIAL_SELECTORS, variant)) return SPECIAL_SELECTORS[variant].wrapper;
|
|
971
1159
|
if (variant.startsWith("supports-[") && variant.endsWith("]")) {
|
|
972
|
-
const
|
|
973
|
-
if (!
|
|
1160
|
+
const inner2 = decodeArbitraryValue(variant.slice(10, -1));
|
|
1161
|
+
if (!inner2 || inner2.length > MAX_CUSTOM_VARIANT_SELECTOR_LENGTH || /[{}]/.test(inner2))
|
|
974
1162
|
return null;
|
|
975
|
-
return { atRule: `@supports ${
|
|
1163
|
+
return { atRule: `@supports ${inner2.startsWith("(") ? inner2 : `(${inner2})`}` };
|
|
976
1164
|
}
|
|
977
1165
|
for (const [prefix, fn] of NTH_VARIANTS) {
|
|
978
1166
|
if (variant.startsWith(prefix) && variant.endsWith("]")) {
|
|
979
1167
|
const arg = variant.slice(prefix.length, -1).trim();
|
|
980
1168
|
return /^(odd|even|[-+\dn\s]+)$/i.test(arg) ? { selectorSuffix: `:${fn}(${arg})` } : null;
|
|
981
1169
|
}
|
|
1170
|
+
const bare = prefix.slice(0, -1);
|
|
1171
|
+
if (variant.startsWith(bare)) {
|
|
1172
|
+
const arg = variant.slice(bare.length);
|
|
1173
|
+
if (/^\d+$/.test(arg)) return { selectorSuffix: `:${fn}(${arg})` };
|
|
1174
|
+
}
|
|
982
1175
|
}
|
|
983
1176
|
if (variant.startsWith("data-")) {
|
|
984
1177
|
const r = resolveAttributeVariant(variant, "data", "");
|
|
@@ -989,17 +1182,34 @@ function resolveVariantUncached(variant, theme, customVariantMap) {
|
|
|
989
1182
|
if (r !== void 0) return r;
|
|
990
1183
|
}
|
|
991
1184
|
if (variant.startsWith("has-[") && variant.endsWith("]")) {
|
|
992
|
-
const
|
|
993
|
-
if (
|
|
1185
|
+
const sel = sanitizeVariantBracket(variant.slice(5, -1));
|
|
1186
|
+
if (sel && !sel.includes("&")) return { selectorSuffix: `:has(${sel})` };
|
|
1187
|
+
}
|
|
1188
|
+
if (variant.startsWith("has-")) {
|
|
1189
|
+
const nested = plainSelectorOf(inner(variant.slice(4)));
|
|
1190
|
+
if (nested !== null) return { selectorSuffix: `:has(${nested})` };
|
|
994
1191
|
}
|
|
995
1192
|
if (variant.startsWith("not-")) {
|
|
996
|
-
const
|
|
997
|
-
if (
|
|
998
|
-
const sel = sanitizeVariantBracket(
|
|
999
|
-
if (sel) return { selectorSuffix: `:not(${sel})` };
|
|
1000
|
-
}
|
|
1001
|
-
if (Object.hasOwn(PSEUDO_CLASSES,
|
|
1002
|
-
return { selectorSuffix: `:not(${PSEUDO_CLASSES[
|
|
1193
|
+
const rest = variant.slice(4);
|
|
1194
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
1195
|
+
const sel = sanitizeVariantBracket(rest.slice(1, -1));
|
|
1196
|
+
if (sel && !sel.includes("&")) return { selectorSuffix: `:not(${sel})` };
|
|
1197
|
+
}
|
|
1198
|
+
if (Object.hasOwn(PSEUDO_CLASSES, rest)) {
|
|
1199
|
+
return { selectorSuffix: `:not(${PSEUDO_CLASSES[rest].suffix})` };
|
|
1200
|
+
}
|
|
1201
|
+
const nestedWrapper = inner(rest);
|
|
1202
|
+
const nested = plainSelectorOf(nestedWrapper);
|
|
1203
|
+
if (nested !== null) return { selectorSuffix: `:not(${nested})` };
|
|
1204
|
+
const atRule = nestedWrapper?.atRule;
|
|
1205
|
+
if (atRule && !nestedWrapper.selectorSuffix && !nestedWrapper.alternate) {
|
|
1206
|
+
const spaceIdx = atRule.indexOf(" ");
|
|
1207
|
+
if (spaceIdx !== -1) {
|
|
1208
|
+
const name = atRule.slice(0, spaceIdx);
|
|
1209
|
+
if (name === "@media" || name === "@supports") {
|
|
1210
|
+
return { atRule: `${name} not ${atRule.slice(spaceIdx + 1)}` };
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1003
1213
|
}
|
|
1004
1214
|
}
|
|
1005
1215
|
const cv = customVariantMap?.get(variant);
|
|
@@ -1038,24 +1248,31 @@ function splitSelectorList(selector) {
|
|
|
1038
1248
|
results.push(selector.slice(start).trim());
|
|
1039
1249
|
return results.filter(Boolean);
|
|
1040
1250
|
}
|
|
1251
|
+
var MEDIA_WORLD = 1;
|
|
1252
|
+
function applyOneWrapper(applied, w) {
|
|
1253
|
+
let selector = applied.selector;
|
|
1254
|
+
if (w.selectorSuffix) {
|
|
1255
|
+
const branches = splitSelectorList(selector);
|
|
1256
|
+
const suffix = w.selectorSuffix;
|
|
1257
|
+
selector = w.replaceAmpersand ? branches.map((b) => suffix.replace(/&/g, b)).join(", ") : branches.map((b) => b + suffix).join(", ");
|
|
1258
|
+
}
|
|
1259
|
+
return {
|
|
1260
|
+
selector,
|
|
1261
|
+
atRules: w.atRule ? [...applied.atRules, w.atRule] : applied.atRules,
|
|
1262
|
+
startingStyle: applied.startingStyle || w.startingStyle === true
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1041
1265
|
function applyVariantWrappers(baseSelector, wrappers) {
|
|
1042
|
-
|
|
1043
|
-
const
|
|
1044
|
-
let
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
const suffix = w.selectorSuffix;
|
|
1049
|
-
selector = w.replaceAmpersand ? branches.map((b) => suffix.replace(/&/g, b)).join(", ") : branches.map((b) => b + suffix).join(", ");
|
|
1050
|
-
}
|
|
1051
|
-
if (w.atRule) {
|
|
1052
|
-
atRules.push(w.atRule);
|
|
1053
|
-
}
|
|
1054
|
-
if (w.startingStyle) {
|
|
1055
|
-
startingStyle = true;
|
|
1266
|
+
const worlds = wrappers.some((w) => w.alternate) ? 2 : 1;
|
|
1267
|
+
const out = [];
|
|
1268
|
+
for (let world = 0; world < worlds; world++) {
|
|
1269
|
+
let branch = { selector: baseSelector, atRules: [], startingStyle: false };
|
|
1270
|
+
for (const w of wrappers) {
|
|
1271
|
+
branch = applyOneWrapper(branch, world === MEDIA_WORLD ? w.alternate ?? w : w);
|
|
1056
1272
|
}
|
|
1273
|
+
out.push(branch);
|
|
1057
1274
|
}
|
|
1058
|
-
return
|
|
1275
|
+
return out;
|
|
1059
1276
|
}
|
|
1060
1277
|
|
|
1061
1278
|
// src/engine/suggest.ts
|
|
@@ -1114,47 +1331,10 @@ function findClosest(input, candidates, maxDistance) {
|
|
|
1114
1331
|
return best;
|
|
1115
1332
|
}
|
|
1116
1333
|
|
|
1117
|
-
// src/css/escape.ts
|
|
1118
|
-
function escapeSelector(raw) {
|
|
1119
|
-
let out = null;
|
|
1120
|
-
let runStart = 0;
|
|
1121
|
-
for (let i = 0; i < raw.length; i++) {
|
|
1122
|
-
const code = raw.charCodeAt(i);
|
|
1123
|
-
if (code >= 97 && code <= 122 || // a-z
|
|
1124
|
-
code >= 65 && code <= 90 || // A-Z
|
|
1125
|
-
code === 45 || // -
|
|
1126
|
-
code === 95 || // _
|
|
1127
|
-
code >= 128) {
|
|
1128
|
-
continue;
|
|
1129
|
-
}
|
|
1130
|
-
if (code >= 48 && code <= 57 && // 0-9
|
|
1131
|
-
i !== 0 && !(i === 1 && raw.charCodeAt(0) === 45)) {
|
|
1132
|
-
continue;
|
|
1133
|
-
}
|
|
1134
|
-
let escaped;
|
|
1135
|
-
if (code === 0) {
|
|
1136
|
-
escaped = "\uFFFD";
|
|
1137
|
-
} else if (code >= 48 && code <= 57) {
|
|
1138
|
-
escaped = `\\${code.toString(16)} `;
|
|
1139
|
-
} else if (code === 9 || code === 10 || code === 12 || code === 13) {
|
|
1140
|
-
escaped = `\\${raw[i]}`;
|
|
1141
|
-
} else if (code < 32 || code === 127) {
|
|
1142
|
-
escaped = `\\${code.toString(16)} `;
|
|
1143
|
-
} else {
|
|
1144
|
-
escaped = `\\${raw[i]}`;
|
|
1145
|
-
}
|
|
1146
|
-
if (out === null) out = [];
|
|
1147
|
-
out.push(raw.slice(runStart, i), escaped);
|
|
1148
|
-
runStart = i + 1;
|
|
1149
|
-
}
|
|
1150
|
-
if (out === null) return raw;
|
|
1151
|
-
out.push(raw.slice(runStart));
|
|
1152
|
-
return out.join("");
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
1334
|
// src/css/token-refs.ts
|
|
1156
|
-
var COLOR_STOP_REF_RE = /var\(--color-([a-z][a-z0-9]*(?:-[a-z][a-z0-9]*)*)(?:-(\d+))?\)/g;
|
|
1157
|
-
var
|
|
1335
|
+
var COLOR_STOP_REF_RE = /var\(--color-([a-z][a-z0-9]*(?:-[a-z][a-z0-9]*)*)(?:-(\d+))?\s*[,)]/g;
|
|
1336
|
+
var COLOR_VAR_REF_RE = /var\(--color-([\w-]+)\s*[,)]/g;
|
|
1337
|
+
var SHADOW_VAR_REF_RE = /var\(--shadow-(DEFAULT|[a-z0-9]+(?:-[a-z0-9]+)*)\)/g;
|
|
1158
1338
|
var TEXT_VAR_REF_RE = /var\(--text-([a-z0-9]+(?:-[a-z0-9]+)*?)(?:-leading)?\)/g;
|
|
1159
1339
|
var FONT_VAR_REF_RE = /var\(--font-([a-z][a-z0-9]*(?:-[a-z0-9]+)*)\)/g;
|
|
1160
1340
|
var ANIMATE_VAR_REF_RE = /var\(--animate-([a-z0-9]+(?:-[a-z0-9]+)*)\)/g;
|
|
@@ -1179,9 +1359,37 @@ function multi(...pairs) {
|
|
|
1179
1359
|
declarations: pairs.map(([property, value]) => ({ property, value }))
|
|
1180
1360
|
};
|
|
1181
1361
|
}
|
|
1362
|
+
function hasBalancedDelimiters(value) {
|
|
1363
|
+
const open = [];
|
|
1364
|
+
for (let i = 0; i < value.length; i++) {
|
|
1365
|
+
const ch = value[i];
|
|
1366
|
+
if (ch === "\\") {
|
|
1367
|
+
i++;
|
|
1368
|
+
} else if (ch === '"' || ch === "'") {
|
|
1369
|
+
const quote = ch;
|
|
1370
|
+
i++;
|
|
1371
|
+
while (i < value.length && value[i] !== quote) {
|
|
1372
|
+
if (value[i] === "\\") i++;
|
|
1373
|
+
i++;
|
|
1374
|
+
}
|
|
1375
|
+
if (i >= value.length) return false;
|
|
1376
|
+
} else if (ch === "(" || ch === "[") {
|
|
1377
|
+
open.push(ch);
|
|
1378
|
+
} else if (ch === ")") {
|
|
1379
|
+
if (open.pop() !== "(") return false;
|
|
1380
|
+
} else if (ch === "]") {
|
|
1381
|
+
if (open.pop() !== "[") return false;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
return open.length === 0;
|
|
1385
|
+
}
|
|
1182
1386
|
function extractArbitrary(value) {
|
|
1183
1387
|
if (!value) return null;
|
|
1184
|
-
|
|
1388
|
+
if (!value.startsWith("[") || !value.endsWith("]")) return null;
|
|
1389
|
+
const inner = value.slice(1, -1);
|
|
1390
|
+
if (inner === "") return null;
|
|
1391
|
+
const decoded = decodeArbitraryValue(inner);
|
|
1392
|
+
return hasBalancedDelimiters(decoded) ? decoded : null;
|
|
1185
1393
|
}
|
|
1186
1394
|
function normalizeDecimalToken(value) {
|
|
1187
1395
|
return value.replaceAll("_", ".");
|
|
@@ -1196,6 +1404,44 @@ function spacingLookup(value, negative = false) {
|
|
|
1196
1404
|
const expr = `calc(${normalized} * var(--spacing))`;
|
|
1197
1405
|
return negative ? `calc(${normalized} * var(--spacing) * -1)` : expr;
|
|
1198
1406
|
}
|
|
1407
|
+
var FRACTIONAL = Object.freeze({
|
|
1408
|
+
"1/2": "50%",
|
|
1409
|
+
"1/3": "33.333333%",
|
|
1410
|
+
"2/3": "66.666667%",
|
|
1411
|
+
"1/4": "25%",
|
|
1412
|
+
"2/4": "50%",
|
|
1413
|
+
"3/4": "75%",
|
|
1414
|
+
"1/5": "20%",
|
|
1415
|
+
"2/5": "40%",
|
|
1416
|
+
"3/5": "60%",
|
|
1417
|
+
"4/5": "80%",
|
|
1418
|
+
"1/6": "16.666667%",
|
|
1419
|
+
"2/6": "33.333333%",
|
|
1420
|
+
"3/6": "50%",
|
|
1421
|
+
"4/6": "66.666667%",
|
|
1422
|
+
"5/6": "83.333333%",
|
|
1423
|
+
"1/12": "8.333333%",
|
|
1424
|
+
"2/12": "16.666667%",
|
|
1425
|
+
"3/12": "25%",
|
|
1426
|
+
"4/12": "33.333333%",
|
|
1427
|
+
"5/12": "41.666667%",
|
|
1428
|
+
"6/12": "50%",
|
|
1429
|
+
"7/12": "58.333333%",
|
|
1430
|
+
"8/12": "66.666667%",
|
|
1431
|
+
"9/12": "75%",
|
|
1432
|
+
"10/12": "83.333333%",
|
|
1433
|
+
"11/12": "91.666667%"
|
|
1434
|
+
});
|
|
1435
|
+
function fractionValue(name) {
|
|
1436
|
+
if (Object.hasOwn(FRACTIONAL, name)) return FRACTIONAL[name];
|
|
1437
|
+
const slash = name.indexOf("/");
|
|
1438
|
+
if (slash === -1) return null;
|
|
1439
|
+
const numerator = name.slice(0, slash);
|
|
1440
|
+
const denominator = name.slice(slash + 1);
|
|
1441
|
+
if (!INTEGER_RE.test(numerator) || !INTEGER_RE.test(denominator)) return null;
|
|
1442
|
+
if (Number(denominator) === 0) return null;
|
|
1443
|
+
return `calc(${numerator} / ${denominator} * 100%)`;
|
|
1444
|
+
}
|
|
1199
1445
|
function deepFreezeUtilityMap(map) {
|
|
1200
1446
|
for (const value of Object.values(map)) {
|
|
1201
1447
|
Object.freeze(value.declarations);
|
|
@@ -1452,6 +1698,35 @@ var DIRECTIVE_TYPE_NAMES = [
|
|
|
1452
1698
|
"register"
|
|
1453
1699
|
];
|
|
1454
1700
|
var REMOVAL_KEY = "--ri-rm";
|
|
1701
|
+
function legacySyntaxWarning(legacy, canonical, directiveName) {
|
|
1702
|
+
const where = directiveName ? ` in @${directiveName}` : "";
|
|
1703
|
+
return `[RI-1046] \`${legacy}\`${where} is a deprecated spelling \u2014 write \`${canonical}\` instead. The old form is not valid CSS, so a formatter cannot read the file; it still works, and will be removed at 1.0.`;
|
|
1704
|
+
}
|
|
1705
|
+
function hasTopLevelKeyframes(body) {
|
|
1706
|
+
let depth = 0;
|
|
1707
|
+
for (let i = 0; i < body.length; i++) {
|
|
1708
|
+
const ch = body[i];
|
|
1709
|
+
if (ch === '"' || ch === "'") {
|
|
1710
|
+
const quote = ch;
|
|
1711
|
+
i++;
|
|
1712
|
+
while (i < body.length && body[i] !== quote) {
|
|
1713
|
+
if (body[i] === "\\") i++;
|
|
1714
|
+
i++;
|
|
1715
|
+
}
|
|
1716
|
+
continue;
|
|
1717
|
+
}
|
|
1718
|
+
if (ch === "{") depth++;
|
|
1719
|
+
else if (ch === "}") depth = Math.max(0, depth - 1);
|
|
1720
|
+
else if (ch === "@" && depth === 0 && body.startsWith("@keyframes", i)) {
|
|
1721
|
+
const after = body[i + "@keyframes".length];
|
|
1722
|
+
if (after === void 0 || !/[\w-]/.test(after)) return true;
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
return false;
|
|
1726
|
+
}
|
|
1727
|
+
function isRemovalValue(value) {
|
|
1728
|
+
return value === "initial";
|
|
1729
|
+
}
|
|
1455
1730
|
var IDENT_KEY_RE = /^[\w-]+$/;
|
|
1456
1731
|
var WS_CHAR_RE = /\s/;
|
|
1457
1732
|
function topLevelIndexOf(str, char) {
|
|
@@ -1484,7 +1759,9 @@ function* scanEntries(src, opts) {
|
|
|
1484
1759
|
let end = i + 1;
|
|
1485
1760
|
while (end < src.length && /[\w-]/.test(src[end])) end++;
|
|
1486
1761
|
const name = src.slice(i + 1, end);
|
|
1487
|
-
if (name)
|
|
1762
|
+
if (name) {
|
|
1763
|
+
yield { key: name, value: "", removal: true, legacyRemoval: true, start: i, end };
|
|
1764
|
+
}
|
|
1488
1765
|
i = end;
|
|
1489
1766
|
continue;
|
|
1490
1767
|
}
|
|
@@ -1544,6 +1821,10 @@ function* scanEntries(src, opts) {
|
|
|
1544
1821
|
if (value) yield { key: value, value: "", removal: true, start: entryStart, end: i };
|
|
1545
1822
|
continue;
|
|
1546
1823
|
}
|
|
1824
|
+
if (isRemovalValue(value)) {
|
|
1825
|
+
yield { key, value: "", removal: true, start: entryStart, end: i };
|
|
1826
|
+
continue;
|
|
1827
|
+
}
|
|
1547
1828
|
yield { key, value, block, start: entryStart, end: i };
|
|
1548
1829
|
continue;
|
|
1549
1830
|
}
|
|
@@ -1556,6 +1837,10 @@ function* scanEntries(src, opts) {
|
|
|
1556
1837
|
if (value) yield { key: value, value: "", removal: true, start: entryStart, end: i };
|
|
1557
1838
|
continue;
|
|
1558
1839
|
}
|
|
1840
|
+
if (isRemovalValue(value)) {
|
|
1841
|
+
yield { key, value: "", removal: true, start: entryStart, end: i };
|
|
1842
|
+
continue;
|
|
1843
|
+
}
|
|
1559
1844
|
yield { key, value, start: entryStart, end: i };
|
|
1560
1845
|
}
|
|
1561
1846
|
}
|
|
@@ -1567,7 +1852,9 @@ function parseKeyValueBody(body, warnings, directiveName) {
|
|
|
1567
1852
|
const line = raw.trim();
|
|
1568
1853
|
if (!line) return;
|
|
1569
1854
|
if (line.startsWith("!")) {
|
|
1570
|
-
|
|
1855
|
+
const name = line.slice(1).trim();
|
|
1856
|
+
removals.push(name);
|
|
1857
|
+
warnings?.push(legacySyntaxWarning(`!${name};`, `${name}: initial;`, directiveName));
|
|
1571
1858
|
return;
|
|
1572
1859
|
}
|
|
1573
1860
|
const colonIdx = line.indexOf(":");
|
|
@@ -1578,6 +1865,10 @@ function parseKeyValueBody(body, warnings, directiveName) {
|
|
|
1578
1865
|
removals.push(value);
|
|
1579
1866
|
return;
|
|
1580
1867
|
}
|
|
1868
|
+
if (key && isRemovalValue(value)) {
|
|
1869
|
+
removals.push(key);
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1581
1872
|
if (key && !IDENT_KEY_RE.test(key)) {
|
|
1582
1873
|
warnings?.push(
|
|
1583
1874
|
`[RI-1035] Invalid @${directiveName ?? "directive"} entry key "${key}" \u2014 keys may only contain letters, numbers, hyphens, and underscores. The entry was skipped.`
|
|
@@ -1911,42 +2202,17 @@ var VIEWPORT_SIZES = Object.freeze({
|
|
|
1911
2202
|
lvh: "100lvh",
|
|
1912
2203
|
dvh: "100dvh"
|
|
1913
2204
|
});
|
|
1914
|
-
var FRACTIONAL = Object.freeze({
|
|
1915
|
-
"1/2": "50%",
|
|
1916
|
-
"1/3": "33.333333%",
|
|
1917
|
-
"2/3": "66.666667%",
|
|
1918
|
-
"1/4": "25%",
|
|
1919
|
-
"2/4": "50%",
|
|
1920
|
-
"3/4": "75%",
|
|
1921
|
-
"1/5": "20%",
|
|
1922
|
-
"2/5": "40%",
|
|
1923
|
-
"3/5": "60%",
|
|
1924
|
-
"4/5": "80%",
|
|
1925
|
-
"1/6": "16.666667%",
|
|
1926
|
-
"2/6": "33.333333%",
|
|
1927
|
-
"3/6": "50%",
|
|
1928
|
-
"4/6": "66.666667%",
|
|
1929
|
-
"5/6": "83.333333%",
|
|
1930
|
-
"1/12": "8.333333%",
|
|
1931
|
-
"2/12": "16.666667%",
|
|
1932
|
-
"3/12": "25%",
|
|
1933
|
-
"4/12": "33.333333%",
|
|
1934
|
-
"5/12": "41.666667%",
|
|
1935
|
-
"6/12": "50%",
|
|
1936
|
-
"7/12": "58.333333%",
|
|
1937
|
-
"8/12": "66.666667%",
|
|
1938
|
-
"9/12": "75%",
|
|
1939
|
-
"10/12": "83.333333%",
|
|
1940
|
-
"11/12": "91.666667%"
|
|
1941
|
-
});
|
|
1942
2205
|
function resolveSizeValue(val, named, negative) {
|
|
1943
2206
|
const arb = extractArbitrary(val);
|
|
1944
2207
|
if (arb !== null) return negative ? `calc(${arb} * -1)` : arb;
|
|
1945
2208
|
if (Object.hasOwn(named, val)) return named[val];
|
|
1946
|
-
|
|
2209
|
+
const fraction = fractionValue(val);
|
|
2210
|
+
if (fraction !== null) return fraction;
|
|
1947
2211
|
return spacingLookup(val, negative);
|
|
1948
2212
|
}
|
|
1949
2213
|
var CONTAINER_WIDTHS = Object.freeze({
|
|
2214
|
+
"3xs": "16rem",
|
|
2215
|
+
"2xs": "18rem",
|
|
1950
2216
|
xs: "20rem",
|
|
1951
2217
|
sm: "24rem",
|
|
1952
2218
|
md: "28rem",
|
|
@@ -1971,7 +2237,11 @@ var MAX_W_NAMED = Object.freeze({
|
|
|
1971
2237
|
...VIEWPORT_SIZES
|
|
1972
2238
|
});
|
|
1973
2239
|
var MIN_W_NAMED = Object.freeze({
|
|
2240
|
+
// `auto` is a min-* value only: `max-width: auto` is not valid CSS, and
|
|
2241
|
+
// Tailwind registers no `max-w-auto` either.
|
|
2242
|
+
auto: "auto",
|
|
1974
2243
|
"0": "0px",
|
|
2244
|
+
...CONTAINER_WIDTHS,
|
|
1975
2245
|
full: "100%",
|
|
1976
2246
|
min: "min-content",
|
|
1977
2247
|
max: "max-content",
|
|
@@ -1980,6 +2250,7 @@ var MIN_W_NAMED = Object.freeze({
|
|
|
1980
2250
|
...VIEWPORT_SIZES
|
|
1981
2251
|
});
|
|
1982
2252
|
var MIN_H_NAMED = Object.freeze({
|
|
2253
|
+
auto: "auto",
|
|
1983
2254
|
"0": "0px",
|
|
1984
2255
|
full: "100%",
|
|
1985
2256
|
min: "min-content",
|
|
@@ -1999,6 +2270,15 @@ var MAX_H_NAMED = Object.freeze({
|
|
|
1999
2270
|
screen: "100vh",
|
|
2000
2271
|
...VIEWPORT_SIZES
|
|
2001
2272
|
});
|
|
2273
|
+
var SIZING_KEYWORDS = Object.freeze([
|
|
2274
|
+
.../* @__PURE__ */ new Set([
|
|
2275
|
+
...Object.keys(NAMED_SIZES),
|
|
2276
|
+
...Object.keys(MIN_W_NAMED),
|
|
2277
|
+
...Object.keys(MAX_W_NAMED),
|
|
2278
|
+
...Object.keys(MIN_H_NAMED),
|
|
2279
|
+
...Object.keys(MAX_H_NAMED)
|
|
2280
|
+
])
|
|
2281
|
+
]);
|
|
2002
2282
|
var CONSTRAINED_SIZE_TABLE = [
|
|
2003
2283
|
["min-w-", "min-width", MIN_W_NAMED],
|
|
2004
2284
|
["max-w-", "max-width", MAX_W_NAMED],
|
|
@@ -2011,7 +2291,8 @@ var CONSTRAINED_SIZE_TABLE = [
|
|
|
2011
2291
|
];
|
|
2012
2292
|
function resolveConstrainedSize(val, named, property) {
|
|
2013
2293
|
if (Object.hasOwn(named, val)) return single(property, named[val]);
|
|
2014
|
-
|
|
2294
|
+
const fraction = fractionValue(val);
|
|
2295
|
+
if (fraction !== null) return single(property, fraction);
|
|
2015
2296
|
const arb = extractArbitrary(val);
|
|
2016
2297
|
if (arb !== null) return single(property, arb);
|
|
2017
2298
|
const spacingVal = spacingLookup(val, false);
|
|
@@ -2031,6 +2312,7 @@ function sizingGenerator(_utility, _value, full, negative, _theme, _warnings) {
|
|
|
2031
2312
|
const val = full.slice(2);
|
|
2032
2313
|
const resolved = resolveSizeValue(val, NAMED_SIZES, negative);
|
|
2033
2314
|
if (resolved) return single("width", resolved);
|
|
2315
|
+
if (Object.hasOwn(CONTAINER_WIDTHS, val)) return single("width", CONTAINER_WIDTHS[val]);
|
|
2034
2316
|
}
|
|
2035
2317
|
if (full.startsWith("h-")) {
|
|
2036
2318
|
const val = full.slice(2);
|
|
@@ -2041,6 +2323,9 @@ function sizingGenerator(_utility, _value, full, negative, _theme, _warnings) {
|
|
|
2041
2323
|
const val = full.slice(7);
|
|
2042
2324
|
const resolved = resolveSizeValue(val, NAMED_SIZES, negative);
|
|
2043
2325
|
if (resolved) return single("inline-size", resolved);
|
|
2326
|
+
if (Object.hasOwn(CONTAINER_WIDTHS, val)) {
|
|
2327
|
+
return single("inline-size", CONTAINER_WIDTHS[val]);
|
|
2328
|
+
}
|
|
2044
2329
|
}
|
|
2045
2330
|
if (full.startsWith("block-")) {
|
|
2046
2331
|
const val = full.slice(6);
|
|
@@ -2397,6 +2682,15 @@ function colorGenerator(utility, value, full, _negative, theme, _warnings, dataT
|
|
|
2397
2682
|
if (resolved) return single(cssProperty, resolved);
|
|
2398
2683
|
}
|
|
2399
2684
|
}
|
|
2685
|
+
if (full.startsWith("placeholder-")) {
|
|
2686
|
+
const resolved = resolveColor(full.slice(12), theme, dataType);
|
|
2687
|
+
if (resolved) {
|
|
2688
|
+
return {
|
|
2689
|
+
declarations: [{ property: "color", value: resolved }],
|
|
2690
|
+
nestedSelector: "&::placeholder"
|
|
2691
|
+
};
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2400
2694
|
if (full.startsWith("divide-") && !DIVIDE_NON_COLOR_RE.test(full)) {
|
|
2401
2695
|
const colorName = full.slice(7);
|
|
2402
2696
|
const resolved = resolveColor(colorName, theme, dataType);
|
|
@@ -2618,8 +2912,13 @@ function splitLineHeightModifier(s) {
|
|
|
2618
2912
|
}
|
|
2619
2913
|
return { base: s, modifier: null };
|
|
2620
2914
|
}
|
|
2915
|
+
function numericLeading(value) {
|
|
2916
|
+
return DECIMAL_RE.test(value) ? spacingLookup(value) : null;
|
|
2917
|
+
}
|
|
2621
2918
|
function resolveLineHeightModifier(mod, theme) {
|
|
2622
2919
|
if (Object.hasOwn(theme.leading, mod)) return theme.leading[mod];
|
|
2920
|
+
const numeric = numericLeading(mod);
|
|
2921
|
+
if (numeric !== null) return numeric;
|
|
2623
2922
|
if (mod.startsWith("(") && mod.endsWith(")")) {
|
|
2624
2923
|
const inner = mod.slice(1, -1);
|
|
2625
2924
|
return /^--[a-zA-Z_][\w-]*$/.test(inner) ? `var(${inner})` : null;
|
|
@@ -2715,7 +3014,9 @@ function typographyGenerator(_utility, _value, full, negative, theme, warnings,
|
|
|
2715
3014
|
if (full.startsWith("text-")) {
|
|
2716
3015
|
const { base: sizeName, modifier } = splitLineHeightModifier(full.slice(5));
|
|
2717
3016
|
const lh = modifier !== null ? resolveLineHeightModifier(modifier, theme) : null;
|
|
3017
|
+
const modifierFailed = modifier !== null && lh === null;
|
|
2718
3018
|
if (Object.hasOwn(theme.text, sizeName)) {
|
|
3019
|
+
if (modifierFailed) return null;
|
|
2719
3020
|
return multi(
|
|
2720
3021
|
["font-size", `var(--text-${sizeName})`],
|
|
2721
3022
|
["line-height", lh ?? `var(--text-${sizeName}-leading)`]
|
|
@@ -2724,6 +3025,7 @@ function typographyGenerator(_utility, _value, full, negative, theme, warnings,
|
|
|
2724
3025
|
if (!isBracketedColor(sizeName)) {
|
|
2725
3026
|
const arbText = extractArbitrary(sizeName);
|
|
2726
3027
|
if (arbText) {
|
|
3028
|
+
if (modifierFailed) return null;
|
|
2727
3029
|
return lh !== null ? multi(["font-size", arbText], ["line-height", lh]) : single("font-size", arbText);
|
|
2728
3030
|
}
|
|
2729
3031
|
}
|
|
@@ -2772,6 +3074,8 @@ function typographyGenerator(_utility, _value, full, negative, theme, warnings,
|
|
|
2772
3074
|
if (Object.hasOwn(theme.leading, name)) {
|
|
2773
3075
|
return single("line-height", theme.leading[name]);
|
|
2774
3076
|
}
|
|
3077
|
+
const numeric = numericLeading(name);
|
|
3078
|
+
if (numeric !== null) return single("line-height", numeric);
|
|
2775
3079
|
const arbLeading = extractArbitrary(name);
|
|
2776
3080
|
if (arbLeading) return single("line-height", arbLeading);
|
|
2777
3081
|
if (name === "px") return single("line-height", "1px");
|
|
@@ -2910,11 +3214,6 @@ function checkAppliedFontWeights(classes, theme, warnings) {
|
|
|
2910
3214
|
|
|
2911
3215
|
// src/utilities/layout.ts
|
|
2912
3216
|
var ASPECT_RATIO_RE = /^(\d+)\/(\d+)$/;
|
|
2913
|
-
var CONTAINER_SCALE = Object.freeze({
|
|
2914
|
-
"3xs": "16rem",
|
|
2915
|
-
"2xs": "18rem",
|
|
2916
|
-
...CONTAINER_WIDTHS
|
|
2917
|
-
});
|
|
2918
3217
|
function resolveGridLine(name, negative) {
|
|
2919
3218
|
if (name === "auto") return "auto";
|
|
2920
3219
|
if (INTEGER_RE.test(name)) return negative ? `calc(${name} * -1)` : name;
|
|
@@ -2922,14 +3221,6 @@ function resolveGridLine(name, negative) {
|
|
|
2922
3221
|
if (arb !== null) return negative ? `calc(${arb} * -1)` : arb;
|
|
2923
3222
|
return null;
|
|
2924
3223
|
}
|
|
2925
|
-
function fractionToPercent(name) {
|
|
2926
|
-
const slash = name.indexOf("/");
|
|
2927
|
-
if (slash === -1) return null;
|
|
2928
|
-
const num = Number(name.slice(0, slash));
|
|
2929
|
-
const den = Number(name.slice(slash + 1));
|
|
2930
|
-
if (!Number.isFinite(num) || !Number.isFinite(den) || den <= 0) return null;
|
|
2931
|
-
return `${Math.round(num / den * 1e6) / 1e4}%`;
|
|
2932
|
-
}
|
|
2933
3224
|
function resolveGridTemplate(name, property) {
|
|
2934
3225
|
if (name === "none") return single(property, "none");
|
|
2935
3226
|
if (name === "subgrid") return single(property, "subgrid");
|
|
@@ -3465,7 +3756,7 @@ function resolveColumns(full) {
|
|
|
3465
3756
|
const name = full.slice(8);
|
|
3466
3757
|
if (name === "auto") return single("columns", "auto");
|
|
3467
3758
|
if (INTEGER_RE.test(name)) return single("columns", name);
|
|
3468
|
-
if (Object.hasOwn(
|
|
3759
|
+
if (Object.hasOwn(CONTAINER_WIDTHS, name)) return single("columns", CONTAINER_WIDTHS[name]);
|
|
3469
3760
|
const arb = extractArbitrary(name);
|
|
3470
3761
|
if (arb) return single("columns", arb);
|
|
3471
3762
|
return null;
|
|
@@ -3490,19 +3781,18 @@ function resolveBasis(full) {
|
|
|
3490
3781
|
const name = full.slice(6);
|
|
3491
3782
|
const arb = extractArbitrary(name);
|
|
3492
3783
|
if (arb !== null) return single("flex-basis", arb);
|
|
3493
|
-
|
|
3784
|
+
if (Object.hasOwn(CONTAINER_WIDTHS, name)) return single("flex-basis", CONTAINER_WIDTHS[name]);
|
|
3785
|
+
const pct = fractionValue(name);
|
|
3494
3786
|
if (pct !== null) return single("flex-basis", pct);
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
if (sp) return single("flex-basis", sp);
|
|
3498
|
-
}
|
|
3787
|
+
const sp = spacingLookup(name, false);
|
|
3788
|
+
if (sp) return single("flex-basis", sp);
|
|
3499
3789
|
return null;
|
|
3500
3790
|
}
|
|
3501
3791
|
function resolveFlex(full) {
|
|
3502
3792
|
const name = full.slice(5);
|
|
3503
3793
|
const arb = extractArbitrary(name);
|
|
3504
3794
|
if (arb !== null) return single("flex", arb);
|
|
3505
|
-
const pct =
|
|
3795
|
+
const pct = fractionValue(name);
|
|
3506
3796
|
if (pct !== null) return single("flex", pct);
|
|
3507
3797
|
if (DECIMAL_RE.test(name)) return single("flex", normalizeDecimalToken(name));
|
|
3508
3798
|
return null;
|
|
@@ -3787,9 +4077,17 @@ function borderGenerator(_utility, _value, full, negative, theme, _warnings, dat
|
|
|
3787
4077
|
return multi(["corner-shape", arb], ["--ri-rounded-scale", "1"]);
|
|
3788
4078
|
}
|
|
3789
4079
|
}
|
|
4080
|
+
if (full === "rounded") {
|
|
4081
|
+
const r = resolveRadius("DEFAULT", theme);
|
|
4082
|
+
if (r) return single("border-radius", r);
|
|
4083
|
+
}
|
|
3790
4084
|
if (full.startsWith("rounded-")) {
|
|
3791
4085
|
const rest = full.slice(8);
|
|
3792
4086
|
for (const [suffix, prop] of ROUNDED_CORNER_ENTRIES) {
|
|
4087
|
+
if (rest === suffix) {
|
|
4088
|
+
const r2 = resolveRadius("DEFAULT", theme);
|
|
4089
|
+
if (r2) return single(prop, r2);
|
|
4090
|
+
}
|
|
3793
4091
|
if (rest.startsWith(suffix) && rest.charCodeAt(suffix.length) === 45) {
|
|
3794
4092
|
const size = rest.slice(suffix.length + 1);
|
|
3795
4093
|
const r2 = resolveRadius(size, theme);
|
|
@@ -3797,6 +4095,10 @@ function borderGenerator(_utility, _value, full, negative, theme, _warnings, dat
|
|
|
3797
4095
|
}
|
|
3798
4096
|
}
|
|
3799
4097
|
for (const [suffix, props] of ROUNDED_SIDE_ENTRIES) {
|
|
4098
|
+
if (rest === suffix) {
|
|
4099
|
+
const r2 = resolveRadius("DEFAULT", theme);
|
|
4100
|
+
if (r2) return multi(...props.map((p) => [p, r2]));
|
|
4101
|
+
}
|
|
3800
4102
|
if (rest.startsWith(suffix) && rest.charCodeAt(suffix.length) === 45) {
|
|
3801
4103
|
const size = rest.slice(suffix.length + 1);
|
|
3802
4104
|
const r2 = resolveRadius(size, theme);
|
|
@@ -3864,6 +4166,143 @@ function borderGenerator(_utility, _value, full, negative, theme, _warnings, dat
|
|
|
3864
4166
|
return null;
|
|
3865
4167
|
}
|
|
3866
4168
|
|
|
4169
|
+
// src/css/shadow-color.ts
|
|
4170
|
+
var SHADOW_KEYWORDS = /* @__PURE__ */ new Set([
|
|
4171
|
+
"inset",
|
|
4172
|
+
"inherit",
|
|
4173
|
+
"initial",
|
|
4174
|
+
"revert",
|
|
4175
|
+
"revert-layer",
|
|
4176
|
+
"unset"
|
|
4177
|
+
]);
|
|
4178
|
+
var MATH_FUNCTIONS2 = /* @__PURE__ */ new Set(["calc", "clamp", "min", "max"]);
|
|
4179
|
+
var COLOR_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
4180
|
+
"color",
|
|
4181
|
+
"color-mix",
|
|
4182
|
+
"contrast-color",
|
|
4183
|
+
"device-cmyk",
|
|
4184
|
+
"hsl",
|
|
4185
|
+
"hsla",
|
|
4186
|
+
"hwb",
|
|
4187
|
+
"lab",
|
|
4188
|
+
"lch",
|
|
4189
|
+
"light-dark",
|
|
4190
|
+
"oklab",
|
|
4191
|
+
"oklch",
|
|
4192
|
+
"rgb",
|
|
4193
|
+
"rgba"
|
|
4194
|
+
]);
|
|
4195
|
+
var LENGTH_START_RE = /^-?(?:\d+|\.\d+)/;
|
|
4196
|
+
function splitShadowLayers(value) {
|
|
4197
|
+
const layers = [];
|
|
4198
|
+
let depth = 0;
|
|
4199
|
+
let start = 0;
|
|
4200
|
+
for (let i = 0; i < value.length; i++) {
|
|
4201
|
+
const ch = value[i];
|
|
4202
|
+
if (ch === "\\") {
|
|
4203
|
+
i++;
|
|
4204
|
+
continue;
|
|
4205
|
+
}
|
|
4206
|
+
if (ch === "(" || ch === "[") depth++;
|
|
4207
|
+
else if (ch === ")" || ch === "]") depth = Math.max(0, depth - 1);
|
|
4208
|
+
else if (ch === "," && depth === 0) {
|
|
4209
|
+
layers.push(value.slice(start, i));
|
|
4210
|
+
start = i + 1;
|
|
4211
|
+
}
|
|
4212
|
+
}
|
|
4213
|
+
layers.push(value.slice(start));
|
|
4214
|
+
return layers;
|
|
4215
|
+
}
|
|
4216
|
+
function tokenizeLayer(layer) {
|
|
4217
|
+
const tokens = [];
|
|
4218
|
+
let i = 0;
|
|
4219
|
+
while (i < layer.length) {
|
|
4220
|
+
if (/\s/.test(layer[i])) {
|
|
4221
|
+
i++;
|
|
4222
|
+
continue;
|
|
4223
|
+
}
|
|
4224
|
+
const start = i;
|
|
4225
|
+
let depth = 0;
|
|
4226
|
+
let isFunction = false;
|
|
4227
|
+
while (i < layer.length) {
|
|
4228
|
+
const ch = layer[i];
|
|
4229
|
+
if (ch === "\\") {
|
|
4230
|
+
i += 2;
|
|
4231
|
+
continue;
|
|
4232
|
+
}
|
|
4233
|
+
if (ch === "(") {
|
|
4234
|
+
if (depth === 0) isFunction = true;
|
|
4235
|
+
depth++;
|
|
4236
|
+
} else if (ch === ")") {
|
|
4237
|
+
depth = Math.max(0, depth - 1);
|
|
4238
|
+
} else if (depth === 0 && /\s/.test(ch)) {
|
|
4239
|
+
break;
|
|
4240
|
+
}
|
|
4241
|
+
i++;
|
|
4242
|
+
}
|
|
4243
|
+
tokens.push({ start, end: i, text: layer.slice(start, i), isFunction });
|
|
4244
|
+
}
|
|
4245
|
+
return tokens;
|
|
4246
|
+
}
|
|
4247
|
+
function functionName(text) {
|
|
4248
|
+
const open = text.indexOf("(");
|
|
4249
|
+
return open === -1 ? "" : text.slice(0, open).toLowerCase();
|
|
4250
|
+
}
|
|
4251
|
+
function slotLayer(layer, colorVar) {
|
|
4252
|
+
const trimmed = layer.trim();
|
|
4253
|
+
if (trimmed === "") return layer;
|
|
4254
|
+
const bang = /!\s*important\s*$/i.exec(trimmed);
|
|
4255
|
+
const core = bang === null ? trimmed : trimmed.slice(0, bang.index).trimEnd();
|
|
4256
|
+
const suffix = bang === null ? "" : ` ${trimmed.slice(bang.index)}`;
|
|
4257
|
+
if (core === "") return layer;
|
|
4258
|
+
const lead = layer.slice(0, layer.indexOf(trimmed));
|
|
4259
|
+
const trail = layer.slice(lead.length + trimmed.length);
|
|
4260
|
+
const tokens = tokenizeLayer(core);
|
|
4261
|
+
let lengths = 0;
|
|
4262
|
+
let values = 0;
|
|
4263
|
+
let last = null;
|
|
4264
|
+
let hit = null;
|
|
4265
|
+
for (const token of tokens) {
|
|
4266
|
+
if (token.isFunction) {
|
|
4267
|
+
const name = functionName(token.text);
|
|
4268
|
+
if (COLOR_FUNCTIONS.has(name)) {
|
|
4269
|
+
hit = token;
|
|
4270
|
+
break;
|
|
4271
|
+
}
|
|
4272
|
+
if (MATH_FUNCTIONS2.has(name)) {
|
|
4273
|
+
lengths++;
|
|
4274
|
+
continue;
|
|
4275
|
+
}
|
|
4276
|
+
last = token;
|
|
4277
|
+
values++;
|
|
4278
|
+
continue;
|
|
4279
|
+
}
|
|
4280
|
+
if (SHADOW_KEYWORDS.has(token.text.toLowerCase())) continue;
|
|
4281
|
+
if (token.text.startsWith("#")) {
|
|
4282
|
+
hit = token;
|
|
4283
|
+
break;
|
|
4284
|
+
}
|
|
4285
|
+
if (LENGTH_START_RE.test(token.text)) {
|
|
4286
|
+
lengths++;
|
|
4287
|
+
continue;
|
|
4288
|
+
}
|
|
4289
|
+
last = token;
|
|
4290
|
+
values++;
|
|
4291
|
+
}
|
|
4292
|
+
const wrap = (token) => {
|
|
4293
|
+
if (token.text.startsWith(`var(${colorVar}`)) return layer;
|
|
4294
|
+
return lead + core.slice(0, token.start) + `var(${colorVar}, ${token.text})` + core.slice(token.end) + suffix + trail;
|
|
4295
|
+
};
|
|
4296
|
+
if (hit !== null) return wrap(hit);
|
|
4297
|
+
if (lengths < 2) return layer;
|
|
4298
|
+
if (values === 0) return `${lead + core} var(${colorVar}, currentColor)${suffix}${trail}`;
|
|
4299
|
+
if (values === 1 && last !== null) return wrap(last);
|
|
4300
|
+
return layer;
|
|
4301
|
+
}
|
|
4302
|
+
function withShadowColorSlotLayers(value, colorVar) {
|
|
4303
|
+
return splitShadowLayers(value).map((layer) => slotLayer(layer, colorVar).trim());
|
|
4304
|
+
}
|
|
4305
|
+
|
|
3867
4306
|
// src/utilities/effects/shadows.ts
|
|
3868
4307
|
var SHADOW_COMPOSITION = "var(--ri-inset-shadow, 0 0 #0000), var(--ri-inset-ring-shadow, 0 0 #0000), var(--ri-ring-offset-shadow, 0 0 #0000), var(--ri-ring-shadow, 0 0 #0000), var(--ri-shadow, 0 0 #0000)";
|
|
3869
4308
|
function composedShadow(slot, value) {
|
|
@@ -3887,58 +4326,103 @@ function resolveColorOrArbitrary(name, colorVar, theme, dataType, onArbitrary) {
|
|
|
3887
4326
|
}
|
|
3888
4327
|
return null;
|
|
3889
4328
|
}
|
|
3890
|
-
function resolveShadowFamily(name,
|
|
3891
|
-
if (name === "none") return wrap(
|
|
3892
|
-
|
|
3893
|
-
}
|
|
3894
|
-
function resolveShadow(full, theme, dataType) {
|
|
3895
|
-
const name = full === "shadow" ? Object.hasOwn(theme.shadows, "DEFAULT") ? "DEFAULT" : Object.hasOwn(theme.shadows, "md") ? "md" : "" : full.slice(7);
|
|
3896
|
-
if (Object.hasOwn(theme.shadows, name))
|
|
3897
|
-
return composedShadow("--ri-shadow", `var(--shadow-${name})`);
|
|
3898
|
-
if (name === "none") return composedShadow("--ri-shadow", "0 0 #0000");
|
|
4329
|
+
function resolveShadowFamily(name, theme, dataType, family) {
|
|
4330
|
+
if (name === "none") return family.wrap([family.none]);
|
|
4331
|
+
if (family.initial && name === "initial") return single(family.colorVar, "initial");
|
|
3899
4332
|
return resolveColorOrArbitrary(
|
|
3900
4333
|
name,
|
|
3901
|
-
|
|
4334
|
+
family.colorVar,
|
|
3902
4335
|
theme,
|
|
3903
4336
|
dataType,
|
|
3904
|
-
(arb) =>
|
|
4337
|
+
(arb) => family.wrap(withShadowColorSlotLayers(arb, family.colorVar))
|
|
3905
4338
|
);
|
|
3906
4339
|
}
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
4340
|
+
var BOX_SHADOW = {
|
|
4341
|
+
none: "0 0 #0000",
|
|
4342
|
+
colorVar: "--ri-shadow-color",
|
|
4343
|
+
initial: true,
|
|
4344
|
+
wrap: (layers) => composedShadow("--ri-shadow", layers.join(", "))
|
|
4345
|
+
};
|
|
4346
|
+
var INSET_SHADOW = {
|
|
4347
|
+
none: "inset 0 0 #0000",
|
|
4348
|
+
colorVar: "--ri-inset-shadow-color",
|
|
4349
|
+
initial: true,
|
|
4350
|
+
wrap: (layers) => composedShadow("--ri-inset-shadow", layers.join(", "))
|
|
4351
|
+
};
|
|
4352
|
+
var TEXT_SHADOW = {
|
|
4353
|
+
none: "none",
|
|
4354
|
+
colorVar: "--ri-text-shadow-color",
|
|
4355
|
+
initial: true,
|
|
4356
|
+
wrap: (layers) => single("text-shadow", layers.join(", "))
|
|
4357
|
+
};
|
|
4358
|
+
function resolveShadow(full, theme, dataType) {
|
|
4359
|
+
const name = full === "shadow" ? Object.hasOwn(theme.shadows, "DEFAULT") ? "DEFAULT" : Object.hasOwn(theme.shadows, "md") ? "md" : "" : full.slice(7);
|
|
4360
|
+
if (Object.hasOwn(theme.shadows, name)) {
|
|
4361
|
+
return BOX_SHADOW.wrap(withShadowColorSlotLayers(theme.shadows[name], BOX_SHADOW.colorVar));
|
|
4362
|
+
}
|
|
4363
|
+
return resolveShadowFamily(name, theme, dataType, BOX_SHADOW);
|
|
3917
4364
|
}
|
|
3918
|
-
function
|
|
3919
|
-
|
|
4365
|
+
function resolveInsetShadow(full, theme, dataType) {
|
|
4366
|
+
return resolveShadowFamily(full.slice(13), theme, dataType, INSET_SHADOW);
|
|
4367
|
+
}
|
|
4368
|
+
var RING_INSET_FLAG = "var(--ri-ring-inset, ) ";
|
|
4369
|
+
var RING_OFFSET_WIDTH = "var(--ri-ring-offset-width, 0px)";
|
|
4370
|
+
var RING = {
|
|
4371
|
+
slot: "--ri-ring-shadow",
|
|
4372
|
+
colorVar: "--ri-ring-color",
|
|
4373
|
+
insetPrefix: RING_INSET_FLAG,
|
|
4374
|
+
offsetAware: true
|
|
4375
|
+
};
|
|
4376
|
+
var INSET_RING = {
|
|
4377
|
+
slot: "--ri-inset-ring-shadow",
|
|
4378
|
+
colorVar: "--ri-inset-ring-color",
|
|
4379
|
+
insetPrefix: "inset ",
|
|
4380
|
+
offsetAware: false
|
|
4381
|
+
};
|
|
4382
|
+
function resolveRingFamily(name, theme, dataType, family) {
|
|
4383
|
+
const ring = (width) => {
|
|
4384
|
+
const w = family.offsetAware ? `calc(${width} + ${RING_OFFSET_WIDTH})` : width;
|
|
4385
|
+
return composedShadow(
|
|
4386
|
+
family.slot,
|
|
4387
|
+
`${family.insetPrefix}0 0 0 ${w} var(${family.colorVar}, currentColor)`
|
|
4388
|
+
);
|
|
4389
|
+
};
|
|
3920
4390
|
if (name === "") return ring("1px");
|
|
3921
4391
|
if (INTEGER_RE.test(name)) return ring(`${name}px`);
|
|
3922
|
-
return resolveColorOrArbitrary(name, colorVar, theme, dataType, (arb) => ring(arb));
|
|
4392
|
+
return resolveColorOrArbitrary(name, family.colorVar, theme, dataType, (arb) => ring(arb));
|
|
3923
4393
|
}
|
|
3924
|
-
function
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
"--ri-ring-
|
|
3928
|
-
|
|
3929
|
-
|
|
4394
|
+
function resolveRingOffset(full, theme, dataType) {
|
|
4395
|
+
const name = full.slice(12);
|
|
4396
|
+
const offset = (width) => multi(
|
|
4397
|
+
["--ri-ring-offset-width", width],
|
|
4398
|
+
[
|
|
4399
|
+
"--ri-ring-offset-shadow",
|
|
4400
|
+
`${RING_INSET_FLAG}0 0 0 ${RING_OFFSET_WIDTH} var(--ri-ring-offset-color, #fff)`
|
|
4401
|
+
]
|
|
4402
|
+
);
|
|
4403
|
+
if (INTEGER_RE.test(name)) return offset(`${name}px`);
|
|
4404
|
+
return resolveColorOrArbitrary(
|
|
4405
|
+
name,
|
|
4406
|
+
"--ri-ring-offset-color",
|
|
3930
4407
|
theme,
|
|
3931
|
-
dataType
|
|
4408
|
+
dataType,
|
|
4409
|
+
(arb) => offset(arb)
|
|
3932
4410
|
);
|
|
3933
4411
|
}
|
|
4412
|
+
function resolveRing(full, theme, dataType) {
|
|
4413
|
+
const offset = full.startsWith("ring-offset-") ? resolveRingOffset(full, theme, dataType) : null;
|
|
4414
|
+
if (offset) return offset;
|
|
4415
|
+
const ring = resolveRingFamily(full === "ring" ? "" : full.slice(5), theme, dataType, RING);
|
|
4416
|
+
if (ring) return ring;
|
|
4417
|
+
if (full === "ring-inset") return single("--ri-ring-inset", "inset");
|
|
4418
|
+
return null;
|
|
4419
|
+
}
|
|
3934
4420
|
function resolveInsetRing(full, theme, dataType) {
|
|
3935
4421
|
return resolveRingFamily(
|
|
3936
4422
|
full === "inset-ring" ? "" : full.slice(11),
|
|
3937
|
-
"--ri-inset-ring-shadow",
|
|
3938
|
-
"--ri-inset-ring-color",
|
|
3939
|
-
"inset ",
|
|
3940
4423
|
theme,
|
|
3941
|
-
dataType
|
|
4424
|
+
dataType,
|
|
4425
|
+
INSET_RING
|
|
3942
4426
|
);
|
|
3943
4427
|
}
|
|
3944
4428
|
function resolveInset(full, theme, dataType) {
|
|
@@ -3948,15 +4432,7 @@ function resolveInset(full, theme, dataType) {
|
|
|
3948
4432
|
return null;
|
|
3949
4433
|
}
|
|
3950
4434
|
function resolveTextShadow(full, theme, dataType) {
|
|
3951
|
-
return resolveShadowFamily(
|
|
3952
|
-
full.slice(12),
|
|
3953
|
-
// "text-shadow-".length
|
|
3954
|
-
"none",
|
|
3955
|
-
"--ri-text-shadow-color",
|
|
3956
|
-
theme,
|
|
3957
|
-
dataType,
|
|
3958
|
-
(value) => single("text-shadow", value)
|
|
3959
|
-
);
|
|
4435
|
+
return resolveShadowFamily(full.slice(12), theme, dataType, TEXT_SHADOW);
|
|
3960
4436
|
}
|
|
3961
4437
|
|
|
3962
4438
|
// src/utilities/effects/transitions.ts
|
|
@@ -4051,14 +4527,32 @@ function resolveTransition(full) {
|
|
|
4051
4527
|
}
|
|
4052
4528
|
|
|
4053
4529
|
// src/utilities/effects/filters.ts
|
|
4054
|
-
var
|
|
4055
|
-
|
|
4530
|
+
var DROP_SHADOW = {
|
|
4531
|
+
none: "0 0 #0000",
|
|
4532
|
+
colorVar: "--ri-drop-shadow-color",
|
|
4533
|
+
initial: false,
|
|
4534
|
+
// One `drop-shadow()` per layer, space-joined: the function takes a single
|
|
4535
|
+
// shadow, so a two-layer value written as `drop-shadow(a, b)` is invalid and
|
|
4536
|
+
// drops silently.
|
|
4537
|
+
wrap: (layers) => multi(
|
|
4538
|
+
["--ri-drop-shadow", layers.map((l) => `drop-shadow(${l})`).join(" ")],
|
|
4539
|
+
["filter", FILTER_COMPOSED]
|
|
4540
|
+
)
|
|
4541
|
+
};
|
|
4056
4542
|
var FILTER_STATICS = {
|
|
4057
4543
|
// Filter — grayscale/invert/sepia (bare + numeric) are handled dynamically via
|
|
4058
|
-
// FILTER_TABLE (bare100)
|
|
4544
|
+
// FILTER_TABLE (bare100). Bare `filter` enables the chain and contributes
|
|
4545
|
+
// nothing of its own, which is what makes a v3-era `filter blur-sm` string
|
|
4546
|
+
// work; `filter-none` is the reset.
|
|
4547
|
+
filter: single("filter", FILTER_COMPOSED),
|
|
4059
4548
|
"filter-none": single("filter", "none"),
|
|
4060
|
-
// Backdrop filter
|
|
4061
|
-
|
|
4549
|
+
// Backdrop filter. `backdrop-blur-none` is NOT here: it clears the blur slot
|
|
4550
|
+
// and re-emits the chain, exactly as `blur-none` does, so it composes with
|
|
4551
|
+
// the other backdrop functions instead of erasing them. It used to be
|
|
4552
|
+
// `backdrop-filter: none`, which is the v3 reading — v4.3.3 emits
|
|
4553
|
+
// `--tw-backdrop-blur: ;` followed by the chain, and `backdrop-filter-none`
|
|
4554
|
+
// is the spelling that really does reset everything.
|
|
4555
|
+
"backdrop-filter": single("backdrop-filter", BACKDROP_FILTER_COMPOSED)
|
|
4062
4556
|
};
|
|
4063
4557
|
deepFreezeUtilityMap(FILTER_STATICS);
|
|
4064
4558
|
var FILTER_TABLE = [
|
|
@@ -4115,15 +4609,7 @@ function resolveFilter(full, negative, theme, dataType) {
|
|
|
4115
4609
|
if (r !== void 0) return r;
|
|
4116
4610
|
}
|
|
4117
4611
|
if (full.startsWith("drop-shadow-")) {
|
|
4118
|
-
return resolveShadowFamily(
|
|
4119
|
-
full.slice(12),
|
|
4120
|
-
// "drop-shadow-".length
|
|
4121
|
-
"0 0 #0000",
|
|
4122
|
-
"--ri-drop-shadow-color",
|
|
4123
|
-
theme,
|
|
4124
|
-
dataType,
|
|
4125
|
-
(value) => multi(["--ri-drop-shadow", `drop-shadow(${value})`], ["filter", FILTER_COMPOSED])
|
|
4126
|
-
);
|
|
4612
|
+
return resolveShadowFamily(full.slice(12), theme, dataType, DROP_SHADOW);
|
|
4127
4613
|
}
|
|
4128
4614
|
return null;
|
|
4129
4615
|
}
|
|
@@ -4147,6 +4633,12 @@ function resolveBackdropFilter(full, theme, negative) {
|
|
|
4147
4633
|
if (full.startsWith("backdrop-blur-")) {
|
|
4148
4634
|
const name = full.slice(14);
|
|
4149
4635
|
if (name === "") return null;
|
|
4636
|
+
if (name === "none" && !Object.hasOwn(theme.blur, name)) {
|
|
4637
|
+
return multi(
|
|
4638
|
+
["--ri-backdrop-blur", "blur(0)"],
|
|
4639
|
+
["backdrop-filter", BACKDROP_FILTER_COMPOSED]
|
|
4640
|
+
);
|
|
4641
|
+
}
|
|
4150
4642
|
const blur = resolveBlurValue(
|
|
4151
4643
|
name,
|
|
4152
4644
|
theme,
|
|
@@ -4181,8 +4673,12 @@ function resolveBackdropFilter(full, theme, negative) {
|
|
|
4181
4673
|
|
|
4182
4674
|
// src/utilities/effects/transforms.ts
|
|
4183
4675
|
var TRANSFORM_COMPOSED = "var(--ri-rotate-x, rotateX(0)) var(--ri-rotate-y, rotateY(0)) var(--ri-rotate-z, rotateZ(0)) var(--ri-skew-x, skewX(0)) var(--ri-skew-y, skewY(0))";
|
|
4676
|
+
var TRANSLATE_XYZ = "var(--ri-translate-x, 0) var(--ri-translate-y, 0) var(--ri-translate-z, 0)";
|
|
4184
4677
|
var TRANSFORM_STATICS = {
|
|
4185
|
-
// Transform
|
|
4678
|
+
// Transform. Bare `transform` and `transform-cpu` are the same declaration —
|
|
4679
|
+
// upstream emits them byte-identically; `-cpu` is the v3-era spelling kept
|
|
4680
|
+
// as the explicit opposite of `-gpu`. Do not "dedupe" the pair away.
|
|
4681
|
+
transform: single("transform", TRANSFORM_COMPOSED),
|
|
4186
4682
|
"transform-none": single("transform", "none"),
|
|
4187
4683
|
"transform-gpu": single("transform", `translateZ(0) ${TRANSFORM_COMPOSED}`),
|
|
4188
4684
|
"transform-cpu": single("transform", TRANSFORM_COMPOSED),
|
|
@@ -4197,6 +4693,7 @@ var TRANSFORM_STATICS = {
|
|
|
4197
4693
|
"transform-view": single("transform-box", "view-box"),
|
|
4198
4694
|
// Translate reset
|
|
4199
4695
|
"translate-none": single("translate", "none"),
|
|
4696
|
+
"translate-3d": single("translate", TRANSLATE_XYZ),
|
|
4200
4697
|
// Rotate reset
|
|
4201
4698
|
"rotate-none": single("rotate", "none"),
|
|
4202
4699
|
// Scale reset
|
|
@@ -4231,14 +4728,8 @@ function resolveTranslate(full, negative) {
|
|
|
4231
4728
|
) : null;
|
|
4232
4729
|
}
|
|
4233
4730
|
if (full.startsWith("translate-z-")) {
|
|
4234
|
-
const val = resolveTransformValue(full.slice(12), negative);
|
|
4235
|
-
return val ? multi(
|
|
4236
|
-
["--ri-translate-z", val],
|
|
4237
|
-
[
|
|
4238
|
-
"translate",
|
|
4239
|
-
"var(--ri-translate-x, 0) var(--ri-translate-y, 0) var(--ri-translate-z, 0)"
|
|
4240
|
-
]
|
|
4241
|
-
) : null;
|
|
4731
|
+
const val = resolveTransformValue(full.slice(12), negative, false);
|
|
4732
|
+
return val ? multi(["--ri-translate-z", val], ["translate", TRANSLATE_XYZ]) : null;
|
|
4242
4733
|
}
|
|
4243
4734
|
if (full.startsWith("translate-")) {
|
|
4244
4735
|
const val = resolveTransformValue(full.slice(10), negative);
|
|
@@ -4378,9 +4869,15 @@ function resolveSkew(full, negative) {
|
|
|
4378
4869
|
["transform", TRANSFORM_COMPOSED]
|
|
4379
4870
|
);
|
|
4380
4871
|
}
|
|
4381
|
-
function resolveTransformValue(name, negative) {
|
|
4382
|
-
if (
|
|
4383
|
-
|
|
4872
|
+
function resolveTransformValue(name, negative, percentOk = true) {
|
|
4873
|
+
if (percentOk) {
|
|
4874
|
+
if (name === "full") return negative ? "-100%" : "100%";
|
|
4875
|
+
const fraction = fractionValue(name);
|
|
4876
|
+
if (fraction !== null) {
|
|
4877
|
+
if (!negative) return fraction;
|
|
4878
|
+
return fraction.startsWith("calc(") ? `calc(${fraction} * -1)` : `-${fraction}`;
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4384
4881
|
const arb = extractArbitrary(name);
|
|
4385
4882
|
if (arb !== null) return negative ? `calc(${arb} * -1)` : arb;
|
|
4386
4883
|
return spacingLookup(name, negative);
|
|
@@ -4972,6 +5469,8 @@ function svgGenerator(_utility, _value, full, _negative, _theme) {
|
|
|
4972
5469
|
}
|
|
4973
5470
|
|
|
4974
5471
|
// src/utilities/roots.ts
|
|
5472
|
+
var CONTAINER_KEYS = Object.keys(CONTAINER_WIDTHS);
|
|
5473
|
+
var FRACTION_KEYS = Object.keys(FRACTIONAL);
|
|
4975
5474
|
var SPACING_SAMPLES = Object.freeze([
|
|
4976
5475
|
"0",
|
|
4977
5476
|
"1",
|
|
@@ -5001,8 +5500,12 @@ var COLOR_BORDER = [colorGenerator, borderGenerator];
|
|
|
5001
5500
|
var EFFECTS = [effectsGenerator];
|
|
5002
5501
|
var ANIMATION_EFFECTS = [animationGenerator, effectsGenerator];
|
|
5003
5502
|
var STATICS_ONLY = { kinds: [] };
|
|
5004
|
-
var SHADOW_SPEC = {
|
|
5503
|
+
var SHADOW_SPEC = {
|
|
5504
|
+
kinds: ["shadow", "color", "special-color"],
|
|
5505
|
+
keywords: ["none", "initial"]
|
|
5506
|
+
};
|
|
5005
5507
|
var RING_SPEC = { kinds: ["int", "color", "special-color"] };
|
|
5508
|
+
var OUTER_RING_SPEC = { ...RING_SPEC, keywords: ["inset"] };
|
|
5006
5509
|
var ROTATE_SKEW_SPEC = {
|
|
5007
5510
|
kinds: ["keywords"],
|
|
5008
5511
|
keywords: [
|
|
@@ -5104,21 +5607,36 @@ var ROOT_GROUPS = [
|
|
|
5104
5607
|
resolvers: SPACING,
|
|
5105
5608
|
spec: { kinds: ["fluid-range"] }
|
|
5106
5609
|
},
|
|
5107
|
-
// Sizing
|
|
5610
|
+
// Sizing. Every root here is offered the whole union of named sizing values
|
|
5611
|
+
// and its own table decides — the enumerator drops a candidate that does not
|
|
5612
|
+
// resolve, so a shared list cannot over-report, while a per-root list can and
|
|
5613
|
+
// did under-report (the logical spellings had none of their own).
|
|
5614
|
+
{
|
|
5615
|
+
roots: ["h", "size", "min", "max"],
|
|
5616
|
+
resolvers: SIZING,
|
|
5617
|
+
spec: { kinds: ["spacing", "fraction"], keywords: SIZING_KEYWORDS }
|
|
5618
|
+
},
|
|
5108
5619
|
{
|
|
5109
|
-
|
|
5620
|
+
// The inline axis reads the container ladder; the block axis does not,
|
|
5621
|
+
// which is why these two are not in the row above.
|
|
5622
|
+
roots: ["w", "min-w", "inline", "min-inline", "max-inline"],
|
|
5110
5623
|
resolvers: SIZING,
|
|
5111
|
-
spec: { kinds: ["spacing", "fraction"] }
|
|
5624
|
+
spec: { kinds: ["spacing", "fraction"], keywords: [...CONTAINER_KEYS, ...SIZING_KEYWORDS] }
|
|
5112
5625
|
},
|
|
5113
5626
|
{
|
|
5114
5627
|
roots: ["max-w"],
|
|
5115
5628
|
resolvers: SIZING,
|
|
5116
|
-
spec: { kinds: ["spacing", "fraction",
|
|
5629
|
+
spec: { kinds: ["spacing", "fraction"], keywords: [...CONTAINER_KEYS, ...SIZING_KEYWORDS] }
|
|
5117
5630
|
},
|
|
5118
5631
|
{
|
|
5119
|
-
|
|
5632
|
+
// `min-block` / `max-block` are roots in their own right, the way
|
|
5633
|
+
// `min-inline` / `max-inline` are. Without them these fell through to the
|
|
5634
|
+
// bare `min` / `max` roots, where the value would have had to be spelled
|
|
5635
|
+
// `block-full` — so the whole logical block axis was unenumerable while
|
|
5636
|
+
// resolving perfectly well.
|
|
5637
|
+
roots: ["min-h", "max-h", "min-block", "max-block"],
|
|
5120
5638
|
resolvers: SIZING,
|
|
5121
|
-
spec: { kinds: ["spacing", "fraction"] }
|
|
5639
|
+
spec: { kinds: ["spacing", "fraction"], keywords: SIZING_KEYWORDS }
|
|
5122
5640
|
},
|
|
5123
5641
|
// Typography
|
|
5124
5642
|
{
|
|
@@ -5234,7 +5752,7 @@ var ROOT_GROUPS = [
|
|
|
5234
5752
|
spec: { kinds: ["color", "special-color", "int"] }
|
|
5235
5753
|
},
|
|
5236
5754
|
{
|
|
5237
|
-
roots: ["accent", "caret", "fill"],
|
|
5755
|
+
roots: ["accent", "caret", "fill", "placeholder"],
|
|
5238
5756
|
resolvers: COLOR_BORDER_EFFECTS_SVG,
|
|
5239
5757
|
spec: { kinds: ["color", "special-color"] }
|
|
5240
5758
|
},
|
|
@@ -5403,7 +5921,7 @@ var ROOT_GROUPS = [
|
|
|
5403
5921
|
{
|
|
5404
5922
|
roots: ["columns"],
|
|
5405
5923
|
resolvers: LAYOUT,
|
|
5406
|
-
spec: { kinds: ["
|
|
5924
|
+
spec: { kinds: ["int"], keywords: CONTAINER_KEYS }
|
|
5407
5925
|
},
|
|
5408
5926
|
{
|
|
5409
5927
|
roots: ["sr"],
|
|
@@ -5423,7 +5941,7 @@ var ROOT_GROUPS = [
|
|
|
5423
5941
|
{
|
|
5424
5942
|
roots: ["basis"],
|
|
5425
5943
|
resolvers: LAYOUT,
|
|
5426
|
-
spec: { kinds: ["spacing", "fraction",
|
|
5944
|
+
spec: { kinds: ["spacing", "fraction"], keywords: CONTAINER_KEYS }
|
|
5427
5945
|
},
|
|
5428
5946
|
// caret/accent color values are registered on the color-bearing row above.
|
|
5429
5947
|
{
|
|
@@ -5455,7 +5973,7 @@ var ROOT_GROUPS = [
|
|
|
5455
5973
|
{
|
|
5456
5974
|
roots: ["inline", "block"],
|
|
5457
5975
|
resolvers: SIZING,
|
|
5458
|
-
spec: { kinds: ["spacing", "fraction"] }
|
|
5976
|
+
spec: { kinds: ["spacing", "fraction"], keywords: SIZING_KEYWORDS }
|
|
5459
5977
|
},
|
|
5460
5978
|
// Borders
|
|
5461
5979
|
{
|
|
@@ -5501,6 +6019,14 @@ var ROOT_GROUPS = [
|
|
|
5501
6019
|
{
|
|
5502
6020
|
roots: ["ring"],
|
|
5503
6021
|
resolvers: EFFECTS,
|
|
6022
|
+
spec: OUTER_RING_SPEC
|
|
6023
|
+
},
|
|
6024
|
+
// `ring-offset-*` shares the ring's value space — an integer width or a
|
|
6025
|
+
// colour — but is its own root so the enumerator offers the whole family
|
|
6026
|
+
// rather than leaving it to be spelled through `ring`.
|
|
6027
|
+
{
|
|
6028
|
+
roots: ["ring-offset"],
|
|
6029
|
+
resolvers: EFFECTS,
|
|
5504
6030
|
spec: RING_SPEC
|
|
5505
6031
|
},
|
|
5506
6032
|
{
|
|
@@ -5580,10 +6106,18 @@ var ROOT_GROUPS = [
|
|
|
5580
6106
|
// Statics-only registration for the remaining filter roots — their dynamic
|
|
5581
6107
|
// value spaces (percentages, angles, drop-shadow tokens) are not enumerated.
|
|
5582
6108
|
{
|
|
5583
|
-
roots: ["brightness", "contrast", "saturate", "hue"
|
|
6109
|
+
roots: ["brightness", "contrast", "saturate", "hue"],
|
|
5584
6110
|
resolvers: EFFECTS,
|
|
5585
6111
|
spec: STATICS_ONLY
|
|
5586
6112
|
},
|
|
6113
|
+
{
|
|
6114
|
+
// `drop-shadow-*` dispatches through the bare `drop` root, so its value
|
|
6115
|
+
// carries the `shadow-` segment. Only the two namespace-free spellings
|
|
6116
|
+
// are listed; the named scale comes from the preset's @utility blocks.
|
|
6117
|
+
roots: ["drop"],
|
|
6118
|
+
resolvers: EFFECTS,
|
|
6119
|
+
spec: { kinds: ["keywords"], keywords: ["shadow-none", "shadow-initial"] }
|
|
6120
|
+
},
|
|
5587
6121
|
{
|
|
5588
6122
|
roots: ["mask"],
|
|
5589
6123
|
resolvers: EFFECTS,
|
|
@@ -5601,6 +6135,11 @@ var ROOT_GROUPS = [
|
|
|
5601
6135
|
kinds: ["keywords"],
|
|
5602
6136
|
keywords: [
|
|
5603
6137
|
...SPACING_SAMPLES.flatMap((s) => [`x-${s}`, `y-${s}`, `z-${s}`]),
|
|
6138
|
+
// Every fraction on both axes and the shorthand — the resolver
|
|
6139
|
+
// reads the whole shared FRACTIONAL table, so a spec listing only
|
|
6140
|
+
// `1/2` would under-report the family by 75 names.
|
|
6141
|
+
...FRACTION_KEYS.flatMap((f) => [`x-${f}`, `y-${f}`, f]),
|
|
6142
|
+
"3d",
|
|
5604
6143
|
"x-full",
|
|
5605
6144
|
"y-full",
|
|
5606
6145
|
"x-1/2",
|
|
@@ -6136,6 +6675,12 @@ var PROPERTY_GROUPS = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
|
6136
6675
|
"--ri-inset-shadow-color": 141,
|
|
6137
6676
|
"--ri-ring-color": 141,
|
|
6138
6677
|
"--ri-inset-ring-color": 141,
|
|
6678
|
+
"--ri-ring-offset-color": 141,
|
|
6679
|
+
// Width and flag are read by the ring/offset shadow layers rather than by a
|
|
6680
|
+
// property of their own, so they belong to the same group for the same
|
|
6681
|
+
// reason the slot vars do.
|
|
6682
|
+
"--ri-ring-offset-width": 141,
|
|
6683
|
+
"--ri-ring-inset": 141,
|
|
6139
6684
|
"text-shadow": 141,
|
|
6140
6685
|
"--ri-text-shadow-color": 141,
|
|
6141
6686
|
outline: 142,
|
|
@@ -6216,16 +6761,24 @@ var PROPERTY_GROUPS = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
|
6216
6761
|
"--ri-rotate-z": 160,
|
|
6217
6762
|
"--ri-skew-x": 160,
|
|
6218
6763
|
"--ri-skew-y": 160,
|
|
6219
|
-
translate: 161,
|
|
6220
6764
|
"--ri-translate-x": 161,
|
|
6221
6765
|
"--ri-translate-y": 161,
|
|
6222
6766
|
"--ri-translate-z": 161,
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6767
|
+
// The whole-property `translate` sorts AFTER the axis variables, not with
|
|
6768
|
+
// them. `translate-none` and `translate-3d` are the only utilities whose
|
|
6769
|
+
// first declaration is the shorthand, and both are meant to win over an axis
|
|
6770
|
+
// utility beside them — a reset that loses to `translate-x-4` resets nothing,
|
|
6771
|
+
// and `translate-3d` exists precisely to re-emit the shorthand with the Z
|
|
6772
|
+
// axis in it. Sharing 161 left the codepoint tie-break to decide, and it put
|
|
6773
|
+
// `.translate-3d` and `.translate-none` first, so both were inert.
|
|
6774
|
+
// Tailwind orders them last for the same reason.
|
|
6775
|
+
translate: 162,
|
|
6776
|
+
rotate: 163,
|
|
6777
|
+
scale: 164,
|
|
6778
|
+
"--ri-scale-x": 164,
|
|
6779
|
+
"--ri-scale-y": 164,
|
|
6780
|
+
"--ri-scale-z": 164,
|
|
6781
|
+
zoom: 165,
|
|
6229
6782
|
// Transition / Animation
|
|
6230
6783
|
transition: 170,
|
|
6231
6784
|
"transition-property": 171,
|
|
@@ -6868,6 +7421,11 @@ function compileUtility(parsed, theme, result, customVariantMap, warnSeen, break
|
|
|
6868
7421
|
}
|
|
6869
7422
|
const utilResult = resolveUtilityDeclarations(parsed, theme, result.warnings);
|
|
6870
7423
|
if (!utilResult) {
|
|
7424
|
+
if (detail && parsed.raw === parsed.utility && isMarkerUtility(parsed.utility)) {
|
|
7425
|
+
detail.reason = "marker";
|
|
7426
|
+
detail.declarations = [];
|
|
7427
|
+
return null;
|
|
7428
|
+
}
|
|
6871
7429
|
if (detail) detail.reason = "unknown-utility";
|
|
6872
7430
|
return null;
|
|
6873
7431
|
}
|
|
@@ -6913,43 +7471,51 @@ function compileUtility(parsed, theme, result, customVariantMap, warnSeen, break
|
|
|
6913
7471
|
if (!wrappers) wrappers = [];
|
|
6914
7472
|
wrappers.push(wrapper);
|
|
6915
7473
|
}
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
const applied = applyVariantWrappers(selector, wrappers);
|
|
6921
|
-
selector = applied.selector;
|
|
6922
|
-
for (const atRule of applied.atRules) {
|
|
7474
|
+
const renderBranch = (branch) => {
|
|
7475
|
+
let atRuleOpen = "";
|
|
7476
|
+
let atRuleClose = "";
|
|
7477
|
+
for (const atRule of branch.atRules) {
|
|
6923
7478
|
atRuleOpen += `${atRule} {
|
|
6924
7479
|
`;
|
|
6925
7480
|
atRuleClose = `}
|
|
6926
7481
|
${atRuleClose}`;
|
|
6927
7482
|
}
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
const indentedDecls = declCSS.replace(/\n/g, "\n ");
|
|
6933
|
-
css = `${selector} {
|
|
7483
|
+
let out;
|
|
7484
|
+
if (branch.startingStyle) {
|
|
7485
|
+
const indentedDecls = declCSS.replace(/\n/g, "\n ");
|
|
7486
|
+
out = `${branch.selector} {
|
|
6934
7487
|
@starting-style {
|
|
6935
7488
|
${indentedDecls}
|
|
6936
7489
|
}
|
|
6937
7490
|
}`;
|
|
6938
|
-
|
|
6939
|
-
|
|
7491
|
+
} else {
|
|
7492
|
+
out = `${branch.selector} {
|
|
6940
7493
|
${declCSS}
|
|
6941
7494
|
}`;
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
7495
|
+
}
|
|
7496
|
+
return atRuleOpen ? `${atRuleOpen}${out}
|
|
7497
|
+
${atRuleClose}` : out;
|
|
7498
|
+
};
|
|
7499
|
+
let css;
|
|
7500
|
+
if (wrappers) {
|
|
7501
|
+
const branches = applyVariantWrappers(selector, wrappers);
|
|
7502
|
+
selector = branches[0].selector;
|
|
7503
|
+
css = branches.map(renderBranch).join("\n\n");
|
|
7504
|
+
} else {
|
|
7505
|
+
css = renderBranch({ selector, atRules: [], startingStyle: false });
|
|
6946
7506
|
}
|
|
6947
7507
|
const cssProperty = utilResult.declarations[0]?.property || "";
|
|
6948
7508
|
const sortKey = computeSortKey(cssProperty, parsed.variants, breakpointWeights);
|
|
6949
7509
|
return { selector, sortKey, css };
|
|
6950
7510
|
}
|
|
7511
|
+
function indentBlock(body) {
|
|
7512
|
+
return body.split("\n").map((line) => line.trim() === "" ? "" : ` ${line}`).join("\n");
|
|
7513
|
+
}
|
|
6951
7514
|
function scanStringForTokenUsage(str, result) {
|
|
6952
7515
|
if (str.includes("var(--color-")) {
|
|
7516
|
+
for (const m of str.matchAll(COLOR_VAR_REF_RE)) {
|
|
7517
|
+
result.usedColorNames.add(m[1]);
|
|
7518
|
+
}
|
|
6953
7519
|
for (const m of str.matchAll(COLOR_STOP_REF_RE)) {
|
|
6954
7520
|
const hue = m[1];
|
|
6955
7521
|
const suffix = m[2] ? Number(m[2]) : void 0;
|
|
@@ -7021,6 +7587,7 @@ function createEmptyCompilationResult() {
|
|
|
7021
7587
|
keyframes: [],
|
|
7022
7588
|
properties: [],
|
|
7023
7589
|
usedColorStops: /* @__PURE__ */ new Map(),
|
|
7590
|
+
usedColorNames: /* @__PURE__ */ new Set(),
|
|
7024
7591
|
usedTextSizes: /* @__PURE__ */ new Set(),
|
|
7025
7592
|
usedFonts: /* @__PURE__ */ new Set(),
|
|
7026
7593
|
usedShadows: /* @__PURE__ */ new Set(),
|
|
@@ -7063,6 +7630,7 @@ function compileClassEntry(raw, theme, customVariantMap, breakpointWeights, vari
|
|
|
7063
7630
|
warnings: scratch.warnings,
|
|
7064
7631
|
arbitraryWarning,
|
|
7065
7632
|
usedColorStops: scratch.usedColorStops,
|
|
7633
|
+
usedColorNames: scratch.usedColorNames,
|
|
7066
7634
|
usedTextSizes: scratch.usedTextSizes,
|
|
7067
7635
|
usedFonts: scratch.usedFonts,
|
|
7068
7636
|
usedShadows: scratch.usedShadows,
|
|
@@ -7148,6 +7716,7 @@ function compileInternal(classNames, theme, variantMapCache, authored) {
|
|
|
7148
7716
|
}
|
|
7149
7717
|
for (const stop of stops) set.add(stop);
|
|
7150
7718
|
}
|
|
7719
|
+
for (const v of entry.usedColorNames) result.usedColorNames.add(v);
|
|
7151
7720
|
for (const v of entry.usedTextSizes) result.usedTextSizes.add(v);
|
|
7152
7721
|
for (const v of entry.usedFonts) result.usedFonts.add(v);
|
|
7153
7722
|
for (const v of entry.usedShadows) result.usedShadows.add(v);
|
|
@@ -7181,7 +7750,7 @@ function compileInternal(classNames, theme, variantMapCache, authored) {
|
|
|
7181
7750
|
for (const [name, def] of Object.entries(theme.animations)) {
|
|
7182
7751
|
if (def.keyframes && animationBases.has(`animate-${name}`)) {
|
|
7183
7752
|
result.keyframes.push(`@keyframes ${name} {
|
|
7184
|
-
|
|
7753
|
+
${indentBlock(def.keyframes)}
|
|
7185
7754
|
}`);
|
|
7186
7755
|
}
|
|
7187
7756
|
}
|
|
@@ -7360,19 +7929,26 @@ function readURLImportTarget(src, start) {
|
|
|
7360
7929
|
if (src[i] === ")") i++;
|
|
7361
7930
|
return { target: target || null, nextIndex: i };
|
|
7362
7931
|
}
|
|
7363
|
-
function
|
|
7932
|
+
function readImportTarget(src, paramsStart) {
|
|
7364
7933
|
let i = paramsStart;
|
|
7365
7934
|
while (i < src.length && WS_RE2.test(src[i])) i++;
|
|
7366
|
-
if (i >= src.length) return null;
|
|
7935
|
+
if (i >= src.length) return { target: null, nextIndex: i };
|
|
7367
7936
|
if (src[i] === '"' || src[i] === "'") {
|
|
7368
|
-
return readQuotedImportTarget(src, i)
|
|
7937
|
+
return readQuotedImportTarget(src, i);
|
|
7369
7938
|
}
|
|
7370
|
-
return readURLImportTarget(src, i)
|
|
7939
|
+
return readURLImportTarget(src, i);
|
|
7371
7940
|
}
|
|
7372
|
-
|
|
7941
|
+
function scanImportTarget(src, paramsStart) {
|
|
7942
|
+
return readImportTarget(src, paramsStart).target;
|
|
7943
|
+
}
|
|
7944
|
+
var RI_MARKER_IMPORT_SPECIFIERS = Object.freeze([
|
|
7373
7945
|
"rainbowindex",
|
|
7374
7946
|
"rainbowindex/index.css"
|
|
7375
7947
|
]);
|
|
7948
|
+
var RI_IMPORT_SPECIFIERS = Object.freeze([
|
|
7949
|
+
...RI_MARKER_IMPORT_SPECIFIERS,
|
|
7950
|
+
"rainbowindex/tailwind.css"
|
|
7951
|
+
]);
|
|
7376
7952
|
var RI_IMPORT_SPECIFIER_ALTERNATION = RI_IMPORT_SPECIFIERS.map(
|
|
7377
7953
|
(s) => s.replace(/[/\\^$.*+?()[\]{}|]/g, "\\$&")
|
|
7378
7954
|
).join("|");
|
|
@@ -7479,9 +8055,15 @@ function splitColorAlpha(side) {
|
|
|
7479
8055
|
}
|
|
7480
8056
|
return { base: side, alpha: null };
|
|
7481
8057
|
}
|
|
7482
|
-
|
|
8058
|
+
var COLOR_KEYWORDS = /* @__PURE__ */ new Set(["transparent", "currentColor", "inherit"]);
|
|
8059
|
+
function expandBareColorRef(v) {
|
|
8060
|
+
if (COLOR_KEYWORDS.has(v)) return v;
|
|
8061
|
+
return /^[\w-]+$/.test(v) ? `var(--color-${v})` : v;
|
|
8062
|
+
}
|
|
8063
|
+
function expandColorSide(side, bareNames = false) {
|
|
7483
8064
|
const { base, alpha } = splitColorAlpha(side);
|
|
7484
|
-
const
|
|
8065
|
+
const stop = expandColorStopRef(base);
|
|
8066
|
+
const expanded = stop !== base || !(bareNames || alpha !== null) ? stop : expandBareColorRef(base);
|
|
7485
8067
|
if (alpha === null) return expanded;
|
|
7486
8068
|
const isPercent = alpha.endsWith("%");
|
|
7487
8069
|
const num = Number.parseFloat(isPercent ? alpha.slice(0, -1) : alpha);
|
|
@@ -7496,15 +8078,26 @@ function parseColorBody(body, warnings) {
|
|
|
7496
8078
|
for (const entry of scanEntries(cleanedBody, { newlineTerminates: true })) {
|
|
7497
8079
|
if (entry.removal) {
|
|
7498
8080
|
removals.push(entry.key);
|
|
8081
|
+
if (entry.legacyRemoval) {
|
|
8082
|
+
warnings?.push(legacySyntaxWarning(`!${entry.key};`, `${entry.key}: initial;`, "color"));
|
|
8083
|
+
}
|
|
7499
8084
|
continue;
|
|
7500
8085
|
}
|
|
8086
|
+
let { key, value } = entry;
|
|
8087
|
+
let darkBlockOverride = null;
|
|
7501
8088
|
if (entry.fragment) {
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
8089
|
+
if (entry.block === void 0) {
|
|
8090
|
+
warnings?.push(
|
|
8091
|
+
`[RI-1035] Invalid @color key "${entry.value}" \u2014 color names may only contain letters, numbers, hyphens, and underscores. The entry was skipped.`
|
|
8092
|
+
);
|
|
8093
|
+
continue;
|
|
8094
|
+
}
|
|
8095
|
+
const nested = readNestedColorEntry(entry.value, entry.block, warnings);
|
|
8096
|
+
if (nested === null) continue;
|
|
8097
|
+
key = entry.value;
|
|
8098
|
+
value = nested.value;
|
|
8099
|
+
darkBlockOverride = nested.options;
|
|
7506
8100
|
}
|
|
7507
|
-
const { key, value } = entry;
|
|
7508
8101
|
if (!key || !value) continue;
|
|
7509
8102
|
if (colorCount >= MAX_COLOR_ENTRIES) {
|
|
7510
8103
|
warnings?.push(
|
|
@@ -7518,7 +8111,16 @@ function parseColorBody(body, warnings) {
|
|
|
7518
8111
|
);
|
|
7519
8112
|
continue;
|
|
7520
8113
|
}
|
|
7521
|
-
const darkBlock = entry.block ?? null;
|
|
8114
|
+
const darkBlock = darkBlockOverride ?? entry.block ?? null;
|
|
8115
|
+
if (darkBlockOverride === null && entry.block !== void 0) {
|
|
8116
|
+
warnings?.push(
|
|
8117
|
+
legacySyntaxWarning(
|
|
8118
|
+
`${key}: <value> { \u2026 }`,
|
|
8119
|
+
`${key} { ${isGenerativeValue(value) ? "ramp" : "value"}: <value>; \u2026 }`,
|
|
8120
|
+
"color"
|
|
8121
|
+
)
|
|
8122
|
+
);
|
|
8123
|
+
}
|
|
7522
8124
|
let darkOverride;
|
|
7523
8125
|
let hasInline = false;
|
|
7524
8126
|
let hasParabolic;
|
|
@@ -7529,9 +8131,16 @@ function parseColorBody(body, warnings) {
|
|
|
7529
8131
|
const colonIdx = stmt.indexOf(":");
|
|
7530
8132
|
if (colonIdx === -1) {
|
|
7531
8133
|
for (const flag of stmt.split(/\s+/)) {
|
|
7532
|
-
if (flag === "inline")
|
|
7533
|
-
|
|
7534
|
-
|
|
8134
|
+
if (flag === "inline") {
|
|
8135
|
+
hasInline = true;
|
|
8136
|
+
warnings?.push(legacySyntaxWarning("inline;", "inline: true;", "color"));
|
|
8137
|
+
} else if (flag === "parabolic") {
|
|
8138
|
+
hasParabolic = true;
|
|
8139
|
+
warnings?.push(legacySyntaxWarning("parabolic;", "parabolic: true;", "color"));
|
|
8140
|
+
} else if (flag === "no-parabolic") {
|
|
8141
|
+
hasParabolic = false;
|
|
8142
|
+
warnings?.push(legacySyntaxWarning("no-parabolic;", "parabolic: false;", "color"));
|
|
8143
|
+
}
|
|
7535
8144
|
}
|
|
7536
8145
|
continue;
|
|
7537
8146
|
}
|
|
@@ -7539,9 +8148,9 @@ function parseColorBody(body, warnings) {
|
|
|
7539
8148
|
const optVal = stmt.slice(colonIdx + 1).trim();
|
|
7540
8149
|
if (optKey === "dark") {
|
|
7541
8150
|
darkOverride = parseDarkOverrideValue(optVal);
|
|
7542
|
-
} else if (optKey === "--ri-inline") {
|
|
8151
|
+
} else if (optKey === "inline" || optKey === "--ri-inline") {
|
|
7543
8152
|
if (optVal === "true") hasInline = true;
|
|
7544
|
-
} else if (optKey === "--ri-parabolic") {
|
|
8153
|
+
} else if (optKey === "parabolic" || optKey === "--ri-parabolic") {
|
|
7545
8154
|
if (optVal === "true") hasParabolic = true;
|
|
7546
8155
|
else if (optVal === "false") hasParabolic = false;
|
|
7547
8156
|
}
|
|
@@ -7563,19 +8172,44 @@ function parseColorBody(body, warnings) {
|
|
|
7563
8172
|
}
|
|
7564
8173
|
return { colors, removals };
|
|
7565
8174
|
}
|
|
8175
|
+
function isGenerativeValue(value) {
|
|
8176
|
+
return /^-?[\d.]+\s+-?[\d.]+$/.test(value.trim());
|
|
8177
|
+
}
|
|
8178
|
+
function readNestedColorEntry(name, block, warnings) {
|
|
8179
|
+
let value = null;
|
|
8180
|
+
const options = [];
|
|
8181
|
+
for (const statement of block.split(";")) {
|
|
8182
|
+
const stmt = statement.trim();
|
|
8183
|
+
if (!stmt) continue;
|
|
8184
|
+
const colon = stmt.indexOf(":");
|
|
8185
|
+
const key = colon === -1 ? "" : stmt.slice(0, colon).trim();
|
|
8186
|
+
if (key === "ramp" || key === "value") {
|
|
8187
|
+
value = stmt.slice(colon + 1).trim();
|
|
8188
|
+
continue;
|
|
8189
|
+
}
|
|
8190
|
+
options.push(stmt);
|
|
8191
|
+
}
|
|
8192
|
+
if (value === null || value === "") {
|
|
8193
|
+
warnings?.push(
|
|
8194
|
+
`[RI-1126] @color entry "${name}" has a block but no \`ramp:\` or \`value:\` declaration, so it defines no colour. Write \`${name} { ramp: <chroma> <hue>; }\` or \`${name} { value: oklch(\u2026); }\`.`
|
|
8195
|
+
);
|
|
8196
|
+
return null;
|
|
8197
|
+
}
|
|
8198
|
+
return { value, options: options.join("; ") };
|
|
8199
|
+
}
|
|
7566
8200
|
function parseColorValue(key, value, warnings) {
|
|
7567
8201
|
const slashIdx = findPairSeparator(value);
|
|
7568
8202
|
if (slashIdx !== -1) {
|
|
7569
|
-
const light = expandColorSide(value.slice(0, slashIdx).trim());
|
|
7570
|
-
const dark = expandColorSide(value.slice(slashIdx + 1).trim());
|
|
8203
|
+
const light = expandColorSide(value.slice(0, slashIdx).trim(), true);
|
|
8204
|
+
const dark = expandColorSide(value.slice(slashIdx + 1).trim(), true);
|
|
7571
8205
|
return { type: "pair", light, dark };
|
|
7572
8206
|
}
|
|
7573
8207
|
if (/^light-dark\s*\(/.test(value)) {
|
|
7574
8208
|
const inner = value.slice(value.indexOf("(") + 1, value.lastIndexOf(")")).trim();
|
|
7575
8209
|
const commaIdx = topLevelIndexOf(inner, ",");
|
|
7576
8210
|
if (commaIdx !== -1) {
|
|
7577
|
-
const light = expandColorSide(inner.slice(0, commaIdx).trim());
|
|
7578
|
-
const dark = expandColorSide(inner.slice(commaIdx + 1).trim());
|
|
8211
|
+
const light = expandColorSide(inner.slice(0, commaIdx).trim(), true);
|
|
8212
|
+
const dark = expandColorSide(inner.slice(commaIdx + 1).trim(), true);
|
|
7579
8213
|
return { type: "pair", light, dark };
|
|
7580
8214
|
}
|
|
7581
8215
|
}
|
|
@@ -7847,6 +8481,10 @@ function applyFaceOptions(face, entries, slot, warnings) {
|
|
|
7847
8481
|
}
|
|
7848
8482
|
}
|
|
7849
8483
|
}
|
|
8484
|
+
function unwrapURL(value) {
|
|
8485
|
+
const match = /^url\(\s*(.*?)\s*\)$/i.exec(value.trim());
|
|
8486
|
+
return stripQuotes(match ? match[1] : value);
|
|
8487
|
+
}
|
|
7850
8488
|
var LEGACY_METRICS_KEYS = /* @__PURE__ */ new Set([
|
|
7851
8489
|
"metricsFallback",
|
|
7852
8490
|
"sizeAdjust",
|
|
@@ -7864,6 +8502,22 @@ function parseSlotBody(body, slot, warnings) {
|
|
|
7864
8502
|
continue;
|
|
7865
8503
|
}
|
|
7866
8504
|
if (entry.fragment) {
|
|
8505
|
+
if (entry.value === "face" && entry.block !== void 0) {
|
|
8506
|
+
let src = "";
|
|
8507
|
+
const own = [];
|
|
8508
|
+
for (const [k, v] of parseKeyValueBody(entry.block, warnings, "font").entries) {
|
|
8509
|
+
if (k === "src") src = unwrapURL(v);
|
|
8510
|
+
else own.push([k, v]);
|
|
8511
|
+
}
|
|
8512
|
+
if (src === "") {
|
|
8513
|
+
warnings?.push(
|
|
8514
|
+
`[RI-1217] @font slot "${slot}" has a \`face { \u2026 }\` block with no \`src:\` \u2014 write \`face { src: url("/fonts/\u2026"); }\`. The entry was ignored.`
|
|
8515
|
+
);
|
|
8516
|
+
} else {
|
|
8517
|
+
out.faces.push({ src, entries: own });
|
|
8518
|
+
}
|
|
8519
|
+
continue;
|
|
8520
|
+
}
|
|
7867
8521
|
if (entry.value === "@face" && entry.block !== void 0) {
|
|
7868
8522
|
warnDeprecated(warnings, slot, "`@face { src: \u2026; }`", "use `face: <src> { \u2026 }`");
|
|
7869
8523
|
let src = "";
|
|
@@ -8092,11 +8746,45 @@ function buildSlot(slot, preambleText, blockBody, warnings) {
|
|
|
8092
8746
|
}
|
|
8093
8747
|
return config;
|
|
8094
8748
|
}
|
|
8749
|
+
function readNestedSlot(slot, block, warnings) {
|
|
8750
|
+
let family = null;
|
|
8751
|
+
let from = null;
|
|
8752
|
+
const rest = [];
|
|
8753
|
+
for (const entry of scanEntries(stripCSSComments(block), { newlineTerminates: false })) {
|
|
8754
|
+
if (entry.block === void 0 && entry.key === "family") {
|
|
8755
|
+
family = entry.value;
|
|
8756
|
+
continue;
|
|
8757
|
+
}
|
|
8758
|
+
if (entry.block === void 0 && entry.key === "from") {
|
|
8759
|
+
from = entry.value;
|
|
8760
|
+
continue;
|
|
8761
|
+
}
|
|
8762
|
+
rest.push(block.slice(entry.start, entry.end).trim());
|
|
8763
|
+
}
|
|
8764
|
+
if (family === null || family === "") {
|
|
8765
|
+
warnings?.push(
|
|
8766
|
+
`[RI-1221] @font slot "${slot}" has a block but no \`family:\` declaration, so it names no font. Write \`${slot} { family: "<Family>", <fallback>; }\` \u2014 or \`family: system;\` for the system stack.`
|
|
8767
|
+
);
|
|
8768
|
+
return null;
|
|
8769
|
+
}
|
|
8770
|
+
return {
|
|
8771
|
+
preamble: from === null ? family : `${family} from ${from}`,
|
|
8772
|
+
body: rest.join("\n")
|
|
8773
|
+
};
|
|
8774
|
+
}
|
|
8095
8775
|
function parseNestedFontBlock(body, warnings) {
|
|
8096
8776
|
const cleanedBody = stripCSSComments(body);
|
|
8097
8777
|
const configs = [];
|
|
8098
8778
|
for (const entry of scanEntries(cleanedBody, { newlineTerminates: false })) {
|
|
8099
|
-
if (entry.removal
|
|
8779
|
+
if (entry.removal) continue;
|
|
8780
|
+
if (entry.fragment) {
|
|
8781
|
+
if (entry.block === void 0) continue;
|
|
8782
|
+
const nested = readNestedSlot(entry.value, entry.block, warnings);
|
|
8783
|
+
if (nested !== null) {
|
|
8784
|
+
configs.push(buildSlot(entry.value, nested.preamble, nested.body, warnings));
|
|
8785
|
+
}
|
|
8786
|
+
continue;
|
|
8787
|
+
}
|
|
8100
8788
|
if (entry.unclosedBlock) break;
|
|
8101
8789
|
if (!entry.key) continue;
|
|
8102
8790
|
if (configs.length >= MAX_FONT_CONFIGS) {
|
|
@@ -8106,6 +8794,13 @@ function parseNestedFontBlock(body, warnings) {
|
|
|
8106
8794
|
break;
|
|
8107
8795
|
}
|
|
8108
8796
|
if (entry.block !== void 0) {
|
|
8797
|
+
warnings?.push(
|
|
8798
|
+
legacySyntaxWarning(
|
|
8799
|
+
`${entry.key}: <family> { \u2026 }`,
|
|
8800
|
+
`${entry.key} { family: <family>; \u2026 }`,
|
|
8801
|
+
"font"
|
|
8802
|
+
)
|
|
8803
|
+
);
|
|
8109
8804
|
configs.push(buildSlot(entry.key, entry.value, entry.block, warnings));
|
|
8110
8805
|
} else if (entry.value) {
|
|
8111
8806
|
configs.push(buildSlot(entry.key, entry.value, void 0, warnings));
|
|
@@ -8145,23 +8840,122 @@ function parseSpacingBody(body) {
|
|
|
8145
8840
|
base
|
|
8146
8841
|
};
|
|
8147
8842
|
}
|
|
8148
|
-
function parseAnimateBody(body) {
|
|
8843
|
+
function parseAnimateBody(body, warnings) {
|
|
8149
8844
|
const animations = {};
|
|
8150
8845
|
const removals = [];
|
|
8151
8846
|
const cleaned = stripCSSComments(body);
|
|
8152
8847
|
for (const entry of scanEntries(cleaned, { newlineTerminates: false })) {
|
|
8153
8848
|
if (entry.removal) {
|
|
8154
8849
|
removals.push(entry.key);
|
|
8850
|
+
if (entry.legacyRemoval) {
|
|
8851
|
+
warnings?.push(legacySyntaxWarning(`!${entry.key};`, `${entry.key}: initial;`, "animate"));
|
|
8852
|
+
}
|
|
8155
8853
|
continue;
|
|
8156
8854
|
}
|
|
8157
8855
|
if (entry.block === void 0) continue;
|
|
8856
|
+
if (entry.fragment) {
|
|
8857
|
+
const parsed = parseNestedAnimation(entry.value, entry.block, warnings);
|
|
8858
|
+
if (parsed !== null) animations[entry.value] = parsed;
|
|
8859
|
+
continue;
|
|
8860
|
+
}
|
|
8158
8861
|
if (!IDENT_KEY_RE.test(entry.key)) continue;
|
|
8159
|
-
|
|
8862
|
+
warnings?.push(
|
|
8863
|
+
legacySyntaxWarning(
|
|
8864
|
+
`${entry.key}: <animation> { \u2026 }`,
|
|
8865
|
+
`${entry.key} { animation: <animation>; @keyframes ${entry.key} { \u2026 } }`,
|
|
8866
|
+
"animate"
|
|
8867
|
+
)
|
|
8868
|
+
);
|
|
8869
|
+
animations[entry.key] = {
|
|
8870
|
+
shorthand: entry.value,
|
|
8871
|
+
keyframes: normalizeKeyframes(entry.block)
|
|
8872
|
+
};
|
|
8873
|
+
}
|
|
8874
|
+
for (const [name, definition] of Object.entries(animations)) {
|
|
8875
|
+
if (definition.shorthand.split(/\s+/).includes(name)) continue;
|
|
8876
|
+
warnings?.push(
|
|
8877
|
+
`[RI-1049] @animate entry "${name}" has the shorthand "${definition.shorthand}", which never names "${name}" \u2014 so \`animate-${name}\` sets no animation-name and the keyframes never run. Write \`${name} ${definition.shorthand}\`.`
|
|
8878
|
+
);
|
|
8160
8879
|
}
|
|
8161
8880
|
return { animations, removals };
|
|
8162
8881
|
}
|
|
8163
|
-
function
|
|
8164
|
-
|
|
8882
|
+
function parseNestedAnimation(name, block, warnings) {
|
|
8883
|
+
if (!IDENT_KEY_RE.test(name)) return null;
|
|
8884
|
+
let shorthand = "";
|
|
8885
|
+
let keyframes = null;
|
|
8886
|
+
let keyframesName = null;
|
|
8887
|
+
let rest = "";
|
|
8888
|
+
let at = 0;
|
|
8889
|
+
const cleaned = stripCSSComments(block);
|
|
8890
|
+
for (const rule of scanTopLevelAtRules(cleaned)) {
|
|
8891
|
+
rest += cleaned.slice(at, rule.start);
|
|
8892
|
+
at = rule.end;
|
|
8893
|
+
if (rule.name !== "keyframes" || rule.body === null) continue;
|
|
8894
|
+
keyframes = rule.body.trim();
|
|
8895
|
+
keyframesName = rule.prelude.trim();
|
|
8896
|
+
}
|
|
8897
|
+
rest += cleaned.slice(at);
|
|
8898
|
+
for (const [key, value] of parseKeyValueBody(rest).entries) {
|
|
8899
|
+
if (key === "animation") shorthand = value;
|
|
8900
|
+
}
|
|
8901
|
+
if (keyframes === null) {
|
|
8902
|
+
warnings?.push(
|
|
8903
|
+
`[RI-1047] @animate entry "${name}" has no @keyframes block, so it defines no animation. Add \`@keyframes ${name} { \u2026 }\` inside it \u2014 or, if a custom utility was intended, move the block out of @animate.`
|
|
8904
|
+
);
|
|
8905
|
+
return null;
|
|
8906
|
+
}
|
|
8907
|
+
if (shorthand === "") {
|
|
8908
|
+
warnings?.push(
|
|
8909
|
+
`[RI-1047] @animate entry "${name}" has @keyframes but no \`animation:\` declaration, so nothing says how to run them. Add \`animation: ${keyframesName || name} <duration> <timing> <iteration>;\`.`
|
|
8910
|
+
);
|
|
8911
|
+
return null;
|
|
8912
|
+
}
|
|
8913
|
+
if (keyframesName !== null && keyframesName !== "" && keyframesName !== name) {
|
|
8914
|
+
warnings?.push(
|
|
8915
|
+
`[RI-1048] @animate entry "${name}" holds \`@keyframes ${keyframesName}\`, but the emitted keyframes are named after the entry \u2014 so "${keyframesName}" would never exist. Rename one of them to match. To reuse another entry's keyframes, name them here too.`
|
|
8916
|
+
);
|
|
8917
|
+
return null;
|
|
8918
|
+
}
|
|
8919
|
+
return { shorthand, keyframes: normalizeKeyframes(keyframes) };
|
|
8920
|
+
}
|
|
8921
|
+
function normalizeKeyframes(body) {
|
|
8922
|
+
const lines = body.split("\n");
|
|
8923
|
+
if (lines.length < 2) return body;
|
|
8924
|
+
let common = Number.POSITIVE_INFINITY;
|
|
8925
|
+
for (const line of lines.slice(1)) {
|
|
8926
|
+
if (line.trim() === "") continue;
|
|
8927
|
+
common = Math.min(common, line.length - line.trimStart().length);
|
|
8928
|
+
}
|
|
8929
|
+
if (!Number.isFinite(common) || common === 0) return body;
|
|
8930
|
+
return [lines[0], ...lines.slice(1).map((line) => line.slice(common))].join("\n");
|
|
8931
|
+
}
|
|
8932
|
+
function scanTopLevelAtRules(css) {
|
|
8933
|
+
const out = [];
|
|
8934
|
+
for (let i = 0; i < css.length; i++) {
|
|
8935
|
+
if (css[i] !== "@") continue;
|
|
8936
|
+
let nameEnd = i + 1;
|
|
8937
|
+
while (nameEnd < css.length && /[\w-]/.test(css[nameEnd])) nameEnd++;
|
|
8938
|
+
const name = css.slice(i + 1, nameEnd);
|
|
8939
|
+
if (!name) continue;
|
|
8940
|
+
let j = nameEnd;
|
|
8941
|
+
while (j < css.length && css[j] !== "{" && css[j] !== ";") j++;
|
|
8942
|
+
if (j >= css.length) break;
|
|
8943
|
+
const prelude = css.slice(nameEnd, j).trim();
|
|
8944
|
+
if (css[j] === ";") {
|
|
8945
|
+
out.push({ name, prelude, body: null, start: i, end: j + 1 });
|
|
8946
|
+
i = j;
|
|
8947
|
+
continue;
|
|
8948
|
+
}
|
|
8949
|
+
const close = findClosingBrace(css, j);
|
|
8950
|
+
if (close === -1) break;
|
|
8951
|
+
out.push({ name, prelude, body: css.slice(j + 1, close), start: i, end: close + 1 });
|
|
8952
|
+
i = close;
|
|
8953
|
+
}
|
|
8954
|
+
return out;
|
|
8955
|
+
}
|
|
8956
|
+
var DEAD_FLUID_KEYWORDS = /* @__PURE__ */ new Set(["parabolic", "no-parabolic", "shift", "no-shift"]);
|
|
8957
|
+
function parseFluidBody(body, warnings) {
|
|
8958
|
+
const { entries } = parseKeyValueBody(body, warnings, "fluid");
|
|
8165
8959
|
const result = {};
|
|
8166
8960
|
for (const [key, value] of entries) {
|
|
8167
8961
|
if (key === "min") result.min = value;
|
|
@@ -8169,6 +8963,16 @@ function parseFluidBody(body) {
|
|
|
8169
8963
|
if (key === "unit") result.unit = value;
|
|
8170
8964
|
if (key === "multiplier") result.multiplier = value;
|
|
8171
8965
|
}
|
|
8966
|
+
if (warnings) {
|
|
8967
|
+
for (const statement of stripCSSComments(body).split(/[;\n]/)) {
|
|
8968
|
+
const word = statement.trim();
|
|
8969
|
+
if (DEAD_FLUID_KEYWORDS.has(word)) {
|
|
8970
|
+
warnings.push(
|
|
8971
|
+
`[RI-1046] \`${word};\` in @fluid is a deprecated spelling that never had an effect \u2014 @fluid takes min, max, unit and multiplier, and nothing else. Delete it. The bare keyword is not valid CSS, so a formatter cannot read the file.`
|
|
8972
|
+
);
|
|
8973
|
+
}
|
|
8974
|
+
}
|
|
8975
|
+
}
|
|
8172
8976
|
return result;
|
|
8173
8977
|
}
|
|
8174
8978
|
function parsePreflightDirective(body, modifier, base) {
|
|
@@ -8231,12 +9035,19 @@ function parseUtilityDirective(body, modifier, warnings) {
|
|
|
8231
9035
|
if (!isValidUtilityName(name, warnings)) return null;
|
|
8232
9036
|
return { name, functional, body: normalizedBody };
|
|
8233
9037
|
}
|
|
9038
|
+
var ANIMATION_DECL_RE = /(^|[;{\s])animation(?:-name)?\s*:/;
|
|
8234
9039
|
function extractUtilityBlocks(body, prefix, newlineTerminates, warnings) {
|
|
8235
9040
|
const cleaned = stripCSSComments(body);
|
|
8236
9041
|
const utilities = [];
|
|
8237
9042
|
const cuts = [];
|
|
8238
9043
|
for (const entry of scanEntries(cleaned, { newlineTerminates })) {
|
|
8239
9044
|
if (!entry.fragment || entry.block === void 0) continue;
|
|
9045
|
+
if (hasTopLevelKeyframes(entry.block)) continue;
|
|
9046
|
+
if (prefix === "animate" && ANIMATION_DECL_RE.test(entry.block)) {
|
|
9047
|
+
warnings?.push(
|
|
9048
|
+
`[RI-1047] @animate entry "${entry.value}" sets \`animation\` but has no @keyframes block, so it was read as a custom utility named "animate-${entry.value}" and the animation it names is never defined. Add \`@keyframes \u2026 { \u2026 }\` inside the entry, or move the block out of @animate if a utility was intended.`
|
|
9049
|
+
);
|
|
9050
|
+
}
|
|
8240
9051
|
const util = parseUtilityDirective(entry.block, `${prefix}-${entry.value}`, warnings);
|
|
8241
9052
|
if (util) utilities.push(util);
|
|
8242
9053
|
cuts.push([entry.start, entry.end]);
|
|
@@ -8470,7 +9281,11 @@ function mergeWithRemovals(defaults, overrides, removals, warnings, directiveNam
|
|
|
8470
9281
|
for (const key of removals) {
|
|
8471
9282
|
if (!Object.hasOwn(result, key) && warnings) {
|
|
8472
9283
|
warnings.push(
|
|
8473
|
-
|
|
9284
|
+
// Spelling-neutral: three forms produce a removal (`key: initial`,
|
|
9285
|
+
// the deprecated `!key`, and the plugin's `--ri-rm`), and naming
|
|
9286
|
+
// one of them in the message sends a reader looking for text that
|
|
9287
|
+
// is not in their file.
|
|
9288
|
+
`[RI-1103] Invalid removal of "${key}" in @${directiveName ?? "unknown"} \u2014 it does not exist, so there is nothing to remove.`
|
|
8474
9289
|
);
|
|
8475
9290
|
}
|
|
8476
9291
|
delete result[key];
|
|
@@ -8544,6 +9359,19 @@ function applyFluidDirective(target, parsed, directiveName, warnings, options =
|
|
|
8544
9359
|
}
|
|
8545
9360
|
validateFluidRange(target, directiveName, warnings);
|
|
8546
9361
|
}
|
|
9362
|
+
function parseDarkVariant(value, warnings) {
|
|
9363
|
+
if (value === "media") return { kind: "media" };
|
|
9364
|
+
if (value === "appearance") return { kind: "appearance" };
|
|
9365
|
+
const selector = /^selector\s*\((.*)\)$/s.exec(value);
|
|
9366
|
+
if (selector) {
|
|
9367
|
+
const inner = selector[1].trim();
|
|
9368
|
+
if (inner) return { kind: "selector", selector: inner };
|
|
9369
|
+
}
|
|
9370
|
+
warnings.push(
|
|
9371
|
+
`[RI-1111] Invalid @color dark variant "${value}" \u2014 expected "media", "appearance", or "selector(<sel>)", as in "selector(.dark)".`
|
|
9372
|
+
);
|
|
9373
|
+
return null;
|
|
9374
|
+
}
|
|
8547
9375
|
function validateColorAliases(theme) {
|
|
8548
9376
|
for (const [name, def] of Object.entries(theme.colors)) {
|
|
8549
9377
|
if (def.type !== "alias") continue;
|
|
@@ -8567,11 +9395,26 @@ function validateColorAliases(theme) {
|
|
|
8567
9395
|
}
|
|
8568
9396
|
}
|
|
8569
9397
|
}
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
9398
|
+
function validateGenerativeColorRefs(theme) {
|
|
9399
|
+
for (const [name, def] of Object.entries(theme.colors)) {
|
|
9400
|
+
const values = def.type === "explicit" ? [def.value] : def.type === "pair" ? [def.light, def.dark] : [];
|
|
9401
|
+
for (const value of values) {
|
|
9402
|
+
for (const match of value.matchAll(BARE_COLOR_VAR_RE)) {
|
|
9403
|
+
const referenced = theme.colors[match[1]];
|
|
9404
|
+
if (referenced?.type !== "generative") continue;
|
|
9405
|
+
theme.warnings.push(
|
|
9406
|
+
`[RI-1109] @color "${name}" references "${match[1]}" with no stop. "${match[1]}" is a generative palette, which defines --color-${match[1]}-<stop> and no bare --color-${match[1]}. Name a stop, as in "${match[1]}-500".`
|
|
9407
|
+
);
|
|
9408
|
+
}
|
|
9409
|
+
}
|
|
9410
|
+
}
|
|
9411
|
+
}
|
|
9412
|
+
var BARE_COLOR_VAR_RE = /var\(--color-([a-z][\w-]*?)\s*[,)]/gi;
|
|
9413
|
+
var SHADOW_ALIAS_RE = /^shadow-([a-z0-9]+(?:-[a-z0-9]+)*)$/;
|
|
9414
|
+
function resolveShadowAliases(theme) {
|
|
9415
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
9416
|
+
for (const [name, value] of Object.entries(theme.shadows)) {
|
|
9417
|
+
const match = SHADOW_ALIAS_RE.exec(value);
|
|
8575
9418
|
if (match) aliases.set(name, match[1]);
|
|
8576
9419
|
}
|
|
8577
9420
|
for (const [name, target] of aliases) {
|
|
@@ -8768,9 +9611,12 @@ function resolveDirectives(directives, attribution) {
|
|
|
8768
9611
|
} else if (k === "hue-shift") {
|
|
8769
9612
|
const n = Number.parseFloat(v);
|
|
8770
9613
|
if (!Number.isNaN(n)) theme.darkConfig.hueShift = n;
|
|
9614
|
+
} else if (k === "variant") {
|
|
9615
|
+
const strategy = parseDarkVariant(v, theme.warnings);
|
|
9616
|
+
if (strategy) theme.darkConfig.variant = strategy;
|
|
8771
9617
|
} else {
|
|
8772
9618
|
theme.warnings.push(
|
|
8773
|
-
`[RI-1104] Unknown @color dark option "${k}" \u2014 supported: mode, chroma-boost, hue-shift.`
|
|
9619
|
+
`[RI-1104] Unknown @color dark option "${k}" \u2014 supported: mode, chroma-boost, hue-shift, variant.`
|
|
8774
9620
|
);
|
|
8775
9621
|
}
|
|
8776
9622
|
}
|
|
@@ -8842,6 +9688,11 @@ function resolveDirectives(directives, attribution) {
|
|
|
8842
9688
|
})) {
|
|
8843
9689
|
if (entry.removal) {
|
|
8844
9690
|
removals.push(entry.key);
|
|
9691
|
+
if (entry.legacyRemoval) {
|
|
9692
|
+
theme.warnings.push(
|
|
9693
|
+
legacySyntaxWarning(`!${entry.key};`, `${entry.key}: initial;`, "rounded")
|
|
9694
|
+
);
|
|
9695
|
+
}
|
|
8845
9696
|
continue;
|
|
8846
9697
|
}
|
|
8847
9698
|
if (entry.fragment) continue;
|
|
@@ -8906,7 +9757,8 @@ function resolveDirectives(directives, attribution) {
|
|
|
8906
9757
|
case "animate": {
|
|
8907
9758
|
warnIgnoredModifier("animate", directive.modifier, theme.warnings);
|
|
8908
9759
|
const { animations: parsedAnims, removals: animRemovals } = parseAnimateBody(
|
|
8909
|
-
directive.body
|
|
9760
|
+
directive.body,
|
|
9761
|
+
theme.warnings
|
|
8910
9762
|
);
|
|
8911
9763
|
theme.animations = mergeWithRemovals(
|
|
8912
9764
|
theme.animations,
|
|
@@ -8918,7 +9770,7 @@ function resolveDirectives(directives, attribution) {
|
|
|
8918
9770
|
break;
|
|
8919
9771
|
}
|
|
8920
9772
|
case "fluid": {
|
|
8921
|
-
const parsed = parseFluidBody(directive.body);
|
|
9773
|
+
const parsed = parseFluidBody(directive.body, theme.warnings);
|
|
8922
9774
|
const targetName = directive.modifier?.trim();
|
|
8923
9775
|
if (!targetName) {
|
|
8924
9776
|
applyFluidDirective(theme.fluid, parsed, "@fluid", theme.warnings, {
|
|
@@ -9018,6 +9870,7 @@ function resolveDirectives(directives, attribution) {
|
|
|
9018
9870
|
}
|
|
9019
9871
|
}
|
|
9020
9872
|
validateColorAliases(theme);
|
|
9873
|
+
validateGenerativeColorRefs(theme);
|
|
9021
9874
|
resolveShadowAliases(theme);
|
|
9022
9875
|
theme.fonts = dedupeLastWins(
|
|
9023
9876
|
theme.fonts,
|
|
@@ -9320,6 +10173,66 @@ var OutputMap = class {
|
|
|
9320
10173
|
}
|
|
9321
10174
|
};
|
|
9322
10175
|
var BODY_TOKEN_RE = /\S+/g;
|
|
10176
|
+
function normalizeApplyParenGroups(input) {
|
|
10177
|
+
if (!input.includes("(")) return input;
|
|
10178
|
+
let out = null;
|
|
10179
|
+
for (let i = 0; i < input.length; i++) {
|
|
10180
|
+
if (input[i] === "[") {
|
|
10181
|
+
while (i < input.length && input[i] !== "]") i++;
|
|
10182
|
+
continue;
|
|
10183
|
+
}
|
|
10184
|
+
if (input[i] !== "(") continue;
|
|
10185
|
+
if (i < 2 || input[i - 1] !== ":") continue;
|
|
10186
|
+
if (!isGroupSegmentCharCode(input.charCodeAt(i - 2))) continue;
|
|
10187
|
+
const close = matchingParen(input, i);
|
|
10188
|
+
if (close === -1) continue;
|
|
10189
|
+
out ??= [...input];
|
|
10190
|
+
out[i] = "{";
|
|
10191
|
+
out[close] = "}";
|
|
10192
|
+
}
|
|
10193
|
+
return out === null ? input : out.join("");
|
|
10194
|
+
}
|
|
10195
|
+
function matchingParen(input, open) {
|
|
10196
|
+
let depth = 0;
|
|
10197
|
+
for (let i = open; i < input.length; i++) {
|
|
10198
|
+
const ch = input[i];
|
|
10199
|
+
if (ch === "\\") {
|
|
10200
|
+
i++;
|
|
10201
|
+
continue;
|
|
10202
|
+
}
|
|
10203
|
+
if (ch === "'" || ch === '"') {
|
|
10204
|
+
const quote = ch;
|
|
10205
|
+
i++;
|
|
10206
|
+
while (i < input.length && input[i] !== quote) {
|
|
10207
|
+
if (input[i] === "\\") i++;
|
|
10208
|
+
i++;
|
|
10209
|
+
}
|
|
10210
|
+
continue;
|
|
10211
|
+
}
|
|
10212
|
+
if (ch === "[") {
|
|
10213
|
+
while (i < input.length && input[i] !== "]") {
|
|
10214
|
+
if (input[i] === "\\") i++;
|
|
10215
|
+
i++;
|
|
10216
|
+
}
|
|
10217
|
+
continue;
|
|
10218
|
+
}
|
|
10219
|
+
if (ch === "(") depth++;
|
|
10220
|
+
else if (ch === ")") {
|
|
10221
|
+
depth--;
|
|
10222
|
+
if (depth === 0) return i;
|
|
10223
|
+
}
|
|
10224
|
+
}
|
|
10225
|
+
return -1;
|
|
10226
|
+
}
|
|
10227
|
+
var LEGACY_APPLY_GROUP_RE = /[\w@-]+:\{/;
|
|
10228
|
+
function expandApplyBodyGroups(input, warnings, path) {
|
|
10229
|
+
if (LEGACY_APPLY_GROUP_RE.test(input)) {
|
|
10230
|
+
warnings?.push(
|
|
10231
|
+
`[RI-1046] \`@apply variant:{ \u2026 }\`${path ? ` in ${path}` : ""} is a deprecated spelling \u2014 write \`@apply variant:( \u2026 )\` instead. A brace opens a block to every CSS parser, so the old form makes the file unreadable to a formatter; it still works, and will be removed at 1.0.`
|
|
10232
|
+
);
|
|
10233
|
+
}
|
|
10234
|
+
return expandVariantGroups(normalizeApplyParenGroups(input), warnings, path);
|
|
10235
|
+
}
|
|
9323
10236
|
function expandVariantGroups(input, warnings, path) {
|
|
9324
10237
|
return expandVariantGroupsCore(input, warnings, null, path);
|
|
9325
10238
|
}
|
|
@@ -9472,8 +10385,8 @@ function expandVariantGroupsCore(input, warnings, map, path) {
|
|
|
9472
10385
|
return parts.join("");
|
|
9473
10386
|
}
|
|
9474
10387
|
var APPLY_AT_RULE_RE = /@(?:apply|a)\s+/g;
|
|
9475
|
-
function
|
|
9476
|
-
if (!css.includes("{") || !css.includes("@")) return css;
|
|
10388
|
+
function expandGroupsInStylesheet(css, warnings, path) {
|
|
10389
|
+
if (!css.includes("{") && !css.includes("(") || !css.includes("@")) return css;
|
|
9477
10390
|
APPLY_AT_RULE_RE.lastIndex = 0;
|
|
9478
10391
|
let match = APPLY_AT_RULE_RE.exec(css);
|
|
9479
10392
|
if (match === null) return css;
|
|
@@ -9493,8 +10406,8 @@ function expandApplyGroups(css, warnings, path) {
|
|
|
9493
10406
|
i++;
|
|
9494
10407
|
}
|
|
9495
10408
|
const body = css.slice(bodyStart, i);
|
|
9496
|
-
if (body.includes("{")) {
|
|
9497
|
-
const expanded =
|
|
10409
|
+
if (body.includes("{") || body.includes("(")) {
|
|
10410
|
+
const expanded = expandApplyBodyGroups(body, warnings, path);
|
|
9498
10411
|
if (expanded !== body) {
|
|
9499
10412
|
out.push(css.slice(lastEnd, bodyStart));
|
|
9500
10413
|
out.push(expanded);
|
|
@@ -9882,7 +10795,9 @@ var CandidateCollector = class {
|
|
|
9882
10795
|
var BOUNDARY = /(?:^|[\s"'`{;:,=+(|])/.source;
|
|
9883
10796
|
var NEGATIVE = /-?/.source;
|
|
9884
10797
|
var IMPORTANT_SUFFIX = /!?/.source;
|
|
9885
|
-
var
|
|
10798
|
+
var VARIANT_BRACKET = /\[(?:[^[\]]|\[[^\]]*\])*\]/.source;
|
|
10799
|
+
var VARIANT_NAME_SUFFIX = /(?:\/[\w-]+)?/.source;
|
|
10800
|
+
var VARIANT_SEGMENT = `(?:[\\w.@-]+(?:${VARIANT_BRACKET})?|${VARIANT_BRACKET})${VARIANT_NAME_SUFFIX}:`;
|
|
9886
10801
|
var VARIANT_PREFIX = `(?:${VARIANT_SEGMENT})*`;
|
|
9887
10802
|
var UTILITY_VALUE = /[\w.@-]+(?:\[[^\]]*\]|(?<=-)\([^)]*\))?(?:\/(?:[\w.]+|\[[^\]]*\]|\([^)]*--[^)]*\)))?/.source;
|
|
9888
10803
|
var VARIANT_GROUP = /[\w.@-]+:\{[^}]*\}/.source;
|
|
@@ -9901,7 +10816,7 @@ var CLASS_HELPERS = [
|
|
|
9901
10816
|
"twJoin",
|
|
9902
10817
|
"twMerge"
|
|
9903
10818
|
];
|
|
9904
|
-
var VARIANT_HELPERS = ["cva", "tv"];
|
|
10819
|
+
var VARIANT_HELPERS = ["cva", "tv", "recipe"];
|
|
9905
10820
|
var CLASS_HELPER_NAMES = Object.freeze([...CLASS_HELPERS]);
|
|
9906
10821
|
var VARIANT_HELPER_NAMES = Object.freeze([...VARIANT_HELPERS]);
|
|
9907
10822
|
var CLASS_HELPERS_CALL_RE = new RegExp(`\\b(?:${CLASS_HELPERS.join("|")})\\s*\\(`, "g");
|
|
@@ -9910,8 +10825,9 @@ var CLASS_MAP_CALL_RE = /\bclassMap\s*\(/g;
|
|
|
9910
10825
|
var TRANSLATE_SCRATCH = new Int32Array(4);
|
|
9911
10826
|
var BRACKET_SPAN_RE = /\[[^\]]*\]/g;
|
|
9912
10827
|
var HAS_UPPERCASE_RE = /[A-Z]/;
|
|
9913
|
-
var BRACKET_WHITESPACE_RE = /\[[^\]]*\s
|
|
9914
|
-
var INDEX_ACCESS_RE =
|
|
10828
|
+
var BRACKET_WHITESPACE_RE = /\[(?:[^[\]]|\[[^\]]*\])*\s(?:[^[\]]|\[[^\]]*\])*\]/;
|
|
10829
|
+
var INDEX_ACCESS_RE = /[^-/]\[\d+\]$/;
|
|
10830
|
+
var EMPTY_BRACKET_RE = /\[\]$/;
|
|
9915
10831
|
var PROPERTY_ACCESS_RE = /^[\w.@]+\[[^\]]+\]$/;
|
|
9916
10832
|
function warnBracketWhitespace(warnings, cls) {
|
|
9917
10833
|
const message = `[RI-1412] Class "${cls}" has whitespace inside its arbitrary value, so it can never match an element \u2014 class attributes, @a/@apply, and safelist() all split on whitespace. Use "_" for a space (\`bg-[url('a_b')]\` emits \`url('a b')\`) and "\\_" for a literal underscore. The class was skipped.`;
|
|
@@ -9972,16 +10888,17 @@ function scanClassTokens(sink, source, baseOffset, warnings) {
|
|
|
9972
10888
|
if (!cls) continue;
|
|
9973
10889
|
const unbanged = cls.endsWith("!") ? cls.slice(0, -1) : cls;
|
|
9974
10890
|
const base = unbanged.replace(VARIANT_STRIP_RE, "");
|
|
10891
|
+
if (BRACKET_WHITESPACE_RE.test(unbanged)) {
|
|
10892
|
+
if (warnings && sink.inClassList) warnBracketWhitespace(warnings, cls);
|
|
10893
|
+
continue;
|
|
10894
|
+
}
|
|
9975
10895
|
if (!base.includes("[")) {
|
|
9976
10896
|
if (HAS_UPPERCASE_RE.test(base)) continue;
|
|
9977
10897
|
} else {
|
|
9978
10898
|
if (HAS_UPPERCASE_RE.test(base.replace(BRACKET_SPAN_RE, ""))) continue;
|
|
10899
|
+
if (EMPTY_BRACKET_RE.test(base)) continue;
|
|
9979
10900
|
if (INDEX_ACCESS_RE.test(base)) continue;
|
|
9980
10901
|
if (PROPERTY_ACCESS_RE.test(base)) continue;
|
|
9981
|
-
if (BRACKET_WHITESPACE_RE.test(base)) {
|
|
9982
|
-
if (warnings && sink.inClassList) warnBracketWhitespace(warnings, cls);
|
|
9983
|
-
continue;
|
|
9984
|
-
}
|
|
9985
10902
|
}
|
|
9986
10903
|
if (!wantsPositions) {
|
|
9987
10904
|
sink.add(cls, 0, 0, -1, -1);
|
|
@@ -10354,6 +11271,37 @@ function extractSvelte(sink, context, warnings) {
|
|
|
10354
11271
|
warnings
|
|
10355
11272
|
);
|
|
10356
11273
|
}
|
|
11274
|
+
function astroFrontmatterEnd(content) {
|
|
11275
|
+
if (!content.startsWith("---")) return 0;
|
|
11276
|
+
const afterOpen = content.indexOf("\n");
|
|
11277
|
+
if (afterOpen === -1) return 0;
|
|
11278
|
+
for (let i = afterOpen; i !== -1; i = content.indexOf("\n", i + 1)) {
|
|
11279
|
+
if (!content.startsWith("---", i + 1)) continue;
|
|
11280
|
+
const lineEnd = content.indexOf("\n", i + 1);
|
|
11281
|
+
const rest = lineEnd === -1 ? content.slice(i + 4) : content.slice(i + 4, lineEnd);
|
|
11282
|
+
if (rest.trim() === "") return i + 4;
|
|
11283
|
+
}
|
|
11284
|
+
return 0;
|
|
11285
|
+
}
|
|
11286
|
+
function extractAstro(sink, context, warnings) {
|
|
11287
|
+
const content = context.content;
|
|
11288
|
+
sink.setOrigin?.("plain");
|
|
11289
|
+
scanClassTokens(sink, content, 0, warnings);
|
|
11290
|
+
sink.setOrigin?.("attribute");
|
|
11291
|
+
collectAssignedValues(sink, content, /(?<![:\w-])class\s*=/g, NOOP_VISITOR, 0, warnings);
|
|
11292
|
+
collectAssignedValues(sink, content, /\bclass:list\s*=/g, collectClassishExpression, 0, warnings);
|
|
11293
|
+
const scriptEnd = astroFrontmatterEnd(content);
|
|
11294
|
+
if (scriptEnd > 0) {
|
|
11295
|
+
const script = content.slice(0, scriptEnd);
|
|
11296
|
+
sink.setOrigin?.("helper");
|
|
11297
|
+
collectCallArguments(sink, script, CLASS_HELPERS_CALL_RE, void 0, 0, warnings);
|
|
11298
|
+
const variantMetadata = collectVariantHelperArguments(sink, script, 0, warnings);
|
|
11299
|
+
collectClassMapArguments(sink, script, 0, warnings);
|
|
11300
|
+
sink.setHelper?.(null);
|
|
11301
|
+
pruneVariantMetadata(sink, variantMetadata, script);
|
|
11302
|
+
}
|
|
11303
|
+
pruneTokens(sink, NON_CLASS_IDENTIFIERS);
|
|
11304
|
+
}
|
|
10357
11305
|
var EXTRACTORS = [
|
|
10358
11306
|
{
|
|
10359
11307
|
test: (context) => !!context.path && context.path.endsWith(".vue"),
|
|
@@ -10363,6 +11311,10 @@ var EXTRACTORS = [
|
|
|
10363
11311
|
test: (context) => !!context.path && context.path.endsWith(".svelte"),
|
|
10364
11312
|
extract: extractSvelte
|
|
10365
11313
|
},
|
|
11314
|
+
{
|
|
11315
|
+
test: (context) => !!context.path && context.path.endsWith(".astro"),
|
|
11316
|
+
extract: extractAstro
|
|
11317
|
+
},
|
|
10366
11318
|
{
|
|
10367
11319
|
test: (context) => !!context.path && context.path.endsWith(".html"),
|
|
10368
11320
|
extract: extractHTML
|
|
@@ -10439,6 +11391,352 @@ function extractClassCandidates(input, warnings) {
|
|
|
10439
11391
|
return collector.finish();
|
|
10440
11392
|
}
|
|
10441
11393
|
|
|
11394
|
+
// src/css/strip.ts
|
|
11395
|
+
var DIRECTIVE_AT_RULE_PATTERNS = [...EXTRACTABLE_DIRECTIVE_NAMES].map(directiveAtRulePattern);
|
|
11396
|
+
function buildProtectedRanges(css) {
|
|
11397
|
+
const ranges = [];
|
|
11398
|
+
let i = 0;
|
|
11399
|
+
while (i < css.length) {
|
|
11400
|
+
if (css[i] === "/" && css[i + 1] === "*") {
|
|
11401
|
+
const start = i;
|
|
11402
|
+
const end = css.indexOf("*/", i + 2);
|
|
11403
|
+
i = end === -1 ? css.length : end + 2;
|
|
11404
|
+
ranges.push([start, i]);
|
|
11405
|
+
continue;
|
|
11406
|
+
}
|
|
11407
|
+
if (css[i] === '"' || css[i] === "'") {
|
|
11408
|
+
const quote = css[i];
|
|
11409
|
+
const start = i;
|
|
11410
|
+
i++;
|
|
11411
|
+
while (i < css.length && css[i] !== quote) {
|
|
11412
|
+
if (css[i] === "\\" && i + 1 < css.length) i++;
|
|
11413
|
+
i++;
|
|
11414
|
+
}
|
|
11415
|
+
if (i < css.length) i++;
|
|
11416
|
+
ranges.push([start, i]);
|
|
11417
|
+
} else {
|
|
11418
|
+
i++;
|
|
11419
|
+
}
|
|
11420
|
+
}
|
|
11421
|
+
return ranges;
|
|
11422
|
+
}
|
|
11423
|
+
function protectedRangeEnd(pos, ranges) {
|
|
11424
|
+
let lo = 0;
|
|
11425
|
+
let hi = ranges.length - 1;
|
|
11426
|
+
while (lo <= hi) {
|
|
11427
|
+
const mid = lo + hi >>> 1;
|
|
11428
|
+
const [start, end] = ranges[mid];
|
|
11429
|
+
if (pos < start) hi = mid - 1;
|
|
11430
|
+
else if (pos >= end) lo = mid + 1;
|
|
11431
|
+
else return end;
|
|
11432
|
+
}
|
|
11433
|
+
return -1;
|
|
11434
|
+
}
|
|
11435
|
+
function isInsideProtectedRange(pos, ranges) {
|
|
11436
|
+
return protectedRangeEnd(pos, ranges) !== -1;
|
|
11437
|
+
}
|
|
11438
|
+
function replaceOutsideProtectedRanges(css, re, ranges) {
|
|
11439
|
+
re.lastIndex = 0;
|
|
11440
|
+
const parts = [];
|
|
11441
|
+
let lastIdx = 0;
|
|
11442
|
+
for (; ; ) {
|
|
11443
|
+
const match = re.exec(css);
|
|
11444
|
+
if (match === null) break;
|
|
11445
|
+
const guardEnd = protectedRangeEnd(match.index, ranges);
|
|
11446
|
+
if (guardEnd !== -1) {
|
|
11447
|
+
re.lastIndex = guardEnd;
|
|
11448
|
+
continue;
|
|
11449
|
+
}
|
|
11450
|
+
if (!isAtRuleBoundary(css, match.index)) {
|
|
11451
|
+
re.lastIndex = match.index + 1;
|
|
11452
|
+
continue;
|
|
11453
|
+
}
|
|
11454
|
+
let end = match.index + match[0].length;
|
|
11455
|
+
if (isInsideProtectedRange(end - 1, ranges)) {
|
|
11456
|
+
let k = end;
|
|
11457
|
+
let aborted = false;
|
|
11458
|
+
while (k < css.length) {
|
|
11459
|
+
if (!isInsideProtectedRange(k, ranges)) {
|
|
11460
|
+
const ch = css[k];
|
|
11461
|
+
if (ch === ";") break;
|
|
11462
|
+
if (ch === "{" || ch === "}") {
|
|
11463
|
+
aborted = true;
|
|
11464
|
+
break;
|
|
11465
|
+
}
|
|
11466
|
+
}
|
|
11467
|
+
k++;
|
|
11468
|
+
}
|
|
11469
|
+
if (aborted) continue;
|
|
11470
|
+
end = k < css.length ? k + 1 : css.length;
|
|
11471
|
+
re.lastIndex = end;
|
|
11472
|
+
}
|
|
11473
|
+
parts.push(css.slice(lastIdx, match.index));
|
|
11474
|
+
lastIdx = end;
|
|
11475
|
+
}
|
|
11476
|
+
parts.push(css.slice(lastIdx));
|
|
11477
|
+
return parts.join("");
|
|
11478
|
+
}
|
|
11479
|
+
function stripBalancedBlocks(css, re, protectedRanges) {
|
|
11480
|
+
re.lastIndex = 0;
|
|
11481
|
+
const ranges = [];
|
|
11482
|
+
for (; ; ) {
|
|
11483
|
+
const match = re.exec(css);
|
|
11484
|
+
if (match === null) break;
|
|
11485
|
+
const start = match.index;
|
|
11486
|
+
const guardEnd = protectedRangeEnd(start, protectedRanges);
|
|
11487
|
+
if (guardEnd !== -1) {
|
|
11488
|
+
re.lastIndex = guardEnd;
|
|
11489
|
+
continue;
|
|
11490
|
+
}
|
|
11491
|
+
if (!isAtRuleBoundary(css, start)) {
|
|
11492
|
+
re.lastIndex = start + 1;
|
|
11493
|
+
continue;
|
|
11494
|
+
}
|
|
11495
|
+
let braceIdx = css.indexOf("{", start);
|
|
11496
|
+
while (braceIdx !== -1 && isInsideProtectedRange(braceIdx, protectedRanges)) {
|
|
11497
|
+
braceIdx = css.indexOf("{", braceIdx + 1);
|
|
11498
|
+
}
|
|
11499
|
+
const preludeEnd = braceIdx === -1 ? css.length : braceIdx;
|
|
11500
|
+
let semiIdx = -1;
|
|
11501
|
+
for (let k = start; k < preludeEnd; k++) {
|
|
11502
|
+
if (css[k] === ";" && !isInsideProtectedRange(k, protectedRanges)) {
|
|
11503
|
+
semiIdx = k;
|
|
11504
|
+
break;
|
|
11505
|
+
}
|
|
11506
|
+
}
|
|
11507
|
+
if (semiIdx !== -1) {
|
|
11508
|
+
ranges.push([start, semiIdx + 1]);
|
|
11509
|
+
re.lastIndex = semiIdx + 1;
|
|
11510
|
+
continue;
|
|
11511
|
+
}
|
|
11512
|
+
if (braceIdx === -1) {
|
|
11513
|
+
ranges.push([start, css.length]);
|
|
11514
|
+
break;
|
|
11515
|
+
}
|
|
11516
|
+
let depth = 1;
|
|
11517
|
+
let j = braceIdx + 1;
|
|
11518
|
+
while (j < css.length && depth > 0) {
|
|
11519
|
+
const ch = css[j];
|
|
11520
|
+
if (ch === '"' || ch === "'") {
|
|
11521
|
+
const quote = ch;
|
|
11522
|
+
j++;
|
|
11523
|
+
while (j < css.length && css[j] !== quote) {
|
|
11524
|
+
if (css[j] === "\\" && j + 1 < css.length) j++;
|
|
11525
|
+
j++;
|
|
11526
|
+
}
|
|
11527
|
+
j++;
|
|
11528
|
+
continue;
|
|
11529
|
+
}
|
|
11530
|
+
if (ch === "/" && css[j + 1] === "*") {
|
|
11531
|
+
const end = css.indexOf("*/", j + 2);
|
|
11532
|
+
j = end === -1 ? css.length : end + 2;
|
|
11533
|
+
continue;
|
|
11534
|
+
}
|
|
11535
|
+
if (ch === "{") depth++;
|
|
11536
|
+
else if (ch === "}") depth--;
|
|
11537
|
+
j++;
|
|
11538
|
+
}
|
|
11539
|
+
ranges.push([start, j]);
|
|
11540
|
+
re.lastIndex = j;
|
|
11541
|
+
}
|
|
11542
|
+
if (ranges.length === 0) return css;
|
|
11543
|
+
const parts = [];
|
|
11544
|
+
let lastEnd = 0;
|
|
11545
|
+
for (const [start, end] of ranges) {
|
|
11546
|
+
parts.push(css.slice(lastEnd, start));
|
|
11547
|
+
lastEnd = end;
|
|
11548
|
+
}
|
|
11549
|
+
parts.push(css.slice(lastEnd));
|
|
11550
|
+
return parts.join("");
|
|
11551
|
+
}
|
|
11552
|
+
var ALL_SEMI_DIRECTIVES_RE = new RegExp(
|
|
11553
|
+
DIRECTIVE_AT_RULE_PATTERNS.map((p) => `${p}[^{;]*;`).join("|"),
|
|
11554
|
+
"g"
|
|
11555
|
+
);
|
|
11556
|
+
var ALL_BRACE_DIRECTIVES_RE = new RegExp(
|
|
11557
|
+
DIRECTIVE_AT_RULE_PATTERNS.map((p) => `${p}[^{]*{`).join("|"),
|
|
11558
|
+
"g"
|
|
11559
|
+
);
|
|
11560
|
+
var RI_IMPORT_RE = new RegExp(
|
|
11561
|
+
`@import\\s+(?:url\\(\\s*)?["'](?:${RI_IMPORT_SPECIFIER_ALTERNATION})["']\\s*\\)?[^;]*;`,
|
|
11562
|
+
"g"
|
|
11563
|
+
);
|
|
11564
|
+
var NO_JOIN_NEEDED = /* @__PURE__ */ new Set([";", ",", "(", ")", "{", "}", ":"]);
|
|
11565
|
+
function stripCSSComments2(css) {
|
|
11566
|
+
if (!css.includes("/*")) return css;
|
|
11567
|
+
const parts = [];
|
|
11568
|
+
let cursor = 0;
|
|
11569
|
+
for (const [start, end] of buildProtectedRanges(css)) {
|
|
11570
|
+
if (css[start] !== "/") continue;
|
|
11571
|
+
if (css[start + 2] === "!") continue;
|
|
11572
|
+
const before = css[start - 1];
|
|
11573
|
+
const after = css[end];
|
|
11574
|
+
const welds = before !== void 0 && after !== void 0 && !/\s/.test(before) && !/\s/.test(after) && !NO_JOIN_NEEDED.has(before) && !NO_JOIN_NEEDED.has(after);
|
|
11575
|
+
parts.push(css.slice(cursor, start), welds ? " " : "");
|
|
11576
|
+
cursor = end;
|
|
11577
|
+
}
|
|
11578
|
+
if (cursor === 0) return css;
|
|
11579
|
+
parts.push(css.slice(cursor));
|
|
11580
|
+
return parts.join("").replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n");
|
|
11581
|
+
}
|
|
11582
|
+
function stripRIDirectives(css) {
|
|
11583
|
+
let currentRanges = buildProtectedRanges(css);
|
|
11584
|
+
let result = replaceOutsideProtectedRanges(css, RI_IMPORT_RE, currentRanges);
|
|
11585
|
+
if (result !== css) {
|
|
11586
|
+
currentRanges = buildProtectedRanges(result);
|
|
11587
|
+
}
|
|
11588
|
+
const beforePhase1 = result;
|
|
11589
|
+
result = replaceOutsideProtectedRanges(result, ALL_SEMI_DIRECTIVES_RE, currentRanges);
|
|
11590
|
+
const dirty = result !== beforePhase1;
|
|
11591
|
+
if (dirty) {
|
|
11592
|
+
currentRanges = buildProtectedRanges(result);
|
|
11593
|
+
}
|
|
11594
|
+
result = stripBalancedBlocks(result, ALL_BRACE_DIRECTIVES_RE, currentRanges);
|
|
11595
|
+
return result.trim();
|
|
11596
|
+
}
|
|
11597
|
+
|
|
11598
|
+
// src/project/imports.ts
|
|
11599
|
+
var DEFAULT_MAX_DEPTH = 8;
|
|
11600
|
+
var RI_MARKER_TARGETS = new Set(RI_MARKER_IMPORT_SPECIFIERS);
|
|
11601
|
+
function isRemoteTarget(target) {
|
|
11602
|
+
return target.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(target) || // A leading "/" is a URL path relative to the site root, not a file path.
|
|
11603
|
+
target.startsWith("/");
|
|
11604
|
+
}
|
|
11605
|
+
function findStatementEnd(src, from) {
|
|
11606
|
+
let i = from;
|
|
11607
|
+
let depth = 0;
|
|
11608
|
+
while (i < src.length) {
|
|
11609
|
+
const ch = src[i];
|
|
11610
|
+
if (ch === "/" && src[i + 1] === "*") {
|
|
11611
|
+
const end = src.indexOf("*/", i + 2);
|
|
11612
|
+
i = end === -1 ? src.length : end + 2;
|
|
11613
|
+
continue;
|
|
11614
|
+
}
|
|
11615
|
+
if (ch === '"' || ch === "'") {
|
|
11616
|
+
const quote = ch;
|
|
11617
|
+
i++;
|
|
11618
|
+
while (i < src.length && src[i] !== quote) {
|
|
11619
|
+
if (src[i] === "\\") i++;
|
|
11620
|
+
i++;
|
|
11621
|
+
}
|
|
11622
|
+
i++;
|
|
11623
|
+
continue;
|
|
11624
|
+
}
|
|
11625
|
+
if (ch === "(") {
|
|
11626
|
+
depth++;
|
|
11627
|
+
i++;
|
|
11628
|
+
continue;
|
|
11629
|
+
}
|
|
11630
|
+
if (ch === ")") {
|
|
11631
|
+
if (depth > 0) depth--;
|
|
11632
|
+
i++;
|
|
11633
|
+
continue;
|
|
11634
|
+
}
|
|
11635
|
+
if (depth === 0) {
|
|
11636
|
+
if (ch === ";") return i + 1;
|
|
11637
|
+
if (ch === "{") return -1;
|
|
11638
|
+
}
|
|
11639
|
+
i++;
|
|
11640
|
+
}
|
|
11641
|
+
return src.length;
|
|
11642
|
+
}
|
|
11643
|
+
function isPackageSpecifier(target) {
|
|
11644
|
+
return !target.startsWith(".");
|
|
11645
|
+
}
|
|
11646
|
+
function inlineInto(css, from, depth, ctx, inPackage) {
|
|
11647
|
+
const edits = [];
|
|
11648
|
+
scanAtRules(css, (name, atPos, nameEnd) => {
|
|
11649
|
+
if (name !== "import") return void 0;
|
|
11650
|
+
const stmtEnd = findStatementEnd(css, nameEnd);
|
|
11651
|
+
if (stmtEnd === -1) return void 0;
|
|
11652
|
+
const { target, nextIndex } = readImportTarget(css, nameEnd);
|
|
11653
|
+
if (target === null) return stmtEnd;
|
|
11654
|
+
const preludeEnd = css[stmtEnd - 1] === ";" ? stmtEnd - 1 : stmtEnd;
|
|
11655
|
+
const tail = css.slice(Math.min(nextIndex, preludeEnd), preludeEnd).trim();
|
|
11656
|
+
if (RI_MARKER_TARGETS.has(target)) {
|
|
11657
|
+
if (depth > 0) edits.push({ start: atPos, end: stmtEnd, text: "" });
|
|
11658
|
+
return stmtEnd;
|
|
11659
|
+
}
|
|
11660
|
+
if (isRemoteTarget(target)) return stmtEnd;
|
|
11661
|
+
if (tail !== "") {
|
|
11662
|
+
ctx.warnings.push(
|
|
11663
|
+
`[RI-1045] Conditional @import "${target}" (${tail}) was left in place; directives inside it are not read. Move the directives to an unconditional @import.`
|
|
11664
|
+
);
|
|
11665
|
+
return stmtEnd;
|
|
11666
|
+
}
|
|
11667
|
+
if (ctx.exhausted) return stmtEnd;
|
|
11668
|
+
if (depth >= ctx.maxDepth) {
|
|
11669
|
+
ctx.warnings.push(
|
|
11670
|
+
`[RI-1043] @import "${target}" nests deeper than ${ctx.maxDepth} levels and was left in place. Flatten the import chain.`
|
|
11671
|
+
);
|
|
11672
|
+
return stmtEnd;
|
|
11673
|
+
}
|
|
11674
|
+
const resolved = ctx.resolve(target, from);
|
|
11675
|
+
if (resolved === null) {
|
|
11676
|
+
ctx.warnings.push(
|
|
11677
|
+
`[RI-1041] Could not resolve @import "${target}"${from ? ` from "${from}"` : ""}. The at-rule was left in place and its directives were not read. Check the path, or install the package.`
|
|
11678
|
+
);
|
|
11679
|
+
return stmtEnd;
|
|
11680
|
+
}
|
|
11681
|
+
if (ctx.stack.has(resolved.path)) {
|
|
11682
|
+
ctx.warnings.push(
|
|
11683
|
+
`[RI-1042] Circular @import "${target}" \u2014 "${resolved.path}" already imports the file importing it. The repeat was dropped.`
|
|
11684
|
+
);
|
|
11685
|
+
edits.push({ start: atPos, end: stmtEnd, text: "" });
|
|
11686
|
+
return stmtEnd;
|
|
11687
|
+
}
|
|
11688
|
+
if (ctx.visited.has(resolved.path)) {
|
|
11689
|
+
edits.push({ start: atPos, end: stmtEnd, text: "" });
|
|
11690
|
+
return stmtEnd;
|
|
11691
|
+
}
|
|
11692
|
+
if (ctx.bytes + resolved.content.length > ctx.maxBytes) {
|
|
11693
|
+
ctx.exhausted = true;
|
|
11694
|
+
ctx.warnings.push(
|
|
11695
|
+
`[RI-1044] Inlined @import files exceed the ${ctx.maxBytes / 1048576} MB limit at "${target}". It and any later import were left in place. Split the stylesheet.`
|
|
11696
|
+
);
|
|
11697
|
+
return stmtEnd;
|
|
11698
|
+
}
|
|
11699
|
+
ctx.visited.add(resolved.path);
|
|
11700
|
+
ctx.files.push(resolved.path);
|
|
11701
|
+
ctx.bytes += resolved.content.length;
|
|
11702
|
+
ctx.stack.add(resolved.path);
|
|
11703
|
+
const entersPackage = !inPackage && isPackageSpecifier(target);
|
|
11704
|
+
const text = inlineInto(
|
|
11705
|
+
resolved.content,
|
|
11706
|
+
resolved.path,
|
|
11707
|
+
depth + 1,
|
|
11708
|
+
ctx,
|
|
11709
|
+
inPackage || entersPackage
|
|
11710
|
+
);
|
|
11711
|
+
ctx.stack.delete(resolved.path);
|
|
11712
|
+
edits.push({ start: atPos, end: stmtEnd, text: entersPackage ? stripCSSComments2(text) : text });
|
|
11713
|
+
return stmtEnd;
|
|
11714
|
+
});
|
|
11715
|
+
if (edits.length === 0) return css;
|
|
11716
|
+
let out = "";
|
|
11717
|
+
let cursor = 0;
|
|
11718
|
+
for (const edit of edits) {
|
|
11719
|
+
out += css.slice(cursor, edit.start) + edit.text;
|
|
11720
|
+
cursor = edit.end;
|
|
11721
|
+
}
|
|
11722
|
+
return out + css.slice(cursor);
|
|
11723
|
+
}
|
|
11724
|
+
function inlineDirectiveImports(css, options) {
|
|
11725
|
+
const ctx = {
|
|
11726
|
+
resolve: options.resolve,
|
|
11727
|
+
maxDepth: options.maxDepth ?? DEFAULT_MAX_DEPTH,
|
|
11728
|
+
maxBytes: options.maxBytes ?? MAX_DIRECTIVE_INPUT_SIZE,
|
|
11729
|
+
warnings: [],
|
|
11730
|
+
files: [],
|
|
11731
|
+
stack: new Set(options.from === void 0 ? [] : [options.from]),
|
|
11732
|
+
visited: new Set(options.from === void 0 ? [] : [options.from]),
|
|
11733
|
+
bytes: 0,
|
|
11734
|
+
exhausted: false
|
|
11735
|
+
};
|
|
11736
|
+
const out = inlineInto(css, options.from, 0, ctx, false);
|
|
11737
|
+
return { css: out, warnings: ctx.warnings, files: ctx.files };
|
|
11738
|
+
}
|
|
11739
|
+
|
|
10442
11740
|
// src/project/analyze.ts
|
|
10443
11741
|
function nextLineTargets(css, spans, warnings) {
|
|
10444
11742
|
const targets = /* @__PURE__ */ new Map();
|
|
@@ -10533,11 +11831,880 @@ function isDisabled(diagnostic, directiveIndex, suppressed, targets, capture) {
|
|
|
10533
11831
|
return false;
|
|
10534
11832
|
}
|
|
10535
11833
|
|
|
11834
|
+
// src/integrations/font-providers/metrics-data.ts
|
|
11835
|
+
var FONT_METRICS_TABLE = {
|
|
11836
|
+
abel: [2006, -604, 0, 2048, 783, "sans-serif"],
|
|
11837
|
+
alegreya: [1016, -345, 0, 1e3, 410, "serif"],
|
|
11838
|
+
"anonymous pro": [1675, -373, 0, 2048, 1118, "monospace"],
|
|
11839
|
+
archivo: [878, -210, 0, 1e3, 440, "sans-serif"],
|
|
11840
|
+
arial: [1854, -434, 67, 2048, 913, "sans-serif"],
|
|
11841
|
+
asap: [934, -212, 0, 1e3, 442, "sans-serif"],
|
|
11842
|
+
barlow: [1e3, -200, 0, 1e3, 431, "sans-serif"],
|
|
11843
|
+
bitter: [935, -265, 0, 1e3, 465, "serif"],
|
|
11844
|
+
"bricolage grotesque": [930, -270, 0, 1e3, 470, "sans-serif"],
|
|
11845
|
+
cabin: [1930, -500, 0, 2e3, 844, "sans-serif"],
|
|
11846
|
+
catamaran: [1100, -540, 0, 1e3, 411, "sans-serif"],
|
|
11847
|
+
chivo: [940, -250, 0, 1e3, 478, "sans-serif"],
|
|
11848
|
+
"cormorant garamond": [924, -287, 0, 1e3, 394, "serif"],
|
|
11849
|
+
"courier new": [1705, -615, 0, 2048, 1229, "monospace"],
|
|
11850
|
+
"crimson pro": [918, -220, 0, 1024, 410, "serif"],
|
|
11851
|
+
"crimson text": [972, -359, 0, 1024, 405, "serif"],
|
|
11852
|
+
"dm sans": [992, -310, 0, 1e3, 466, "sans-serif"],
|
|
11853
|
+
"dm serif display": [1036, -335, 0, 1e3, 446, "serif"],
|
|
11854
|
+
dosis: [1027, -237, 0, 1e3, 377, "sans-serif"],
|
|
11855
|
+
"eb garamond": [1007, -298, 0, 1e3, 385, "serif"],
|
|
11856
|
+
epilogue: [1580, -470, 0, 2e3, 990, "sans-serif"],
|
|
11857
|
+
"exo 2": [999, -201, 0, 1e3, 455, "sans-serif"],
|
|
11858
|
+
figtree: [950, -250, 0, 1e3, 449, "sans-serif"],
|
|
11859
|
+
"fira code": [1980, -644, 0, 2e3, 1200, "monospace"],
|
|
11860
|
+
"fira sans": [935, -265, 0, 1e3, 458, "sans-serif"],
|
|
11861
|
+
fraunces: [1956, -510, 0, 2e3, 938, "serif"],
|
|
11862
|
+
gabarito: [940, -260, 0, 1e3, 442, "display"],
|
|
11863
|
+
"geist mono": [1005, -295, 0, 1e3, 600, "monospace"],
|
|
11864
|
+
geist: [1005, -295, 0, 1e3, 467, "sans-serif"],
|
|
11865
|
+
georgia: [1878, -449, 0, 2048, 913, "serif"],
|
|
11866
|
+
heebo: [2146, -862, 0, 2048, 912, "sans-serif"],
|
|
11867
|
+
"helvetica neue": [952, -213, 28, 1e3, 450, "sans-serif"],
|
|
11868
|
+
helvetica: [1577, -471, 0, 2048, 913, "sans-serif"],
|
|
11869
|
+
hind: [1055, -546, 0, 1e3, 429, "sans-serif"],
|
|
11870
|
+
"ibm plex mono": [1025, -275, 0, 1e3, 600, "monospace"],
|
|
11871
|
+
"ibm plex sans": [1025, -275, 0, 1e3, 451, "sans-serif"],
|
|
11872
|
+
"ibm plex serif": [1025, -275, 0, 1e3, 473, "serif"],
|
|
11873
|
+
inconsolata: [859, -190, 0, 1e3, 500, "monospace"],
|
|
11874
|
+
"instrument sans": [970, -250, 0, 1e3, 458, "sans-serif"],
|
|
11875
|
+
"instrument serif": [990, -310, 0, 1e3, 341, "serif"],
|
|
11876
|
+
inter: [1984, -494, 0, 2048, 978, "sans-serif"],
|
|
11877
|
+
"jetbrains mono": [1020, -300, 0, 1e3, 600, "monospace"],
|
|
11878
|
+
"josefin sans": [750, -250, 0, 1e3, 456, "sans-serif"],
|
|
11879
|
+
kanit: [1100, -395, 0, 1e3, 452, "sans-serif"],
|
|
11880
|
+
karla: [1834, -504, 0, 2e3, 913, "sans-serif"],
|
|
11881
|
+
lato: [1974, -426, 0, 2e3, 871, "sans-serif"],
|
|
11882
|
+
lexend: [1e3, -250, 0, 1e3, 490, "sans-serif"],
|
|
11883
|
+
"libre baskerville": [970, -270, 0, 1e3, 517, "serif"],
|
|
11884
|
+
"libre franklin": [966, -246, 0, 1e3, 465, "sans-serif"],
|
|
11885
|
+
lora: [1006, -274, 0, 1e3, 468, "serif"],
|
|
11886
|
+
manrope: [2132, -600, 0, 2e3, 920, "sans-serif"],
|
|
11887
|
+
"maven pro": [965, -210, 0, 1e3, 462, "sans-serif"],
|
|
11888
|
+
merriweather: [1968, -546, 0, 2e3, 970, "serif"],
|
|
11889
|
+
montserrat: [968, -251, 0, 1e3, 503, "sans-serif"],
|
|
11890
|
+
mulish: [1005, -250, 0, 1e3, 464, "sans-serif"],
|
|
11891
|
+
newsreader: [1470, -530, 0, 2e3, 857, "serif"],
|
|
11892
|
+
"noto sans": [1069, -293, 0, 1e3, 474, "sans-serif"],
|
|
11893
|
+
"noto serif": [1069, -293, 0, 1e3, 481, "serif"],
|
|
11894
|
+
"nunito sans": [1011, -353, 0, 1e3, 452, "sans-serif"],
|
|
11895
|
+
nunito: [1011, -353, 0, 1e3, 452, "sans-serif"],
|
|
11896
|
+
onest: [970, -305, 0, 1e3, 469, "sans-serif"],
|
|
11897
|
+
"open sans": [2189, -600, 0, 2048, 960, "sans-serif"],
|
|
11898
|
+
oswald: [1193, -289, 0, 1e3, 363, "sans-serif"],
|
|
11899
|
+
outfit: [1e3, -260, 0, 1e3, 445, "sans-serif"],
|
|
11900
|
+
overpass: [1766, -766, 0, 2e3, 898, "sans-serif"],
|
|
11901
|
+
oxygen: [2103, -483, 0, 2048, 923, "sans-serif"],
|
|
11902
|
+
"playfair display": [1082, -251, 0, 1e3, 452, "serif"],
|
|
11903
|
+
"plus jakarta sans": [1038, -222, 0, 1e3, 468, "sans-serif"],
|
|
11904
|
+
poppins: [1050, -350, 100, 1e3, 500, "sans-serif"],
|
|
11905
|
+
"pt sans": [1018, -276, 0, 1e3, 431, "sans-serif"],
|
|
11906
|
+
"pt serif": [1039, -286, 0, 1e3, 448, "serif"],
|
|
11907
|
+
"public sans": [1900, -450, 0, 2e3, 935, "sans-serif"],
|
|
11908
|
+
quicksand: [1e3, -250, 0, 1e3, 465, "sans-serif"],
|
|
11909
|
+
raleway: [940, -234, 0, 1e3, 463, "sans-serif"],
|
|
11910
|
+
"red hat display": [1018, -305, 0, 1e3, 442, "sans-serif"],
|
|
11911
|
+
"red hat text": [1018, -305, 0, 1e3, 447, "sans-serif"],
|
|
11912
|
+
"roboto condensed": [1900, -500, 0, 2048, 811, "sans-serif"],
|
|
11913
|
+
"roboto flex": [1900, -500, 0, 2048, 908, "sans-serif"],
|
|
11914
|
+
"roboto mono": [2146, -555, 0, 2048, 1229, "monospace"],
|
|
11915
|
+
"roboto slab": [2146, -555, 0, 2048, 972, "serif"],
|
|
11916
|
+
roboto: [1900, -500, 0, 2048, 911, "sans-serif"],
|
|
11917
|
+
rubik: [935, -250, 0, 1e3, 468, "sans-serif"],
|
|
11918
|
+
"schibsted grotesk": [2e3, -528, 0, 2048, 954, "sans-serif"],
|
|
11919
|
+
"segoe ui": [2210, -514, 0, 2048, 908, "sans-serif"],
|
|
11920
|
+
sora: [970, -290, 0, 1e3, 507, "sans-serif"],
|
|
11921
|
+
"source code pro": [984, -273, 0, 1e3, 600, "monospace"],
|
|
11922
|
+
"source sans 3": [1024, -400, 0, 1e3, 418, "sans-serif"],
|
|
11923
|
+
"source serif 4": [1036, -335, 0, 1e3, 479, "serif"],
|
|
11924
|
+
"space grotesk": [984, -292, 0, 1e3, 489, "sans-serif"],
|
|
11925
|
+
"space mono": [1120, -361, 0, 1e3, 612, "monospace"],
|
|
11926
|
+
spectral: [1059, -463, 0, 1e3, 446, "serif"],
|
|
11927
|
+
tahoma: [2049, -423, 0, 2048, 917, "sans-serif"],
|
|
11928
|
+
"times new roman": [1825, -443, 87, 2048, 832, "serif"],
|
|
11929
|
+
"titillium web": [1133, -388, 0, 1e3, 421, "sans-serif"],
|
|
11930
|
+
"trebuchet ms": [1923, -455, 0, 2048, 934, "sans-serif"],
|
|
11931
|
+
"ubuntu mono": [830, -170, 0, 1e3, 500, "monospace"],
|
|
11932
|
+
ubuntu: [932, -189, 28, 1e3, 455, "sans-serif"],
|
|
11933
|
+
urbanist: [1900, -500, 0, 2e3, 883, "sans-serif"],
|
|
11934
|
+
"varela round": [918, -286, 0, 1e3, 478, "sans-serif"],
|
|
11935
|
+
verdana: [2059, -430, 0, 2048, 1049, "sans-serif"],
|
|
11936
|
+
"victor mono": [1100, -250, 0, 1e3, 600, "monospace"],
|
|
11937
|
+
vollkorn: [952, -441, 0, 1e3, 438, "serif"],
|
|
11938
|
+
"work sans": [930, -243, 0, 1e3, 499, "sans-serif"],
|
|
11939
|
+
"zilla slab": [944, -256, 0, 1e3, 434, "serif"]
|
|
11940
|
+
};
|
|
11941
|
+
|
|
11942
|
+
// src/integrations/font-providers/metrics.ts
|
|
11943
|
+
var CATEGORY_FALLBACK = {
|
|
11944
|
+
"sans-serif": "Arial",
|
|
11945
|
+
serif: "Times New Roman",
|
|
11946
|
+
monospace: "Courier New"
|
|
11947
|
+
};
|
|
11948
|
+
function lookupFontMetrics(family) {
|
|
11949
|
+
return FONT_METRICS_TABLE[family.trim().toLowerCase()];
|
|
11950
|
+
}
|
|
11951
|
+
var round4 = (n) => Math.round(n * 1e4) / 1e4;
|
|
11952
|
+
function computeFallbackMetrics(fallbackName, font, fallbackFont) {
|
|
11953
|
+
const [ascent, descent, lineGap, unitsPerEm, xWidthAvg] = font;
|
|
11954
|
+
const [, , , fbUnitsPerEm, fbXWidthAvg] = fallbackFont;
|
|
11955
|
+
const sizeAdjust = xWidthAvg / unitsPerEm / (fbXWidthAvg / fbUnitsPerEm);
|
|
11956
|
+
return {
|
|
11957
|
+
fallback: fallbackName,
|
|
11958
|
+
sizeAdjust: round4(sizeAdjust * 100),
|
|
11959
|
+
ascent: round4(ascent / unitsPerEm / sizeAdjust * 100),
|
|
11960
|
+
descent: round4(Math.abs(descent) / unitsPerEm / sizeAdjust * 100),
|
|
11961
|
+
lineGap: round4(lineGap / unitsPerEm / sizeAdjust * 100)
|
|
11962
|
+
};
|
|
11963
|
+
}
|
|
11964
|
+
function resolveAutoMetrics(family, fallbackStack, explicitFallback) {
|
|
11965
|
+
const font = lookupFontMetrics(family);
|
|
11966
|
+
if (!font) return null;
|
|
11967
|
+
const fallbackName = explicitFallback ?? fallbackStack.find((f) => lookupFontMetrics(f)) ?? CATEGORY_FALLBACK[font[5]] ?? "Arial";
|
|
11968
|
+
const fallbackFont = lookupFontMetrics(fallbackName);
|
|
11969
|
+
if (!fallbackFont) return null;
|
|
11970
|
+
return computeFallbackMetrics(fallbackName, font, fallbackFont);
|
|
11971
|
+
}
|
|
11972
|
+
|
|
11973
|
+
// src/integrations/font-providers/emit.ts
|
|
11974
|
+
var SYSTEM_STACKS = Object.freeze({
|
|
11975
|
+
sans: 'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
|
|
11976
|
+
serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
|
|
11977
|
+
mono: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"'
|
|
11978
|
+
});
|
|
11979
|
+
function getFallbackStack(slot) {
|
|
11980
|
+
if (!SYSTEM_STACKS[slot] && isRIDebug()) {
|
|
11981
|
+
console.warn(`[RI-DEBUG] Unknown font slot "${slot}" \u2014 falling back to sans stack.`);
|
|
11982
|
+
}
|
|
11983
|
+
return SYSTEM_STACKS[slot] || SYSTEM_STACKS.sans;
|
|
11984
|
+
}
|
|
11985
|
+
function googleFontsUrl(family, face) {
|
|
11986
|
+
const encodedFamily = encodeURIComponent(family).replace(/%20/g, "+");
|
|
11987
|
+
let axisParam;
|
|
11988
|
+
if (face.weight.includes(",")) {
|
|
11989
|
+
const weights = face.weight.split(",").map((w) => w.trim());
|
|
11990
|
+
if (face.style.includes("italic")) {
|
|
11991
|
+
const tuples = weights.flatMap((w) => [`0,${w}`, `1,${w}`]);
|
|
11992
|
+
axisParam = `ital,wght@${tuples.join(";")}`;
|
|
11993
|
+
} else {
|
|
11994
|
+
axisParam = `wght@${weights.join(";")}`;
|
|
11995
|
+
}
|
|
11996
|
+
} else if (face.weight.includes(" ")) {
|
|
11997
|
+
const range = face.weight.replace(" ", "..");
|
|
11998
|
+
axisParam = face.style.includes("italic") ? `ital,wght@0,${range};1,${range}` : `wght@${range}`;
|
|
11999
|
+
} else {
|
|
12000
|
+
const w = face.weight || "400";
|
|
12001
|
+
axisParam = face.style.includes("italic") ? `ital,wght@0,${w};1,${w}` : `wght@${w}`;
|
|
12002
|
+
}
|
|
12003
|
+
const display = face.display || "swap";
|
|
12004
|
+
return `https://fonts.googleapis.com/css2?family=${encodedFamily}:${axisParam}&display=${display}`;
|
|
12005
|
+
}
|
|
12006
|
+
function escapeFontFamily(name) {
|
|
12007
|
+
return name.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\0/g, "\\0").replace(/\n/g, "\\a ").replace(/\r/g, "\\d ");
|
|
12008
|
+
}
|
|
12009
|
+
function generateFallbackFontFace(family, metrics) {
|
|
12010
|
+
const safeFamily = escapeFontFamily(family);
|
|
12011
|
+
return `@font-face {
|
|
12012
|
+
font-family: "${safeFamily} Fallback";
|
|
12013
|
+
src: local("${escapeFontFamily(metrics.fallback)}");
|
|
12014
|
+
size-adjust: ${metrics.sizeAdjust}%;
|
|
12015
|
+
ascent-override: ${metrics.ascent}%;
|
|
12016
|
+
descent-override: ${metrics.descent}%;
|
|
12017
|
+
line-gap-override: ${metrics.lineGap}%;
|
|
12018
|
+
}`;
|
|
12019
|
+
}
|
|
12020
|
+
var FONT_FORMAT_MIME = {
|
|
12021
|
+
woff2: "font/woff2",
|
|
12022
|
+
woff: "font/woff",
|
|
12023
|
+
truetype: "font/ttf",
|
|
12024
|
+
opentype: "font/otf"
|
|
12025
|
+
};
|
|
12026
|
+
function inferFontFormat(path) {
|
|
12027
|
+
if (path.endsWith(".woff2")) return "woff2";
|
|
12028
|
+
if (path.endsWith(".woff")) return "woff";
|
|
12029
|
+
if (path.endsWith(".ttf")) return "truetype";
|
|
12030
|
+
if (path.endsWith(".otf")) return "opentype";
|
|
12031
|
+
return "woff2";
|
|
12032
|
+
}
|
|
12033
|
+
function generateWebFontFace(family, face) {
|
|
12034
|
+
if (face.provider === "system" || !face.provider) return null;
|
|
12035
|
+
if (face.provider === "google") {
|
|
12036
|
+
return { type: "import", css: `@import url("${googleFontsUrl(family, face)}");` };
|
|
12037
|
+
}
|
|
12038
|
+
const safeProvider = escapeFontFamily(face.provider);
|
|
12039
|
+
const format = inferFontFormat(face.provider);
|
|
12040
|
+
const src = `url("${safeProvider}") format("${format}")`;
|
|
12041
|
+
const declarations = [` font-family: "${escapeFontFamily(family)}";`, ` src: ${src};`];
|
|
12042
|
+
if (face.weight) declarations.push(` font-weight: ${face.weight};`);
|
|
12043
|
+
if (face.style && face.style !== "normal") declarations.push(` font-style: ${face.style};`);
|
|
12044
|
+
if (face.display) declarations.push(` font-display: ${face.display};`);
|
|
12045
|
+
if (face.unicodeRange) declarations.push(` unicode-range: ${face.unicodeRange};`);
|
|
12046
|
+
return { type: "font-face", css: `@font-face {
|
|
12047
|
+
${declarations.join("\n")}
|
|
12048
|
+
}` };
|
|
12049
|
+
}
|
|
12050
|
+
function normalizeLocalStyle(style, family, warnings) {
|
|
12051
|
+
if (style.includes(" ") && !style.startsWith("oblique")) {
|
|
12052
|
+
const first = style.split(/\s+/)[0];
|
|
12053
|
+
warnings.push(
|
|
12054
|
+
`[RI-1203] Local font "${family}" has a compound font-style "${style}" \u2014 a single @font-face takes one style. Split upright and italic into separate @face blocks (or use the italic: shorthand). Using "${first}".`
|
|
12055
|
+
);
|
|
12056
|
+
return first;
|
|
12057
|
+
}
|
|
12058
|
+
return style;
|
|
12059
|
+
}
|
|
12060
|
+
function resolveSlotMetrics(slot, warnings) {
|
|
12061
|
+
const cfg = slot.metrics;
|
|
12062
|
+
if (cfg === null) return null;
|
|
12063
|
+
if (cfg?.sizeAdjust !== void 0) {
|
|
12064
|
+
return {
|
|
12065
|
+
fallback: cfg.fallback || slot.fallback[0] || "Arial",
|
|
12066
|
+
sizeAdjust: cfg.sizeAdjust,
|
|
12067
|
+
ascent: cfg.ascent,
|
|
12068
|
+
descent: cfg.descent,
|
|
12069
|
+
lineGap: cfg.lineGap
|
|
12070
|
+
};
|
|
12071
|
+
}
|
|
12072
|
+
const resolved = resolveAutoMetrics(slot.family, slot.fallback, cfg?.fallback);
|
|
12073
|
+
if (!resolved && cfg?.fallback) {
|
|
12074
|
+
const missing = lookupFontMetrics(slot.family) ? cfg.fallback : slot.family;
|
|
12075
|
+
warnings.push(
|
|
12076
|
+
`[RI-1220] @font slot "${slot.slot}" requests metrics matching against "${cfg.fallback}", but "${missing}" is not in the built-in metrics table \u2014 no fallback @font-face was generated. Provide the four percentages explicitly (metrics: "${cfg.fallback}" <size-adjust> <ascent> <descent> <line-gap>) or use \`metrics: none\`.`
|
|
12077
|
+
);
|
|
12078
|
+
}
|
|
12079
|
+
return resolved;
|
|
12080
|
+
}
|
|
12081
|
+
function generateFontCSS(slot) {
|
|
12082
|
+
const imports = [];
|
|
12083
|
+
const fontFaces = [];
|
|
12084
|
+
const variables = [];
|
|
12085
|
+
const warnings = [];
|
|
12086
|
+
const pushFeatureVars = () => {
|
|
12087
|
+
if (slot.features) variables.push(`--font-${slot.slot}--features: ${slot.features};`);
|
|
12088
|
+
if (slot.variation) variables.push(`--font-${slot.slot}--variations: ${slot.variation};`);
|
|
12089
|
+
};
|
|
12090
|
+
if (slot.kind === "system") {
|
|
12091
|
+
variables.push(`--font-${slot.slot}: ${getFallbackStack(slot.slot)};`);
|
|
12092
|
+
return { imports, fontFaces, variables, warnings };
|
|
12093
|
+
}
|
|
12094
|
+
if (slot.kind === "manual") {
|
|
12095
|
+
const fallback = slot.fallback.length > 0 ? slot.fallback.join(", ") : getFallbackStack(slot.slot);
|
|
12096
|
+
const stack = [`"${escapeFontFamily(slot.family)}"`, fallback].join(", ");
|
|
12097
|
+
variables.push(`--font-${slot.slot}: ${stack};`);
|
|
12098
|
+
pushFeatureVars();
|
|
12099
|
+
return { imports, fontFaces, variables, warnings };
|
|
12100
|
+
}
|
|
12101
|
+
const metrics = resolveSlotMetrics(slot, warnings);
|
|
12102
|
+
if (metrics) fontFaces.push(generateFallbackFontFace(slot.family, metrics));
|
|
12103
|
+
for (const face of slot.faces) {
|
|
12104
|
+
if (face.provider !== "google" && !face.provider.startsWith("/") && !face.provider.startsWith("http") && !face.provider.startsWith(".")) {
|
|
12105
|
+
warnings.push(
|
|
12106
|
+
`[RI-1201] Unknown font provider "${face.provider}" for "${slot.family}" \u2014 supported: google, or a file path/URL.`
|
|
12107
|
+
);
|
|
12108
|
+
continue;
|
|
12109
|
+
}
|
|
12110
|
+
const emitFace = face.provider === "google" ? face : { ...face, style: normalizeLocalStyle(face.style, slot.family, warnings) };
|
|
12111
|
+
const webFont = generateWebFontFace(slot.family, emitFace);
|
|
12112
|
+
if (!webFont) continue;
|
|
12113
|
+
if (webFont.type === "import") imports.push(webFont.css);
|
|
12114
|
+
else fontFaces.push(webFont.css);
|
|
12115
|
+
}
|
|
12116
|
+
const fallbackStack = slot.fallback.length > 0 ? slot.fallback.join(", ") : getFallbackStack(slot.slot);
|
|
12117
|
+
const safeFamily = escapeFontFamily(slot.family);
|
|
12118
|
+
const stackParts = [`"${safeFamily}"`];
|
|
12119
|
+
if (metrics) stackParts.push(`"${safeFamily} Fallback"`);
|
|
12120
|
+
stackParts.push(fallbackStack);
|
|
12121
|
+
variables.push(`--font-${slot.slot}: ${stackParts.join(", ")};`);
|
|
12122
|
+
pushFeatureVars();
|
|
12123
|
+
return { imports, fontFaces, variables, warnings };
|
|
12124
|
+
}
|
|
12125
|
+
function getFontPreloadLinks(slots) {
|
|
12126
|
+
const links = [];
|
|
12127
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12128
|
+
for (const slot of slots) {
|
|
12129
|
+
for (const face of slot.faces) {
|
|
12130
|
+
if (!face.preload) continue;
|
|
12131
|
+
if (face.provider === "system" || face.provider === "google" || !face.provider) continue;
|
|
12132
|
+
if (seen.has(face.provider)) continue;
|
|
12133
|
+
seen.add(face.provider);
|
|
12134
|
+
links.push({
|
|
12135
|
+
href: face.provider,
|
|
12136
|
+
as: "font",
|
|
12137
|
+
type: FONT_FORMAT_MIME[inferFontFormat(face.provider)],
|
|
12138
|
+
crossorigin: true
|
|
12139
|
+
});
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
12142
|
+
return links;
|
|
12143
|
+
}
|
|
12144
|
+
|
|
12145
|
+
// src/css/preflight.ts
|
|
12146
|
+
var DEFAULT_PREFLIGHT = {
|
|
12147
|
+
core: true,
|
|
12148
|
+
typography: true,
|
|
12149
|
+
content: true,
|
|
12150
|
+
forms: true,
|
|
12151
|
+
interactive: true,
|
|
12152
|
+
modern: true
|
|
12153
|
+
};
|
|
12154
|
+
var modules = [
|
|
12155
|
+
// ── Core ─────────────────────────────────────────────────
|
|
12156
|
+
{
|
|
12157
|
+
name: "box-sizing",
|
|
12158
|
+
category: "core",
|
|
12159
|
+
css: `*, *::before, *::after {
|
|
12160
|
+
box-sizing: border-box;
|
|
12161
|
+
}`
|
|
12162
|
+
},
|
|
12163
|
+
{
|
|
12164
|
+
name: "margins",
|
|
12165
|
+
category: "core",
|
|
12166
|
+
css: `body, h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, pre, ol, ul, menu {
|
|
12167
|
+
margin: 0;
|
|
12168
|
+
}`
|
|
12169
|
+
},
|
|
12170
|
+
{
|
|
12171
|
+
name: "borders",
|
|
12172
|
+
category: "core",
|
|
12173
|
+
css: `*, *::before, *::after {
|
|
12174
|
+
border-width: 0;
|
|
12175
|
+
border-style: solid;
|
|
12176
|
+
border-color: inherit;
|
|
12177
|
+
}`
|
|
12178
|
+
},
|
|
12179
|
+
{
|
|
12180
|
+
name: "root-defaults",
|
|
12181
|
+
category: "core",
|
|
12182
|
+
css: `:root {
|
|
12183
|
+
line-height: 1.5;
|
|
12184
|
+
-webkit-text-size-adjust: 100%;
|
|
12185
|
+
tab-size: 4;
|
|
12186
|
+
}
|
|
12187
|
+
body {
|
|
12188
|
+
line-height: inherit;
|
|
12189
|
+
font-family: var(--font-sans);
|
|
12190
|
+
}
|
|
12191
|
+
code, kbd, samp, pre {
|
|
12192
|
+
font-family: var(--font-mono);
|
|
12193
|
+
font-size: 1em;
|
|
12194
|
+
}`
|
|
12195
|
+
},
|
|
12196
|
+
// ── Typography ───────────────────────────────────────────
|
|
12197
|
+
{
|
|
12198
|
+
name: "font-smoothing",
|
|
12199
|
+
category: "typography",
|
|
12200
|
+
css: `body {
|
|
12201
|
+
-webkit-font-smoothing: antialiased;
|
|
12202
|
+
-moz-osx-font-smoothing: grayscale;
|
|
12203
|
+
}`
|
|
12204
|
+
},
|
|
12205
|
+
{
|
|
12206
|
+
name: "font-inherit",
|
|
12207
|
+
category: "typography",
|
|
12208
|
+
css: `button, input, optgroup, select, textarea {
|
|
12209
|
+
font-family: inherit;
|
|
12210
|
+
font-feature-settings: inherit;
|
|
12211
|
+
font-variation-settings: inherit;
|
|
12212
|
+
font-size: 100%;
|
|
12213
|
+
font-weight: inherit;
|
|
12214
|
+
line-height: inherit;
|
|
12215
|
+
letter-spacing: inherit;
|
|
12216
|
+
color: inherit;
|
|
12217
|
+
}`
|
|
12218
|
+
},
|
|
12219
|
+
{
|
|
12220
|
+
name: "heading-sizes",
|
|
12221
|
+
category: "typography",
|
|
12222
|
+
css: `h1, h2, h3, h4, h5, h6 {
|
|
12223
|
+
font-size: inherit;
|
|
12224
|
+
font-weight: inherit;
|
|
12225
|
+
}`
|
|
12226
|
+
},
|
|
12227
|
+
{
|
|
12228
|
+
name: "link-reset",
|
|
12229
|
+
category: "typography",
|
|
12230
|
+
css: `a {
|
|
12231
|
+
color: inherit;
|
|
12232
|
+
text-decoration: inherit;
|
|
12233
|
+
}`
|
|
12234
|
+
},
|
|
12235
|
+
// ── Content ──────────────────────────────────────────────
|
|
12236
|
+
{
|
|
12237
|
+
name: "media-block",
|
|
12238
|
+
category: "content",
|
|
12239
|
+
css: `img, svg, video, canvas, audio, iframe, embed, object {
|
|
12240
|
+
display: block;
|
|
12241
|
+
max-inline-size: 100%;
|
|
12242
|
+
}
|
|
12243
|
+
img, video {
|
|
12244
|
+
block-size: auto;
|
|
12245
|
+
}`
|
|
12246
|
+
},
|
|
12247
|
+
{
|
|
12248
|
+
name: "list-reset",
|
|
12249
|
+
category: "content",
|
|
12250
|
+
css: `ol, ul, menu {
|
|
12251
|
+
list-style: none;
|
|
12252
|
+
padding: 0;
|
|
12253
|
+
}`
|
|
12254
|
+
},
|
|
12255
|
+
{
|
|
12256
|
+
name: "table-reset",
|
|
12257
|
+
category: "content",
|
|
12258
|
+
css: `table {
|
|
12259
|
+
text-indent: 0;
|
|
12260
|
+
border-color: inherit;
|
|
12261
|
+
border-collapse: collapse;
|
|
12262
|
+
}`
|
|
12263
|
+
},
|
|
12264
|
+
{
|
|
12265
|
+
name: "hr-reset",
|
|
12266
|
+
category: "content",
|
|
12267
|
+
css: `hr {
|
|
12268
|
+
block-size: 0;
|
|
12269
|
+
border-top-width: 1px;
|
|
12270
|
+
color: inherit;
|
|
12271
|
+
}`
|
|
12272
|
+
},
|
|
12273
|
+
// ── Forms ────────────────────────────────────────────────
|
|
12274
|
+
{
|
|
12275
|
+
name: "button-reset",
|
|
12276
|
+
category: "forms",
|
|
12277
|
+
css: `button, [role="button"] {
|
|
12278
|
+
cursor: pointer;
|
|
12279
|
+
padding: 0;
|
|
12280
|
+
}
|
|
12281
|
+
button {
|
|
12282
|
+
background-color: transparent;
|
|
12283
|
+
background-image: none;
|
|
12284
|
+
}`
|
|
12285
|
+
},
|
|
12286
|
+
{
|
|
12287
|
+
name: "input-reset",
|
|
12288
|
+
category: "forms",
|
|
12289
|
+
css: `input::placeholder, textarea::placeholder {
|
|
12290
|
+
opacity: 1;
|
|
12291
|
+
color: color-mix(in oklab, currentColor 48%, transparent);
|
|
12292
|
+
}
|
|
12293
|
+
input:where([type="button"], [type="reset"], [type="submit"]) {
|
|
12294
|
+
-webkit-appearance: button;
|
|
12295
|
+
appearance: button;
|
|
12296
|
+
}`
|
|
12297
|
+
},
|
|
12298
|
+
{
|
|
12299
|
+
name: "textarea-reset",
|
|
12300
|
+
category: "forms",
|
|
12301
|
+
css: `textarea {
|
|
12302
|
+
resize: vertical;
|
|
12303
|
+
}`
|
|
12304
|
+
},
|
|
12305
|
+
{
|
|
12306
|
+
name: "fieldset-reset",
|
|
12307
|
+
category: "forms",
|
|
12308
|
+
css: `fieldset {
|
|
12309
|
+
margin: 0;
|
|
12310
|
+
padding: 0;
|
|
12311
|
+
}
|
|
12312
|
+
legend {
|
|
12313
|
+
padding: 0;
|
|
12314
|
+
}`
|
|
12315
|
+
},
|
|
12316
|
+
// ── Interactive ──────────────────────────────────────────
|
|
12317
|
+
{
|
|
12318
|
+
name: "focus-visible",
|
|
12319
|
+
category: "interactive",
|
|
12320
|
+
css: `:focus-visible {
|
|
12321
|
+
outline-width: 2px;
|
|
12322
|
+
outline-style: solid;
|
|
12323
|
+
outline-offset: 2px;
|
|
12324
|
+
outline-color: currentColor;
|
|
12325
|
+
}`
|
|
12326
|
+
},
|
|
12327
|
+
{
|
|
12328
|
+
name: "dialog-reset",
|
|
12329
|
+
category: "interactive",
|
|
12330
|
+
css: `dialog {
|
|
12331
|
+
padding: 0;
|
|
12332
|
+
}
|
|
12333
|
+
dialog::backdrop {
|
|
12334
|
+
background-color: oklch(0 0 0 / 0.5);
|
|
12335
|
+
}`
|
|
12336
|
+
},
|
|
12337
|
+
{
|
|
12338
|
+
name: "summary-reset",
|
|
12339
|
+
category: "interactive",
|
|
12340
|
+
css: `summary {
|
|
12341
|
+
display: list-item;
|
|
12342
|
+
cursor: pointer;
|
|
12343
|
+
}`
|
|
12344
|
+
},
|
|
12345
|
+
// ── Modern ───────────────────────────────────────────────
|
|
12346
|
+
{
|
|
12347
|
+
name: "interpolate-size",
|
|
12348
|
+
category: "modern",
|
|
12349
|
+
css: `@supports (interpolate-size: allow-keywords) {
|
|
12350
|
+
:root {
|
|
12351
|
+
interpolate-size: allow-keywords;
|
|
12352
|
+
}
|
|
12353
|
+
}`
|
|
12354
|
+
},
|
|
12355
|
+
{
|
|
12356
|
+
name: "overflow-wrap",
|
|
12357
|
+
category: "modern",
|
|
12358
|
+
css: `body {
|
|
12359
|
+
overflow-wrap: break-word;
|
|
12360
|
+
}`
|
|
12361
|
+
},
|
|
12362
|
+
{
|
|
12363
|
+
name: "color-scheme",
|
|
12364
|
+
category: "modern",
|
|
12365
|
+
css: `html {
|
|
12366
|
+
color-scheme: light dark;
|
|
12367
|
+
}
|
|
12368
|
+
html[data-appearance="dark"] {
|
|
12369
|
+
color-scheme: dark;
|
|
12370
|
+
}
|
|
12371
|
+
html[data-appearance="light"] {
|
|
12372
|
+
color-scheme: light;
|
|
12373
|
+
}`
|
|
12374
|
+
}
|
|
12375
|
+
];
|
|
12376
|
+
function generatePreflight(config = DEFAULT_PREFLIGHT) {
|
|
12377
|
+
const enabledModules = modules.filter((m) => config[m.category]);
|
|
12378
|
+
if (enabledModules.length === 0) return "";
|
|
12379
|
+
return enabledModules.map((m) => `/* preflight: ${m.name} */
|
|
12380
|
+
${m.css}`).join("\n\n");
|
|
12381
|
+
}
|
|
12382
|
+
|
|
12383
|
+
// src/assembly.ts
|
|
12384
|
+
function resolveColorDemand(theme, usage) {
|
|
12385
|
+
const shadowsToEmit = resolveTransitiveShadowDeps(theme.shadows, usage.usedShadows);
|
|
12386
|
+
const effectiveStops = new Map(
|
|
12387
|
+
[...usage.usedColorStops].map(([k, v]) => [k, new Set(v)])
|
|
12388
|
+
);
|
|
12389
|
+
const liveNames = new Set(usage.usedColorNames);
|
|
12390
|
+
let demandGrew = true;
|
|
12391
|
+
const addStops = (name, stops) => {
|
|
12392
|
+
let set = effectiveStops.get(name);
|
|
12393
|
+
if (!set) {
|
|
12394
|
+
set = /* @__PURE__ */ new Set();
|
|
12395
|
+
effectiveStops.set(name, set);
|
|
12396
|
+
demandGrew = true;
|
|
12397
|
+
}
|
|
12398
|
+
for (const stop of stops) {
|
|
12399
|
+
if (set.has(stop)) continue;
|
|
12400
|
+
set.add(stop);
|
|
12401
|
+
demandGrew = true;
|
|
12402
|
+
}
|
|
12403
|
+
};
|
|
12404
|
+
const addName = (name) => {
|
|
12405
|
+
if (liveNames.has(name)) return;
|
|
12406
|
+
liveNames.add(name);
|
|
12407
|
+
demandGrew = true;
|
|
12408
|
+
};
|
|
12409
|
+
const scanForColors = (text) => {
|
|
12410
|
+
if (!text.includes("var(--color-")) return;
|
|
12411
|
+
for (const m of text.matchAll(COLOR_VAR_REF_RE)) addName(m[1]);
|
|
12412
|
+
for (const m of text.matchAll(COLOR_STOP_REF_RE)) {
|
|
12413
|
+
if (m[2]) addStops(m[1], [Number(m[2])]);
|
|
12414
|
+
}
|
|
12415
|
+
};
|
|
12416
|
+
for (const name of shadowsToEmit) scanForColors(theme.shadows[name] ?? "");
|
|
12417
|
+
for (const body of usage.keyframes) scanForColors(body);
|
|
12418
|
+
for (const registration of theme.registeredProperties) {
|
|
12419
|
+
if (registration.initialValue) scanForColors(registration.initialValue);
|
|
12420
|
+
}
|
|
12421
|
+
while (demandGrew) {
|
|
12422
|
+
demandGrew = false;
|
|
12423
|
+
for (const [name, def] of Object.entries(theme.colors)) {
|
|
12424
|
+
const stops = effectiveStops.get(name);
|
|
12425
|
+
const liveByStop = stops !== void 0 && stops.size > 0;
|
|
12426
|
+
const liveByName = liveNames.has(name);
|
|
12427
|
+
if (!liveByStop && !liveByName) continue;
|
|
12428
|
+
switch (def.type) {
|
|
12429
|
+
case "alias":
|
|
12430
|
+
if (liveByStop) addStops(def.source, [...stops]);
|
|
12431
|
+
if (liveByName) addName(def.source);
|
|
12432
|
+
break;
|
|
12433
|
+
case "explicit":
|
|
12434
|
+
scanForColors(def.value);
|
|
12435
|
+
break;
|
|
12436
|
+
case "pair":
|
|
12437
|
+
scanForColors(def.light);
|
|
12438
|
+
scanForColors(def.dark);
|
|
12439
|
+
break;
|
|
12440
|
+
default:
|
|
12441
|
+
break;
|
|
12442
|
+
}
|
|
12443
|
+
}
|
|
12444
|
+
}
|
|
12445
|
+
const themeSuffixes = effectiveStops.get("theme");
|
|
12446
|
+
if (theme.colors.theme && themeSuffixes) {
|
|
12447
|
+
for (const [name, def] of Object.entries(theme.colors)) {
|
|
12448
|
+
if (name === "theme" || def.type !== "generative" || !def.inline) continue;
|
|
12449
|
+
addStops(name, themeSuffixes);
|
|
12450
|
+
}
|
|
12451
|
+
}
|
|
12452
|
+
return { effectiveStops, liveNames, shadowsToEmit };
|
|
12453
|
+
}
|
|
12454
|
+
function generateTokenLayer(theme, usage, fontOutputCache, demand = resolveColorDemand(theme, usage)) {
|
|
12455
|
+
const vars = [];
|
|
12456
|
+
vars.push(`--spacing: ${theme.spacing.base};`);
|
|
12457
|
+
const pushBounds = (prefix, config) => {
|
|
12458
|
+
if (config?.min !== void 0) vars.push(`${prefix}-min: ${config.min};`);
|
|
12459
|
+
if (config?.max !== void 0) vars.push(`${prefix}-max: ${config.max};`);
|
|
12460
|
+
};
|
|
12461
|
+
pushBounds("--fluid", theme.fluid);
|
|
12462
|
+
pushBounds("--fluid-text", theme.textFluid);
|
|
12463
|
+
pushBounds("--fluid-spacing", theme.spacingFluid);
|
|
12464
|
+
for (const [name, range] of Object.entries(theme.fluidRanges)) {
|
|
12465
|
+
pushBounds(`--fluid-${name}`, range);
|
|
12466
|
+
}
|
|
12467
|
+
const { effectiveStops, liveNames, shadowsToEmit } = demand;
|
|
12468
|
+
const colorVars = generateAllColorVariables(
|
|
12469
|
+
theme.colors,
|
|
12470
|
+
theme.darkConfig,
|
|
12471
|
+
effectiveStops,
|
|
12472
|
+
liveNames
|
|
12473
|
+
);
|
|
12474
|
+
vars.push(...colorVars);
|
|
12475
|
+
for (const [name, size] of Object.entries(theme.text).sort(
|
|
12476
|
+
([a], [b]) => codepointCompare(a, b)
|
|
12477
|
+
)) {
|
|
12478
|
+
if (!usage.usedTextSizes.has(name)) continue;
|
|
12479
|
+
vars.push(`--text-${name}: ${size.fontSize};`);
|
|
12480
|
+
vars.push(`--text-${name}-leading: ${size.lineHeight};`);
|
|
12481
|
+
}
|
|
12482
|
+
const configuredSlots = /* @__PURE__ */ new Set();
|
|
12483
|
+
for (const fontConfig of theme.fonts) {
|
|
12484
|
+
if (!usage.usedFonts.has(fontConfig.slot)) continue;
|
|
12485
|
+
const output = getCachedFontOutput(fontConfig, fontOutputCache);
|
|
12486
|
+
vars.push(...output.variables);
|
|
12487
|
+
configuredSlots.add(fontConfig.slot);
|
|
12488
|
+
}
|
|
12489
|
+
for (const [slot, stack] of Object.entries(SYSTEM_STACKS).sort(
|
|
12490
|
+
([a], [b]) => codepointCompare(a, b)
|
|
12491
|
+
)) {
|
|
12492
|
+
if (!configuredSlots.has(slot) && usage.usedFonts.has(slot)) {
|
|
12493
|
+
vars.push(`--font-${slot}: ${stack};`);
|
|
12494
|
+
}
|
|
12495
|
+
}
|
|
12496
|
+
for (const [name, val] of Object.entries(theme.shadows).sort(
|
|
12497
|
+
([a], [b]) => codepointCompare(a, b)
|
|
12498
|
+
)) {
|
|
12499
|
+
if (!shadowsToEmit.has(name)) continue;
|
|
12500
|
+
vars.push(`--shadow-${name}: ${val};`);
|
|
12501
|
+
}
|
|
12502
|
+
for (const [name, val] of Object.entries(theme.radii).sort(
|
|
12503
|
+
([a], [b]) => codepointCompare(a, b)
|
|
12504
|
+
)) {
|
|
12505
|
+
vars.push(`--rounded-${name}: ${val};`);
|
|
12506
|
+
}
|
|
12507
|
+
for (const [name, def] of Object.entries(theme.animations).sort(
|
|
12508
|
+
([a], [b]) => codepointCompare(a, b)
|
|
12509
|
+
)) {
|
|
12510
|
+
if (!usage.usedAnimations.has(name)) continue;
|
|
12511
|
+
vars.push(`--animate-${name}: ${def.shorthand};`);
|
|
12512
|
+
}
|
|
12513
|
+
return `:root {
|
|
12514
|
+
${vars.join("\n ")}
|
|
12515
|
+
}`;
|
|
12516
|
+
}
|
|
12517
|
+
function resolveTransitiveShadowDeps(shadows, seeds) {
|
|
12518
|
+
const out = /* @__PURE__ */ new Set();
|
|
12519
|
+
const worklist = [];
|
|
12520
|
+
for (const name of seeds) {
|
|
12521
|
+
if (Object.hasOwn(shadows, name)) {
|
|
12522
|
+
out.add(name);
|
|
12523
|
+
worklist.push(name);
|
|
12524
|
+
}
|
|
12525
|
+
}
|
|
12526
|
+
while (worklist.length > 0) {
|
|
12527
|
+
const name = worklist.pop();
|
|
12528
|
+
const value = shadows[name];
|
|
12529
|
+
if (!value?.includes("var(--shadow-")) continue;
|
|
12530
|
+
for (const m of value.matchAll(SHADOW_VAR_REF_RE)) {
|
|
12531
|
+
const dep = m[1];
|
|
12532
|
+
if (!out.has(dep) && Object.hasOwn(shadows, dep)) {
|
|
12533
|
+
out.add(dep);
|
|
12534
|
+
worklist.push(dep);
|
|
12535
|
+
}
|
|
12536
|
+
}
|
|
12537
|
+
}
|
|
12538
|
+
return out;
|
|
12539
|
+
}
|
|
12540
|
+
function cornerShapeValue(shape) {
|
|
12541
|
+
return typeof shape === "string" ? shape : `superellipse(${shape.superellipse})`;
|
|
12542
|
+
}
|
|
12543
|
+
function generateCornerShapeBlock(theme) {
|
|
12544
|
+
if (theme.roundedShape === null) return null;
|
|
12545
|
+
const value = cornerShapeValue(theme.roundedShape);
|
|
12546
|
+
const shapeRule = `:root {
|
|
12547
|
+
corner-shape: ${value};
|
|
12548
|
+
}
|
|
12549
|
+
*, ::before, ::after {
|
|
12550
|
+
corner-shape: inherit;
|
|
12551
|
+
}`;
|
|
12552
|
+
if (theme.roundedShapeScale === 1) return shapeRule;
|
|
12553
|
+
const scaleBlock = `@supports (corner-shape: ${value}) {
|
|
12554
|
+
:root {
|
|
12555
|
+
--ri-rounded-scale: ${theme.roundedShapeScale};
|
|
12556
|
+
}
|
|
12557
|
+
}`;
|
|
12558
|
+
return `${shapeRule}
|
|
12559
|
+
|
|
12560
|
+
${scaleBlock}`;
|
|
12561
|
+
}
|
|
12562
|
+
function fontCacheKey(config) {
|
|
12563
|
+
return JSON.stringify(config);
|
|
12564
|
+
}
|
|
12565
|
+
function getCachedFontOutput(config, cache) {
|
|
12566
|
+
const key = fontCacheKey(config);
|
|
12567
|
+
let cached = cache.get(key);
|
|
12568
|
+
if (!cached) {
|
|
12569
|
+
cached = generateFontCSS(config);
|
|
12570
|
+
cache.set(key, cached);
|
|
12571
|
+
}
|
|
12572
|
+
return cached;
|
|
12573
|
+
}
|
|
12574
|
+
function renderRegisteredProperty(reg) {
|
|
12575
|
+
const lines = [
|
|
12576
|
+
`@property ${reg.name} {`,
|
|
12577
|
+
` syntax: ${reg.syntax};`,
|
|
12578
|
+
` inherits: ${reg.inherits};`
|
|
12579
|
+
];
|
|
12580
|
+
if (reg.initialValue !== void 0) lines.push(` initial-value: ${reg.initialValue};`);
|
|
12581
|
+
lines.push("}");
|
|
12582
|
+
return lines.join("\n");
|
|
12583
|
+
}
|
|
12584
|
+
var PROPERTY_NAME_RE = /@property\s+(--[A-Za-z0-9_-]+)/;
|
|
12585
|
+
function collectPropertyBlocks(registered, engineProperties) {
|
|
12586
|
+
const blocks = [];
|
|
12587
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12588
|
+
const push = (block) => {
|
|
12589
|
+
const name = PROPERTY_NAME_RE.exec(block)?.[1];
|
|
12590
|
+
if (name) {
|
|
12591
|
+
if (seen.has(name)) return;
|
|
12592
|
+
seen.add(name);
|
|
12593
|
+
}
|
|
12594
|
+
blocks.push(block);
|
|
12595
|
+
};
|
|
12596
|
+
for (const reg of registered) push(renderRegisteredProperty(reg));
|
|
12597
|
+
for (const block of engineProperties) push(block);
|
|
12598
|
+
return blocks;
|
|
12599
|
+
}
|
|
12600
|
+
function assembleSections(compilation, theme, fontOutputCache) {
|
|
12601
|
+
const baseSections = [];
|
|
12602
|
+
const fontImports = [];
|
|
12603
|
+
const fontFaceBlocks = [];
|
|
12604
|
+
const assemblyWarnings = [];
|
|
12605
|
+
const fontWarningsEmitted = /* @__PURE__ */ new Set();
|
|
12606
|
+
if (theme.preflight.core !== false) {
|
|
12607
|
+
compilation.usedFonts.add("sans");
|
|
12608
|
+
compilation.usedFonts.add("mono");
|
|
12609
|
+
}
|
|
12610
|
+
for (const fontConfig of theme.fonts) {
|
|
12611
|
+
if (!compilation.usedFonts.has(fontConfig.slot)) continue;
|
|
12612
|
+
const output = getCachedFontOutput(fontConfig, fontOutputCache);
|
|
12613
|
+
fontImports.push(...output.imports);
|
|
12614
|
+
fontFaceBlocks.push(...output.fontFaces);
|
|
12615
|
+
for (const w of output.warnings) {
|
|
12616
|
+
if (!fontWarningsEmitted.has(w)) {
|
|
12617
|
+
assemblyWarnings.push(w);
|
|
12618
|
+
fontWarningsEmitted.add(w);
|
|
12619
|
+
}
|
|
12620
|
+
}
|
|
12621
|
+
}
|
|
12622
|
+
const importsSection = fontImports.length > 0 ? fontImports.join("\n") : null;
|
|
12623
|
+
const propertyBlocks = collectPropertyBlocks(theme.registeredProperties, compilation.properties);
|
|
12624
|
+
if (propertyBlocks.length > 0) {
|
|
12625
|
+
baseSections.push(propertyBlocks.join("\n\n"));
|
|
12626
|
+
}
|
|
12627
|
+
if (fontFaceBlocks.length > 0) {
|
|
12628
|
+
baseSections.push(fontFaceBlocks.join("\n\n"));
|
|
12629
|
+
}
|
|
12630
|
+
const demand = resolveColorDemand(theme, compilation);
|
|
12631
|
+
const tokenLayer = generateTokenLayer(theme, compilation, fontOutputCache, demand);
|
|
12632
|
+
if (tokenLayer) baseSections.push(tokenLayer);
|
|
12633
|
+
for (const w of checkPaletteContrast(theme.colors, compilation.usedColorStops)) {
|
|
12634
|
+
assemblyWarnings.push(w);
|
|
12635
|
+
}
|
|
12636
|
+
const themeOverrides = generateThemeOverrides(theme.colors, demand.effectiveStops.get("theme"));
|
|
12637
|
+
if (themeOverrides.length > 0) {
|
|
12638
|
+
baseSections.push(themeOverrides.join("\n\n"));
|
|
12639
|
+
}
|
|
12640
|
+
const cornerShape = generateCornerShapeBlock(theme);
|
|
12641
|
+
if (cornerShape) baseSections.push(cornerShape);
|
|
12642
|
+
if (compilation.keyframes.length > 0) {
|
|
12643
|
+
baseSections.push(compilation.keyframes.join("\n\n"));
|
|
12644
|
+
}
|
|
12645
|
+
const preflight = generatePreflight(theme.preflight);
|
|
12646
|
+
if (preflight) baseSections.push(preflight);
|
|
12647
|
+
const utilityCSS = renderCSS({
|
|
12648
|
+
...compilation,
|
|
12649
|
+
properties: [],
|
|
12650
|
+
keyframes: []
|
|
12651
|
+
});
|
|
12652
|
+
const utilitiesSection = utilityCSS !== "" ? utilityCSS : null;
|
|
12653
|
+
const parts = {
|
|
12654
|
+
imports: importsSection,
|
|
12655
|
+
base: baseSections,
|
|
12656
|
+
utilities: utilitiesSection
|
|
12657
|
+
};
|
|
12658
|
+
const sections = theme.layer ? applyLayerWrapping(parts, theme.layer) : [
|
|
12659
|
+
...importsSection !== null ? [importsSection] : [],
|
|
12660
|
+
...baseSections,
|
|
12661
|
+
...utilitiesSection !== null ? [utilitiesSection] : []
|
|
12662
|
+
];
|
|
12663
|
+
return { sections, warnings: assemblyWarnings };
|
|
12664
|
+
}
|
|
12665
|
+
function wrapInLayer(content, layerName) {
|
|
12666
|
+
const indented = content.replace(/^(?=.)/gm, " ");
|
|
12667
|
+
return `@layer ${layerName} {
|
|
12668
|
+
${indented}
|
|
12669
|
+
}`;
|
|
12670
|
+
}
|
|
12671
|
+
function applyLayerWrapping(parts, layer) {
|
|
12672
|
+
const sections = [];
|
|
12673
|
+
if (parts.imports !== null) sections.push(parts.imports);
|
|
12674
|
+
if (layer.wrapAll) {
|
|
12675
|
+
sections.push(`@layer ${layer.wrapAll};`);
|
|
12676
|
+
const joined = [...parts.base, ...parts.utilities !== null ? [parts.utilities] : []].join(
|
|
12677
|
+
"\n\n"
|
|
12678
|
+
);
|
|
12679
|
+
if (joined) sections.push(wrapInLayer(joined, layer.wrapAll));
|
|
12680
|
+
return sections;
|
|
12681
|
+
}
|
|
12682
|
+
if (layer.order && layer.order.length > 0) {
|
|
12683
|
+
sections.push(`@layer ${layer.order.join(", ")};`);
|
|
12684
|
+
}
|
|
12685
|
+
if (parts.base.length > 0) {
|
|
12686
|
+
const baseJoined = parts.base.join("\n\n");
|
|
12687
|
+
if (layer.base) {
|
|
12688
|
+
sections.push(wrapInLayer(baseJoined, layer.base));
|
|
12689
|
+
} else {
|
|
12690
|
+
sections.push(baseJoined);
|
|
12691
|
+
}
|
|
12692
|
+
}
|
|
12693
|
+
if (parts.utilities !== null) {
|
|
12694
|
+
if (layer.utilities) {
|
|
12695
|
+
sections.push(wrapInLayer(parts.utilities, layer.utilities));
|
|
12696
|
+
} else {
|
|
12697
|
+
sections.push(parts.utilities);
|
|
12698
|
+
}
|
|
12699
|
+
}
|
|
12700
|
+
return sections;
|
|
12701
|
+
}
|
|
12702
|
+
|
|
10536
12703
|
export {
|
|
10537
|
-
|
|
10538
|
-
SHADOW_VAR_REF_RE,
|
|
12704
|
+
escapeSelector,
|
|
10539
12705
|
isRIDebug,
|
|
10540
12706
|
withTimeout,
|
|
12707
|
+
stripCSSComments,
|
|
10541
12708
|
isAtRuleBoundary,
|
|
10542
12709
|
codepointCompare,
|
|
10543
12710
|
APPLY_ALIASES,
|
|
@@ -10548,6 +12715,7 @@ export {
|
|
|
10548
12715
|
matchCustomUtility,
|
|
10549
12716
|
forEachApplyClassList,
|
|
10550
12717
|
DIRECTIVE_TYPE_NAMES,
|
|
12718
|
+
scanEntries,
|
|
10551
12719
|
findClosingBrace,
|
|
10552
12720
|
SAFE_FONT_FAMILY_RE,
|
|
10553
12721
|
weightIsLoaded,
|
|
@@ -10583,10 +12751,8 @@ export {
|
|
|
10583
12751
|
scanCSSForTokenUsage,
|
|
10584
12752
|
createEmptyCompilationResult,
|
|
10585
12753
|
createThemeSnapshot,
|
|
10586
|
-
renderCSS,
|
|
10587
12754
|
createCompiler,
|
|
10588
12755
|
DIRECTIVE_NAMES_SET,
|
|
10589
|
-
directiveAtRulePattern,
|
|
10590
12756
|
isAtRuleNameChar,
|
|
10591
12757
|
RI_IMPORT_SPECIFIERS,
|
|
10592
12758
|
RI_IMPORT_SPECIFIER_ALTERNATION,
|
|
@@ -10594,16 +12760,20 @@ export {
|
|
|
10594
12760
|
isSuppressible,
|
|
10595
12761
|
parseFileDisables,
|
|
10596
12762
|
resolveDirectives,
|
|
10597
|
-
EXTRACTABLE_DIRECTIVE_NAMES,
|
|
10598
12763
|
MAX_DIRECTIVE_INPUT_SIZE,
|
|
10599
12764
|
extractDirectives,
|
|
12765
|
+
expandApplyBodyGroups,
|
|
10600
12766
|
expandVariantGroups,
|
|
10601
|
-
|
|
12767
|
+
expandGroupsInStylesheet,
|
|
10602
12768
|
CLASS_HELPER_NAMES,
|
|
10603
12769
|
VARIANT_HELPER_NAMES,
|
|
10604
12770
|
extractClasses,
|
|
10605
12771
|
extractClassesFromSource,
|
|
10606
12772
|
extractClassCandidates,
|
|
12773
|
+
getFontPreloadLinks,
|
|
12774
|
+
stripRIDirectives,
|
|
12775
|
+
inlineDirectiveImports,
|
|
10607
12776
|
analyzeProjectCSSMemo,
|
|
10608
|
-
analyzeProjectCSS
|
|
12777
|
+
analyzeProjectCSS,
|
|
12778
|
+
assembleSections
|
|
10609
12779
|
};
|