@kbach/react 0.6.25 → 0.6.26
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/README.md +53 -27
- package/dist/{chunk-XISB5W3A.mjs → chunk-AKX6I7WP.mjs} +1301 -1297
- package/dist/{chunk-RUI5EQDF.mjs → chunk-NWQIZZCW.mjs} +6 -2
- package/dist/core/index.d.ts +1274 -0
- package/dist/core/index.js +3457 -0
- package/dist/index.d.ts +50 -224
- package/dist/index.js +215 -3445
- package/dist/index.mjs +77 -36
- package/dist/jsx-dev-runtime.js +54 -3279
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.js +54 -3279
- package/dist/jsx-runtime.mjs +2 -2
- package/dist/vite-plugin.js +1348 -1292
- package/dist/vite-plugin.mjs +1348 -1292
- package/kbach-react.md +15 -1
- package/package.json +4 -8
- package/dist/index.d.mts +0 -455
- package/dist/jsx-dev-runtime.d.mts +0 -21
- package/dist/jsx-runtime.d.mts +0 -17
- package/dist/vite-plugin-client.d.mts +0 -8
- package/dist/vite-plugin-client.d.ts +0 -8
- package/dist/web-substitute-CfpYFnE7.d.mts +0 -22
package/dist/vite-plugin.js
CHANGED
|
@@ -649,14 +649,16 @@ var defaultTheme = {
|
|
|
649
649
|
animation: {}
|
|
650
650
|
};
|
|
651
651
|
|
|
652
|
-
// src/core/
|
|
652
|
+
// src/core/resolvers/color.ts
|
|
653
653
|
function resolveColor(value, colors, isArbitrary) {
|
|
654
654
|
if (isArbitrary) return value;
|
|
655
655
|
const slashIdx = value.indexOf("/");
|
|
656
656
|
const colorPart = slashIdx > 0 ? value.slice(0, slashIdx) : value;
|
|
657
657
|
const opacityPart = slashIdx > 0 ? value.slice(slashIdx + 1) : null;
|
|
658
658
|
let hex = null;
|
|
659
|
-
if (colorPart
|
|
659
|
+
if (colorPart.startsWith("[") && colorPart.endsWith("]")) {
|
|
660
|
+
hex = colorPart.slice(1, -1);
|
|
661
|
+
} else if (colorPart in colors) {
|
|
660
662
|
const entry = colors[colorPart];
|
|
661
663
|
if (typeof entry === "string") hex = entry;
|
|
662
664
|
else if (typeof entry === "object" && "6" in entry) hex = entry["6"];
|
|
@@ -721,6 +723,86 @@ function withOpacityVar(color, varName) {
|
|
|
721
723
|
const [r, g, b] = rgb;
|
|
722
724
|
return `rgba(${r},${g},${b},var(${varName},1))`;
|
|
723
725
|
}
|
|
726
|
+
var colorResolvers = {
|
|
727
|
+
// ── Background ─────────────────────────────────────────────────────────────
|
|
728
|
+
bg: ({ value, isArbitrary }, { colors }) => {
|
|
729
|
+
const color = resolveColor(value, colors, isArbitrary);
|
|
730
|
+
if (!color) return null;
|
|
731
|
+
return { backgroundColor: getEffectiveIsWeb() ? withOpacityVar(color, "--bg-opacity") : color };
|
|
732
|
+
},
|
|
733
|
+
"bg-opacity": ({ value, isArbitrary }, _) => {
|
|
734
|
+
if (!getEffectiveIsWeb()) return null;
|
|
735
|
+
const n = parseFloat(value);
|
|
736
|
+
if (isNaN(n)) return null;
|
|
737
|
+
const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
|
|
738
|
+
return { "--bg-opacity": v };
|
|
739
|
+
},
|
|
740
|
+
// ── Background gradient (CSS variable gradient stops, web-only) ──────────
|
|
741
|
+
"bg-gradient-to": ({ value }) => {
|
|
742
|
+
if (!getEffectiveIsWeb()) return null;
|
|
743
|
+
const directions = {
|
|
744
|
+
t: "to top",
|
|
745
|
+
tr: "to top right",
|
|
746
|
+
r: "to right",
|
|
747
|
+
br: "to bottom right",
|
|
748
|
+
b: "to bottom",
|
|
749
|
+
bl: "to bottom left",
|
|
750
|
+
l: "to left",
|
|
751
|
+
tl: "to top left"
|
|
752
|
+
};
|
|
753
|
+
const dir = directions[value];
|
|
754
|
+
if (!dir) return null;
|
|
755
|
+
return {
|
|
756
|
+
backgroundImage: `linear-gradient(${dir}, var(--kb-gradient-from, transparent), var(--kb-gradient-stops, transparent))`
|
|
757
|
+
};
|
|
758
|
+
},
|
|
759
|
+
from: ({ value, isArbitrary }, { colors }) => {
|
|
760
|
+
if (!getEffectiveIsWeb()) return null;
|
|
761
|
+
const color = resolveColor(value, colors, isArbitrary);
|
|
762
|
+
if (!color) return null;
|
|
763
|
+
return {
|
|
764
|
+
"--kb-gradient-from": color,
|
|
765
|
+
"--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-to, transparent)`
|
|
766
|
+
};
|
|
767
|
+
},
|
|
768
|
+
via: ({ value, isArbitrary }, { colors }) => {
|
|
769
|
+
if (!getEffectiveIsWeb()) return null;
|
|
770
|
+
const color = resolveColor(value, colors, isArbitrary);
|
|
771
|
+
if (!color) return null;
|
|
772
|
+
return {
|
|
773
|
+
"--kb-gradient-via": color,
|
|
774
|
+
"--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-via), var(--kb-gradient-to, transparent)`
|
|
775
|
+
};
|
|
776
|
+
},
|
|
777
|
+
to: ({ value, isArbitrary }, { colors }) => {
|
|
778
|
+
if (!getEffectiveIsWeb()) return null;
|
|
779
|
+
const color = resolveColor(value, colors, isArbitrary);
|
|
780
|
+
if (!color) return null;
|
|
781
|
+
return { "--kb-gradient-to": color };
|
|
782
|
+
},
|
|
783
|
+
// ── Tint color (native-only, for Image and icon components) ──────────────
|
|
784
|
+
tint: ({ value, isArbitrary }, { colors }) => {
|
|
785
|
+
if (getEffectiveIsWeb()) return null;
|
|
786
|
+
const color = resolveColor(value, colors, isArbitrary);
|
|
787
|
+
return color ? { tintColor: color } : null;
|
|
788
|
+
},
|
|
789
|
+
// ── Caret color (web-only) ────────────────────────────────────────────────
|
|
790
|
+
caret: ({ value, isArbitrary }, { colors }) => {
|
|
791
|
+
if (!getEffectiveIsWeb()) return null;
|
|
792
|
+
if (value === "auto" || value === "transparent") return { caretColor: value };
|
|
793
|
+
const color = resolveColor(value, colors, isArbitrary);
|
|
794
|
+
return color ? { caretColor: color } : null;
|
|
795
|
+
},
|
|
796
|
+
// ── Accent color (web-only) ───────────────────────────────────────────────
|
|
797
|
+
accent: ({ value, isArbitrary }, { colors }) => {
|
|
798
|
+
if (!getEffectiveIsWeb()) return null;
|
|
799
|
+
if (value === "auto") return { accentColor: "auto" };
|
|
800
|
+
const color = resolveColor(value, colors, isArbitrary);
|
|
801
|
+
return color ? { accentColor: color } : null;
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
// src/core/resolvers/spacing.ts
|
|
724
806
|
function resolveSpacing(value, negative, spacing, isArbitrary) {
|
|
725
807
|
if (isArbitrary) {
|
|
726
808
|
const resolved = getEffectiveIsWeb() ? value : toNativeValue(value);
|
|
@@ -753,516 +835,174 @@ function resolveSizing(value, spacing, isArbitrary) {
|
|
|
753
835
|
}
|
|
754
836
|
return null;
|
|
755
837
|
}
|
|
838
|
+
function makeSpacingResolver(prop) {
|
|
839
|
+
return ({ value, negative, isArbitrary }, { spacing }) => {
|
|
840
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
841
|
+
return v !== null ? { [prop]: v } : null;
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
var PADDING_MARGIN_PROPS = {
|
|
845
|
+
p: "padding",
|
|
846
|
+
px: "paddingHorizontal",
|
|
847
|
+
py: "paddingVertical",
|
|
848
|
+
pt: "paddingTop",
|
|
849
|
+
pr: "paddingRight",
|
|
850
|
+
pb: "paddingBottom",
|
|
851
|
+
pl: "paddingLeft",
|
|
852
|
+
m: "margin",
|
|
853
|
+
mx: "marginHorizontal",
|
|
854
|
+
my: "marginVertical",
|
|
855
|
+
mt: "marginTop",
|
|
856
|
+
mr: "marginRight",
|
|
857
|
+
mb: "marginBottom",
|
|
858
|
+
ml: "marginLeft"
|
|
859
|
+
};
|
|
860
|
+
var spacingResolvers = {
|
|
861
|
+
// ── Sizing ─────────────────────────────────────────────────────────────────
|
|
862
|
+
w: ({ value, isArbitrary }, { spacing }) => {
|
|
863
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
864
|
+
return v !== null ? { width: v } : null;
|
|
865
|
+
},
|
|
866
|
+
h: ({ value, isArbitrary }, { spacing }) => {
|
|
867
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
868
|
+
return v !== null ? { height: v } : null;
|
|
869
|
+
},
|
|
870
|
+
"min-w": ({ value, isArbitrary }, { spacing }) => {
|
|
871
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
872
|
+
return v !== null ? { minWidth: v } : null;
|
|
873
|
+
},
|
|
874
|
+
"min-h": ({ value, isArbitrary }, { spacing }) => {
|
|
875
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
876
|
+
return v !== null ? { minHeight: v } : null;
|
|
877
|
+
},
|
|
878
|
+
"max-w": ({ value, isArbitrary }, { spacing }) => {
|
|
879
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
880
|
+
return v !== null ? { maxWidth: v } : null;
|
|
881
|
+
},
|
|
882
|
+
"max-h": ({ value, isArbitrary }, { spacing }) => {
|
|
883
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
884
|
+
return v !== null ? { maxHeight: v } : null;
|
|
885
|
+
},
|
|
886
|
+
// ── Size shorthand (sets width AND height in one utility) ────────────────
|
|
887
|
+
size: ({ value, isArbitrary }, { spacing }) => {
|
|
888
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
889
|
+
return v !== null ? { width: v, height: v } : null;
|
|
890
|
+
},
|
|
891
|
+
// ── Flex basis ─────────────────────────────────────────────────────────────
|
|
892
|
+
basis: ({ value, isArbitrary }, { spacing }) => {
|
|
893
|
+
const v = resolveSizing(value, spacing, isArbitrary);
|
|
894
|
+
return v !== null ? { flexBasis: v } : null;
|
|
895
|
+
},
|
|
896
|
+
// ── Gap ────────────────────────────────────────────────────────────────────
|
|
897
|
+
gap: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
898
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
899
|
+
return v !== null ? { gap: v } : null;
|
|
900
|
+
},
|
|
901
|
+
"gap-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
902
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
903
|
+
return v !== null ? { columnGap: v } : null;
|
|
904
|
+
},
|
|
905
|
+
"gap-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
906
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
907
|
+
return v !== null ? { rowGap: v } : null;
|
|
908
|
+
},
|
|
909
|
+
// ── Position ───────────────────────────────────────────────────────────────
|
|
910
|
+
top: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
911
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
912
|
+
return v !== null ? { top: v } : null;
|
|
913
|
+
},
|
|
914
|
+
right: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
915
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
916
|
+
return v !== null ? { right: v } : null;
|
|
917
|
+
},
|
|
918
|
+
bottom: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
919
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
920
|
+
return v !== null ? { bottom: v } : null;
|
|
921
|
+
},
|
|
922
|
+
left: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
923
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
924
|
+
return v !== null ? { left: v } : null;
|
|
925
|
+
},
|
|
926
|
+
inset: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
927
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
928
|
+
return v !== null ? { top: v, right: v, bottom: v, left: v } : null;
|
|
929
|
+
},
|
|
930
|
+
"inset-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
931
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
932
|
+
return v !== null ? { left: v, right: v } : null;
|
|
933
|
+
},
|
|
934
|
+
"inset-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
935
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
936
|
+
return v !== null ? { top: v, bottom: v } : null;
|
|
937
|
+
},
|
|
938
|
+
// ── Translate ──────────────────────────────────────────────────────────────
|
|
939
|
+
"translate-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
940
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
941
|
+
if (v === null) return null;
|
|
942
|
+
if (getEffectiveIsWeb()) return { transform: `translateX(${typeof v === "number" ? `${v}px` : v})` };
|
|
943
|
+
if (typeof v === "string") {
|
|
944
|
+
const n = parseFloat(v);
|
|
945
|
+
return isNaN(n) ? null : { transform: [{ translateX: n }] };
|
|
946
|
+
}
|
|
947
|
+
return { transform: [{ translateX: v }] };
|
|
948
|
+
},
|
|
949
|
+
"translate-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
950
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
951
|
+
if (v === null) return null;
|
|
952
|
+
if (getEffectiveIsWeb()) return { transform: `translateY(${typeof v === "number" ? `${v}px` : v})` };
|
|
953
|
+
if (typeof v === "string") {
|
|
954
|
+
const n = parseFloat(v);
|
|
955
|
+
return isNaN(n) ? null : { transform: [{ translateY: n }] };
|
|
956
|
+
}
|
|
957
|
+
return { transform: [{ translateY: v }] };
|
|
958
|
+
},
|
|
959
|
+
// ── Space between ─────────────────────────────────────────────────────────
|
|
960
|
+
// On web: emits __spaceX/__spaceY markers → resolver generates > * + * CSS rules.
|
|
961
|
+
// On native (RN 0.71+): uses columnGap/rowGap directly.
|
|
962
|
+
"space-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
963
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
964
|
+
if (v === null) return null;
|
|
965
|
+
if (getEffectiveIsWeb()) return { __spaceX: v };
|
|
966
|
+
return { columnGap: v };
|
|
967
|
+
},
|
|
968
|
+
"space-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
969
|
+
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
970
|
+
if (v === null) return null;
|
|
971
|
+
if (getEffectiveIsWeb()) return { __spaceY: v };
|
|
972
|
+
return { rowGap: v };
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
for (const [utility, prop] of Object.entries(PADDING_MARGIN_PROPS)) {
|
|
976
|
+
spacingResolvers[utility] = makeSpacingResolver(prop);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
// src/core/resolvers/border.ts
|
|
756
980
|
function resolveRadius(value, radii, isArbitrary) {
|
|
757
981
|
if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
|
|
758
982
|
const key = value === "" ? "DEFAULT" : value;
|
|
759
983
|
return radii[key] ?? null;
|
|
760
984
|
}
|
|
761
|
-
function
|
|
762
|
-
|
|
763
|
-
|
|
985
|
+
function makeBorderSideResolver(widthProp, colorProp) {
|
|
986
|
+
return ({ value, isArbitrary }, { colors, borderWidth }) => {
|
|
987
|
+
if (!value) return { [widthProp]: 1 };
|
|
988
|
+
if (isArbitrary) {
|
|
989
|
+
const w2 = toNativeValue(value);
|
|
990
|
+
if (typeof w2 === "number") return { [widthProp]: w2 };
|
|
991
|
+
return { [colorProp]: value };
|
|
992
|
+
}
|
|
993
|
+
const color = resolveColor(value, colors, false);
|
|
994
|
+
if (color) return { [colorProp]: color };
|
|
995
|
+
const w = borderWidth[value];
|
|
996
|
+
return w !== void 0 ? { [widthProp]: w } : null;
|
|
997
|
+
};
|
|
764
998
|
}
|
|
765
|
-
var
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
773
|
-
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
774
|
-
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
775
|
-
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
776
|
-
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
777
|
-
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
778
|
-
// native either (null → no style applied → still display:'none').
|
|
779
|
-
flex: { display: "flex" },
|
|
780
|
-
block: web ? { display: "block" } : null,
|
|
781
|
-
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
782
|
-
inline: { display: web ? "inline" : "flex" },
|
|
783
|
-
grid: web ? { display: "grid" } : null,
|
|
784
|
-
grd: web ? { display: "grid" } : null,
|
|
785
|
-
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
786
|
-
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
787
|
-
hidden: { display: "none" },
|
|
788
|
-
contents: web ? { display: "contents" } : null,
|
|
789
|
-
"flow-root": web ? { display: "flow-root" } : null,
|
|
790
|
-
// Flex direction (both web and native)
|
|
791
|
-
"flex-row": { flexDirection: "row" },
|
|
792
|
-
"flex-col": { flexDirection: "column" },
|
|
793
|
-
"flex-row-reverse": { flexDirection: "row-reverse" },
|
|
794
|
-
"flex-col-reverse": { flexDirection: "column-reverse" },
|
|
795
|
-
// Flex wrap (both)
|
|
796
|
-
"flex-wrap": { flexWrap: "wrap" },
|
|
797
|
-
"flex-wrap-reverse": { flexWrap: "wrap-reverse" },
|
|
798
|
-
"flex-nowrap": { flexWrap: "nowrap" },
|
|
799
|
-
// Flex grow / shrink (both)
|
|
800
|
-
"flex-grow": { flexGrow: 1 },
|
|
801
|
-
"flex-grow-0": { flexGrow: 0 },
|
|
802
|
-
"flex-shrink": { flexShrink: 1 },
|
|
803
|
-
"flex-shrink-0": { flexShrink: 0 },
|
|
804
|
-
// Align items (both)
|
|
805
|
-
"items-start": { alignItems: "flex-start" },
|
|
806
|
-
"items-end": { alignItems: "flex-end" },
|
|
807
|
-
"items-center": { alignItems: "center" },
|
|
808
|
-
"items-baseline": { alignItems: "baseline" },
|
|
809
|
-
"items-stretch": { alignItems: "stretch" },
|
|
810
|
-
// Justify content (both)
|
|
811
|
-
"justify-start": { justifyContent: "flex-start" },
|
|
812
|
-
"justify-end": { justifyContent: "flex-end" },
|
|
813
|
-
"justify-center": { justifyContent: "center" },
|
|
814
|
-
"justify-between": { justifyContent: "space-between" },
|
|
815
|
-
"justify-around": { justifyContent: "space-around" },
|
|
816
|
-
"justify-evenly": { justifyContent: "space-evenly" },
|
|
817
|
-
// Align content (both)
|
|
818
|
-
"content-start": { alignContent: "flex-start" },
|
|
819
|
-
"content-end": { alignContent: "flex-end" },
|
|
820
|
-
"content-center": { alignContent: "center" },
|
|
821
|
-
"content-between": { alignContent: "space-between" },
|
|
822
|
-
"content-around": { alignContent: "space-around" },
|
|
823
|
-
"content-evenly": { alignContent: "space-evenly" },
|
|
824
|
-
"content-stretch": { alignContent: "stretch" },
|
|
825
|
-
// Align self (both)
|
|
826
|
-
"self-auto": { alignSelf: "auto" },
|
|
827
|
-
"self-start": { alignSelf: "flex-start" },
|
|
828
|
-
"self-end": { alignSelf: "flex-end" },
|
|
829
|
-
"self-center": { alignSelf: "center" },
|
|
830
|
-
"self-stretch": { alignSelf: "stretch" },
|
|
831
|
-
"self-baseline": { alignSelf: "baseline" },
|
|
832
|
-
// Text align (both)
|
|
833
|
-
"text-left": { textAlign: "left" },
|
|
834
|
-
"text-right": { textAlign: "right" },
|
|
835
|
-
"text-center": { textAlign: "center" },
|
|
836
|
-
"text-justify": { textAlign: "justify" },
|
|
837
|
-
// Font weight shortcuts (both)
|
|
838
|
-
"font-thin": { fontWeight: "100" },
|
|
839
|
-
"font-extralight": { fontWeight: "200" },
|
|
840
|
-
"font-light": { fontWeight: "300" },
|
|
841
|
-
"font-normal": { fontWeight: "400" },
|
|
842
|
-
"font-medium": { fontWeight: "500" },
|
|
843
|
-
"font-semibold": { fontWeight: "600" },
|
|
844
|
-
"font-bold": { fontWeight: "700" },
|
|
845
|
-
"font-extrabold": { fontWeight: "800" },
|
|
846
|
-
"font-black": { fontWeight: "900" },
|
|
847
|
-
// Text decoration (overline is web-only)
|
|
848
|
-
underline: { textDecorationLine: "underline" },
|
|
849
|
-
overline: web ? { textDecorationLine: "overline" } : null,
|
|
850
|
-
"line-through": { textDecorationLine: "line-through" },
|
|
851
|
-
"no-underline": { textDecorationLine: "none" },
|
|
852
|
-
// Text transform (both)
|
|
853
|
-
uppercase: { textTransform: "uppercase" },
|
|
854
|
-
lowercase: { textTransform: "lowercase" },
|
|
855
|
-
capitalize: { textTransform: "capitalize" },
|
|
856
|
-
"normal-case": { textTransform: "none" },
|
|
857
|
-
// Font style (both)
|
|
858
|
-
italic: { fontStyle: "italic" },
|
|
859
|
-
"non-italic": { fontStyle: "normal" },
|
|
860
|
-
// Position (fixed/sticky/static are web-only; RN only supports relative/absolute)
|
|
861
|
-
relative: { position: "relative" },
|
|
862
|
-
absolute: { position: "absolute" },
|
|
863
|
-
fixed: web ? { position: "fixed" } : null,
|
|
864
|
-
sticky: web ? { position: "sticky" } : null,
|
|
865
|
-
static: web ? { position: "static" } : null,
|
|
866
|
-
// Visibility (no `visibility` prop on native; use opacity instead)
|
|
867
|
-
visible: web ? { visibility: "visible" } : null,
|
|
868
|
-
invisible: web ? { visibility: "hidden" } : { opacity: 0 },
|
|
869
|
-
// Overflow (RN supports 'hidden' | 'visible' | 'scroll'; not 'auto')
|
|
870
|
-
"overflow-hidden": { overflow: "hidden" },
|
|
871
|
-
"overflow-visible": { overflow: "visible" },
|
|
872
|
-
"overflow-scroll": { overflow: "scroll" },
|
|
873
|
-
"overflow-auto": web ? { overflow: "auto" } : { overflow: "scroll" },
|
|
874
|
-
// overflowX / overflowY are web-only
|
|
875
|
-
"overflow-x-hidden": web ? { overflowX: "hidden" } : null,
|
|
876
|
-
"overflow-x-scroll": web ? { overflowX: "scroll" } : null,
|
|
877
|
-
"overflow-x-auto": web ? { overflowX: "auto" } : null,
|
|
878
|
-
"overflow-y-hidden": web ? { overflowY: "hidden" } : null,
|
|
879
|
-
"overflow-y-scroll": web ? { overflowY: "scroll" } : null,
|
|
880
|
-
"overflow-y-auto": web ? { overflowY: "auto" } : null,
|
|
881
|
-
// Object fit (web-only; use resizeMode prop on RN Image)
|
|
882
|
-
"object-contain": web ? { objectFit: "contain" } : null,
|
|
883
|
-
"object-cover": web ? { objectFit: "cover" } : null,
|
|
884
|
-
"object-fill": web ? { objectFit: "fill" } : null,
|
|
885
|
-
"object-none": web ? { objectFit: "none" } : null,
|
|
886
|
-
"object-scale-down": web ? { objectFit: "scale-down" } : null,
|
|
887
|
-
// Border style (both)
|
|
888
|
-
"border-solid": { borderStyle: "solid" },
|
|
889
|
-
"border-dashed": { borderStyle: "dashed" },
|
|
890
|
-
"border-dotted": { borderStyle: "dotted" },
|
|
891
|
-
"border-none": { borderWidth: 0 },
|
|
892
|
-
// Border sides default width (both)
|
|
893
|
-
"border-t": { borderTopWidth: 1 },
|
|
894
|
-
"border-r": { borderRightWidth: 1 },
|
|
895
|
-
"border-b": { borderBottomWidth: 1 },
|
|
896
|
-
"border-l": { borderLeftWidth: 1 },
|
|
897
|
-
// Cursor (web-only)
|
|
898
|
-
"cursor-auto": web ? { cursor: "auto" } : null,
|
|
899
|
-
"cursor-default": web ? { cursor: "default" } : null,
|
|
900
|
-
"cursor-pointer": web ? { cursor: "pointer" } : null,
|
|
901
|
-
"cursor-wait": web ? { cursor: "wait" } : null,
|
|
902
|
-
"cursor-text": web ? { cursor: "text" } : null,
|
|
903
|
-
"cursor-move": web ? { cursor: "move" } : null,
|
|
904
|
-
"cursor-not-allowed": web ? { cursor: "not-allowed" } : null,
|
|
905
|
-
// User select (web-only)
|
|
906
|
-
"select-none": web ? { userSelect: "none" } : null,
|
|
907
|
-
"select-text": web ? { userSelect: "text" } : null,
|
|
908
|
-
"select-all": web ? { userSelect: "all" } : null,
|
|
909
|
-
"select-auto": web ? { userSelect: "auto" } : null,
|
|
910
|
-
// Pointer events (both)
|
|
911
|
-
"pointer-events-none": { pointerEvents: "none" },
|
|
912
|
-
"pointer-events-auto": { pointerEvents: "auto" },
|
|
913
|
-
// Whitespace (web-only; RN Text uses numberOfLines prop instead)
|
|
914
|
-
"whitespace-normal": web ? { whiteSpace: "normal" } : null,
|
|
915
|
-
"whitespace-nowrap": web ? { whiteSpace: "nowrap" } : null,
|
|
916
|
-
"whitespace-pre": web ? { whiteSpace: "pre" } : null,
|
|
917
|
-
"whitespace-pre-wrap": web ? { whiteSpace: "pre-wrap" } : null,
|
|
918
|
-
"whitespace-pre-line": web ? { whiteSpace: "pre-line" } : null,
|
|
919
|
-
// Word break (web-only)
|
|
920
|
-
"break-normal": web ? { overflowWrap: "normal", wordBreak: "normal" } : null,
|
|
921
|
-
"break-words": web ? { overflowWrap: "break-word" } : null,
|
|
922
|
-
"break-all": web ? { wordBreak: "break-all" } : null,
|
|
923
|
-
// Misc web-only
|
|
924
|
-
truncate: web ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } : null,
|
|
925
|
-
"box-border": web ? { boxSizing: "border-box" } : null,
|
|
926
|
-
"box-content": web ? { boxSizing: "content-box" } : null,
|
|
927
|
-
"appearance-none": web ? { appearance: "none" } : null,
|
|
928
|
-
"outline-none": web ? { outline: "none", outlineOffset: "0" } : null,
|
|
929
|
-
outline: web ? { outline: "2px solid transparent", outlineOffset: "2px" } : null,
|
|
930
|
-
resize: web ? { resize: "both" } : null,
|
|
931
|
-
"resize-none": web ? { resize: "none" } : null,
|
|
932
|
-
"resize-y": web ? { resize: "vertical" } : null,
|
|
933
|
-
"resize-x": web ? { resize: "horizontal" } : null,
|
|
934
|
-
antialiased: web ? { WebkitFontSmoothing: "antialiased", MozOsxFontSmoothing: "grayscale" } : null,
|
|
935
|
-
"subpixel-antialiased": web ? { WebkitFontSmoothing: "subpixel-antialiased", MozOsxFontSmoothing: "auto" } : null,
|
|
936
|
-
"overflow-ellipsis": web ? { textOverflow: "ellipsis" } : null,
|
|
937
|
-
"sr-only": web ? {
|
|
938
|
-
position: "absolute",
|
|
939
|
-
width: 1,
|
|
940
|
-
height: 1,
|
|
941
|
-
padding: 0,
|
|
942
|
-
margin: -1,
|
|
943
|
-
overflow: "hidden",
|
|
944
|
-
clip: "rect(0,0,0,0)",
|
|
945
|
-
whiteSpace: "nowrap",
|
|
946
|
-
border: 0
|
|
947
|
-
} : null,
|
|
948
|
-
"not-sr-only": web ? {
|
|
949
|
-
position: "static",
|
|
950
|
-
width: "auto",
|
|
951
|
-
height: "auto",
|
|
952
|
-
padding: 0,
|
|
953
|
-
margin: 0,
|
|
954
|
-
overflow: "visible",
|
|
955
|
-
clip: "auto",
|
|
956
|
-
whiteSpace: "normal"
|
|
957
|
-
} : null,
|
|
958
|
-
// Lists (web-only)
|
|
959
|
-
"list-none": web ? { listStyleType: "none" } : null,
|
|
960
|
-
"list-disc": web ? { listStyleType: "disc" } : null,
|
|
961
|
-
"list-decimal": web ? { listStyleType: "decimal" } : null,
|
|
962
|
-
// Background clip (web-only)
|
|
963
|
-
"bg-clip-border": web ? { backgroundClip: "border-box" } : null,
|
|
964
|
-
"bg-clip-padding": web ? { backgroundClip: "padding-box" } : null,
|
|
965
|
-
"bg-clip-content": web ? { backgroundClip: "content-box" } : null,
|
|
966
|
-
"bg-clip-text": web ? { backgroundClip: "text", WebkitBackgroundClip: "text" } : null,
|
|
967
|
-
// Background image
|
|
968
|
-
"bg-none": web ? { backgroundImage: "none" } : null,
|
|
969
|
-
// Background size (web-only)
|
|
970
|
-
"bg-auto": web ? { backgroundSize: "auto" } : null,
|
|
971
|
-
"bg-cover": web ? { backgroundSize: "cover" } : null,
|
|
972
|
-
"bg-contain": web ? { backgroundSize: "contain" } : null,
|
|
973
|
-
// Background position (web-only)
|
|
974
|
-
"bg-center": web ? { backgroundPosition: "center" } : null,
|
|
975
|
-
"bg-top": web ? { backgroundPosition: "top" } : null,
|
|
976
|
-
"bg-bottom": web ? { backgroundPosition: "bottom" } : null,
|
|
977
|
-
"bg-left": web ? { backgroundPosition: "left" } : null,
|
|
978
|
-
"bg-right": web ? { backgroundPosition: "right" } : null,
|
|
979
|
-
"bg-left-top": web ? { backgroundPosition: "left top" } : null,
|
|
980
|
-
"bg-left-bottom": web ? { backgroundPosition: "left bottom" } : null,
|
|
981
|
-
"bg-right-top": web ? { backgroundPosition: "right top" } : null,
|
|
982
|
-
"bg-right-bottom": web ? { backgroundPosition: "right bottom" } : null,
|
|
983
|
-
// Background repeat (web-only)
|
|
984
|
-
"bg-repeat": web ? { backgroundRepeat: "repeat" } : null,
|
|
985
|
-
"bg-no-repeat": web ? { backgroundRepeat: "no-repeat" } : null,
|
|
986
|
-
"bg-repeat-x": web ? { backgroundRepeat: "repeat-x" } : null,
|
|
987
|
-
"bg-repeat-y": web ? { backgroundRepeat: "repeat-y" } : null,
|
|
988
|
-
"bg-repeat-round": web ? { backgroundRepeat: "round" } : null,
|
|
989
|
-
"bg-repeat-space": web ? { backgroundRepeat: "space" } : null,
|
|
990
|
-
// Background attachment (web-only)
|
|
991
|
-
"bg-fixed": web ? { backgroundAttachment: "fixed" } : null,
|
|
992
|
-
"bg-local": web ? { backgroundAttachment: "local" } : null,
|
|
993
|
-
"bg-scroll": web ? { backgroundAttachment: "scroll" } : null,
|
|
994
|
-
// Object position (web-only)
|
|
995
|
-
"object-center": web ? { objectPosition: "center" } : null,
|
|
996
|
-
"object-top": web ? { objectPosition: "top" } : null,
|
|
997
|
-
"object-bottom": web ? { objectPosition: "bottom" } : null,
|
|
998
|
-
"object-left": web ? { objectPosition: "left" } : null,
|
|
999
|
-
"object-right": web ? { objectPosition: "right" } : null,
|
|
1000
|
-
"object-left-top": web ? { objectPosition: "left top" } : null,
|
|
1001
|
-
"object-left-bottom": web ? { objectPosition: "left bottom" } : null,
|
|
1002
|
-
"object-right-top": web ? { objectPosition: "right top" } : null,
|
|
1003
|
-
"object-right-bottom": web ? { objectPosition: "right bottom" } : null,
|
|
1004
|
-
// Table (web-only)
|
|
1005
|
-
table: web ? { display: "table" } : null,
|
|
1006
|
-
"table-auto": web ? { tableLayout: "auto" } : null,
|
|
1007
|
-
"table-fixed": web ? { tableLayout: "fixed" } : null,
|
|
1008
|
-
"caption-top": web ? { captionSide: "top" } : null,
|
|
1009
|
-
"caption-bottom": web ? { captionSide: "bottom" } : null,
|
|
1010
|
-
"border-collapse": web ? { borderCollapse: "collapse" } : null,
|
|
1011
|
-
"border-separate": web ? { borderCollapse: "separate" } : null,
|
|
1012
|
-
// List style position (web-only)
|
|
1013
|
-
"list-inside": web ? { listStylePosition: "inside" } : null,
|
|
1014
|
-
"list-outside": web ? { listStylePosition: "outside" } : null,
|
|
1015
|
-
// Font variant numeric (web-only)
|
|
1016
|
-
"normal-nums": web ? { fontVariantNumeric: "normal" } : null,
|
|
1017
|
-
ordinal: web ? { fontVariantNumeric: "ordinal" } : null,
|
|
1018
|
-
"slashed-zero": web ? { fontVariantNumeric: "slashed-zero" } : null,
|
|
1019
|
-
"lining-nums": web ? { fontVariantNumeric: "lining-nums" } : null,
|
|
1020
|
-
"oldstyle-nums": web ? { fontVariantNumeric: "oldstyle-nums" } : null,
|
|
1021
|
-
"proportional-nums": web ? { fontVariantNumeric: "proportional-nums" } : null,
|
|
1022
|
-
"tabular-nums": web ? { fontVariantNumeric: "tabular-nums" } : null,
|
|
1023
|
-
"diagonal-fractions": web ? { fontVariantNumeric: "diagonal-fractions" } : null,
|
|
1024
|
-
"stacked-fractions": web ? { fontVariantNumeric: "stacked-fractions" } : null,
|
|
1025
|
-
// Isolation (web-only)
|
|
1026
|
-
isolate: web ? { isolation: "isolate" } : null,
|
|
1027
|
-
"isolation-auto": web ? { isolation: "auto" } : null,
|
|
1028
|
-
// Backface visibility (both iOS and Android)
|
|
1029
|
-
"backface-visible": { backfaceVisibility: "visible" },
|
|
1030
|
-
"backface-hidden": { backfaceVisibility: "hidden" },
|
|
1031
|
-
// CSS filters — standalone = default/full effect (web-only)
|
|
1032
|
-
grayscale: web ? { "--kb-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
|
|
1033
|
-
invert: web ? { "--kb-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
|
|
1034
|
-
sepia: web ? { "--kb-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
|
|
1035
|
-
// Divide none
|
|
1036
|
-
"divide-none": web ? { __divideX: 0, __divideY: 0 } : null,
|
|
1037
|
-
// Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
|
|
1038
|
-
group: web ? {} : null,
|
|
1039
|
-
peer: web ? {} : null,
|
|
1040
|
-
// Text-wrap (web-only)
|
|
1041
|
-
"text-wrap": web ? { textWrap: "wrap" } : null,
|
|
1042
|
-
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1043
|
-
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1044
|
-
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1045
|
-
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1046
|
-
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1047
|
-
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1048
|
-
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1049
|
-
// is unchanged since there's no dynamic chrome to account for.
|
|
1050
|
-
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1051
|
-
"w-screen": web ? { width: "100dvw" } : null,
|
|
1052
|
-
"min-h-screen": { minHeight: "100dvh" },
|
|
1053
|
-
"max-h-screen": { maxHeight: "100dvh" },
|
|
1054
|
-
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1055
|
-
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1056
|
-
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1057
|
-
"max-w-none": { maxWidth: "none" },
|
|
1058
|
-
"max-w-xs": { maxWidth: 320 },
|
|
1059
|
-
"max-w-sm": { maxWidth: 384 },
|
|
1060
|
-
"max-w-md": { maxWidth: 448 },
|
|
1061
|
-
"max-w-lg": { maxWidth: 512 },
|
|
1062
|
-
"max-w-xl": { maxWidth: 576 },
|
|
1063
|
-
"max-w-2xl": { maxWidth: 672 },
|
|
1064
|
-
"max-w-3xl": { maxWidth: 768 },
|
|
1065
|
-
"max-w-4xl": { maxWidth: 896 },
|
|
1066
|
-
"max-w-5xl": { maxWidth: 1024 },
|
|
1067
|
-
"max-w-6xl": { maxWidth: 1152 },
|
|
1068
|
-
"max-w-7xl": { maxWidth: 1280 },
|
|
1069
|
-
"max-w-prose": web ? { maxWidth: "65ch" } : null,
|
|
1070
|
-
// Extended cursors (web-only)
|
|
1071
|
-
"cursor-grab": web ? { cursor: "grab" } : null,
|
|
1072
|
-
"cursor-grabbing": web ? { cursor: "grabbing" } : null,
|
|
1073
|
-
"cursor-zoom-in": web ? { cursor: "zoom-in" } : null,
|
|
1074
|
-
"cursor-zoom-out": web ? { cursor: "zoom-out" } : null,
|
|
1075
|
-
"cursor-crosshair": web ? { cursor: "crosshair" } : null,
|
|
1076
|
-
"cursor-help": web ? { cursor: "help" } : null,
|
|
1077
|
-
"cursor-none": web ? { cursor: "none" } : null,
|
|
1078
|
-
// Overflow clip (web-only)
|
|
1079
|
-
"overflow-clip": web ? { overflow: "clip" } : null,
|
|
1080
|
-
"overflow-x-clip": web ? { overflowX: "clip" } : null,
|
|
1081
|
-
"overflow-y-clip": web ? { overflowY: "clip" } : null,
|
|
1082
|
-
// Scroll behavior (web-only)
|
|
1083
|
-
"scroll-smooth": web ? { scrollBehavior: "smooth" } : null,
|
|
1084
|
-
"scroll-auto": web ? { scrollBehavior: "auto" } : null,
|
|
1085
|
-
// Float (web-only)
|
|
1086
|
-
"float-left": web ? { float: "left" } : null,
|
|
1087
|
-
"float-right": web ? { float: "right" } : null,
|
|
1088
|
-
"float-start": web ? { float: "inline-start" } : null,
|
|
1089
|
-
"float-end": web ? { float: "inline-end" } : null,
|
|
1090
|
-
"float-none": web ? { float: "none" } : null,
|
|
1091
|
-
// Clear (web-only)
|
|
1092
|
-
"clear-left": web ? { clear: "left" } : null,
|
|
1093
|
-
"clear-right": web ? { clear: "right" } : null,
|
|
1094
|
-
"clear-both": web ? { clear: "both" } : null,
|
|
1095
|
-
"clear-start": web ? { clear: "inline-start" } : null,
|
|
1096
|
-
"clear-end": web ? { clear: "inline-end" } : null,
|
|
1097
|
-
"clear-none": web ? { clear: "none" } : null,
|
|
1098
|
-
// Vertical align (web-only)
|
|
1099
|
-
"align-baseline": web ? { verticalAlign: "baseline" } : null,
|
|
1100
|
-
"align-top": web ? { verticalAlign: "top" } : null,
|
|
1101
|
-
"align-middle": web ? { verticalAlign: "middle" } : null,
|
|
1102
|
-
"align-bottom": web ? { verticalAlign: "bottom" } : null,
|
|
1103
|
-
"align-text-top": web ? { verticalAlign: "text-top" } : null,
|
|
1104
|
-
"align-text-bottom": web ? { verticalAlign: "text-bottom" } : null,
|
|
1105
|
-
"align-sub": web ? { verticalAlign: "sub" } : null,
|
|
1106
|
-
"align-super": web ? { verticalAlign: "super" } : null,
|
|
1107
|
-
// Touch action (web-only)
|
|
1108
|
-
"touch-auto": web ? { touchAction: "auto" } : null,
|
|
1109
|
-
"touch-none": web ? { touchAction: "none" } : null,
|
|
1110
|
-
"touch-pan-x": web ? { touchAction: "pan-x" } : null,
|
|
1111
|
-
"touch-pan-y": web ? { touchAction: "pan-y" } : null,
|
|
1112
|
-
"touch-pan-left": web ? { touchAction: "pan-left" } : null,
|
|
1113
|
-
"touch-pan-right": web ? { touchAction: "pan-right" } : null,
|
|
1114
|
-
"touch-pan-up": web ? { touchAction: "pan-up" } : null,
|
|
1115
|
-
"touch-pan-down": web ? { touchAction: "pan-down" } : null,
|
|
1116
|
-
"touch-pinch-zoom": web ? { touchAction: "pinch-zoom" } : null,
|
|
1117
|
-
"touch-manipulation": web ? { touchAction: "manipulation" } : null
|
|
1118
|
-
};
|
|
1119
|
-
}
|
|
1120
|
-
function getStandalone() {
|
|
1121
|
-
if (!_standalone) _standalone = buildStandalone();
|
|
1122
|
-
return _standalone;
|
|
1123
|
-
}
|
|
1124
|
-
function makeSpacingResolver(prop) {
|
|
1125
|
-
return ({ value, negative, isArbitrary }, { spacing }) => {
|
|
1126
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
1127
|
-
return v !== null ? { [prop]: v } : null;
|
|
1128
|
-
};
|
|
1129
|
-
}
|
|
1130
|
-
var PADDING_MARGIN_PROPS = {
|
|
1131
|
-
p: "padding",
|
|
1132
|
-
px: "paddingHorizontal",
|
|
1133
|
-
py: "paddingVertical",
|
|
1134
|
-
pt: "paddingTop",
|
|
1135
|
-
pr: "paddingRight",
|
|
1136
|
-
pb: "paddingBottom",
|
|
1137
|
-
pl: "paddingLeft",
|
|
1138
|
-
m: "margin",
|
|
1139
|
-
mx: "marginHorizontal",
|
|
1140
|
-
my: "marginVertical",
|
|
1141
|
-
mt: "marginTop",
|
|
1142
|
-
mr: "marginRight",
|
|
1143
|
-
mb: "marginBottom",
|
|
1144
|
-
ml: "marginLeft"
|
|
1145
|
-
};
|
|
1146
|
-
function makeBorderSideResolver(widthProp, colorProp) {
|
|
1147
|
-
return ({ value, isArbitrary }, { colors, borderWidth }) => {
|
|
1148
|
-
if (!value) return { [widthProp]: 1 };
|
|
1149
|
-
if (isArbitrary) {
|
|
1150
|
-
const w2 = toNativeValue(value);
|
|
1151
|
-
if (typeof w2 === "number") return { [widthProp]: w2 };
|
|
1152
|
-
return { [colorProp]: value };
|
|
1153
|
-
}
|
|
1154
|
-
const color = resolveColor(value, colors, false);
|
|
1155
|
-
if (color) return { [colorProp]: color };
|
|
1156
|
-
const w = borderWidth[value];
|
|
1157
|
-
return w !== void 0 ? { [widthProp]: w } : null;
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
var BORDER_SIDE_PROPS = {
|
|
1161
|
-
"border-t": ["borderTopWidth", "borderTopColor"],
|
|
1162
|
-
"border-r": ["borderRightWidth", "borderRightColor"],
|
|
1163
|
-
"border-b": ["borderBottomWidth", "borderBottomColor"],
|
|
1164
|
-
"border-l": ["borderLeftWidth", "borderLeftColor"]
|
|
1165
|
-
};
|
|
1166
|
-
function keyframeDeclToCSS(decl) {
|
|
1167
|
-
return Object.entries(decl).map(([prop, val]) => `${prop.replace(/([A-Z])/g, "-$1").toLowerCase()}: ${val}`).join("; ");
|
|
1168
|
-
}
|
|
1169
|
-
function buildKeyframeCSS(name, steps) {
|
|
1170
|
-
const body = Object.entries(steps).map(([selector, decl]) => `${selector} { ${keyframeDeclToCSS(decl)} }`).join(" ");
|
|
1171
|
-
return `@keyframes ${name} { ${body} }`;
|
|
1172
|
-
}
|
|
1173
|
-
var BUILTIN_ANIMATIONS = {
|
|
1174
|
-
none: { animation: "none" },
|
|
1175
|
-
spin: {
|
|
1176
|
-
animation: "kb-spin 1s linear infinite",
|
|
1177
|
-
__keyframe: "@keyframes kb-spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }"
|
|
1178
|
-
},
|
|
1179
|
-
ping: {
|
|
1180
|
-
animation: "kb-ping 1s cubic-bezier(0,0,0.2,1) infinite",
|
|
1181
|
-
__keyframe: "@keyframes kb-ping { 75%, 100% { transform: scale(2); opacity: 0 } }"
|
|
1182
|
-
},
|
|
1183
|
-
pulse: {
|
|
1184
|
-
animation: "kb-pulse 2s cubic-bezier(0.4,0,0.6,1) infinite",
|
|
1185
|
-
__keyframe: "@keyframes kb-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }"
|
|
1186
|
-
},
|
|
1187
|
-
bounce: {
|
|
1188
|
-
animation: "kb-bounce 1s infinite",
|
|
1189
|
-
__keyframe: "@keyframes kb-bounce { 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8,0,1,1) } 50% { transform: none; animation-timing-function: cubic-bezier(0,0,0.2,1) } }"
|
|
1190
|
-
}
|
|
1191
|
-
};
|
|
1192
|
-
function buildAnimationValue(animation, keyframes) {
|
|
1193
|
-
const words = animation.trim().split(/\s+/);
|
|
1194
|
-
const name = words[0];
|
|
1195
|
-
if (!name) return { animation };
|
|
1196
|
-
const builtin = BUILTIN_ANIMATIONS[name];
|
|
1197
|
-
if (builtin?.__keyframe) {
|
|
1198
|
-
const kbName = builtin.animation.split(/\s+/, 1)[0];
|
|
1199
|
-
return { animation: [kbName, ...words.slice(1)].join(" "), __keyframe: builtin.__keyframe };
|
|
1200
|
-
}
|
|
1201
|
-
const steps = keyframes?.[name];
|
|
1202
|
-
return steps ? { animation, __keyframe: buildKeyframeCSS(name, steps) } : { animation };
|
|
1203
|
-
}
|
|
1204
|
-
var RESOLVERS = {
|
|
1205
|
-
// ── Background ─────────────────────────────────────────────────────────────
|
|
1206
|
-
bg: ({ value, isArbitrary }, { colors }) => {
|
|
1207
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1208
|
-
if (!color) return null;
|
|
1209
|
-
return { backgroundColor: getEffectiveIsWeb() ? withOpacityVar(color, "--bg-opacity") : color };
|
|
1210
|
-
},
|
|
1211
|
-
"bg-opacity": ({ value, isArbitrary }, _) => {
|
|
1212
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1213
|
-
const n = parseFloat(value);
|
|
1214
|
-
if (isNaN(n)) return null;
|
|
1215
|
-
const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
|
|
1216
|
-
return { "--bg-opacity": v };
|
|
1217
|
-
},
|
|
1218
|
-
// ── Text ───────────────────────────────────────────────────────────────────
|
|
1219
|
-
text: ({ value, isArbitrary }, { colors, fontSize }) => {
|
|
1220
|
-
const size = resolveFontSize(value, fontSize, false);
|
|
1221
|
-
if (!isArbitrary && size !== null) return { fontSize: size };
|
|
1222
|
-
if (isArbitrary) {
|
|
1223
|
-
if (/^\d/.test(value) || /^(calc|min|max|clamp)/.test(value)) {
|
|
1224
|
-
return { fontSize: getEffectiveIsWeb() ? value : toNativeValue(value) };
|
|
1225
|
-
}
|
|
1226
|
-
return { color: getEffectiveIsWeb() ? withOpacityVar(value, "--text-opacity") : value };
|
|
1227
|
-
}
|
|
1228
|
-
const color = resolveColor(value, colors, false);
|
|
1229
|
-
if (!color) return null;
|
|
1230
|
-
return { color: getEffectiveIsWeb() ? withOpacityVar(color, "--text-opacity") : color };
|
|
1231
|
-
},
|
|
1232
|
-
"text-opacity": ({ value, isArbitrary }, _) => {
|
|
1233
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1234
|
-
const n = parseFloat(value);
|
|
1235
|
-
if (isNaN(n)) return null;
|
|
1236
|
-
const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
|
|
1237
|
-
return { "--text-opacity": v };
|
|
1238
|
-
},
|
|
1239
|
-
// ── Padding & margin ───────────────────────────────────────────────────────
|
|
1240
|
-
// Generated below via makeSpacingResolver() — see PADDING_MARGIN_PROPS.
|
|
1241
|
-
// ── Sizing ─────────────────────────────────────────────────────────────────
|
|
1242
|
-
w: ({ value, isArbitrary }, { spacing }) => {
|
|
1243
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1244
|
-
return v !== null ? { width: v } : null;
|
|
1245
|
-
},
|
|
1246
|
-
h: ({ value, isArbitrary }, { spacing }) => {
|
|
1247
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1248
|
-
return v !== null ? { height: v } : null;
|
|
1249
|
-
},
|
|
1250
|
-
"min-w": ({ value, isArbitrary }, { spacing }) => {
|
|
1251
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1252
|
-
return v !== null ? { minWidth: v } : null;
|
|
1253
|
-
},
|
|
1254
|
-
"min-h": ({ value, isArbitrary }, { spacing }) => {
|
|
1255
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1256
|
-
return v !== null ? { minHeight: v } : null;
|
|
1257
|
-
},
|
|
1258
|
-
"max-w": ({ value, isArbitrary }, { spacing }) => {
|
|
1259
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1260
|
-
return v !== null ? { maxWidth: v } : null;
|
|
1261
|
-
},
|
|
1262
|
-
"max-h": ({ value, isArbitrary }, { spacing }) => {
|
|
1263
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1264
|
-
return v !== null ? { maxHeight: v } : null;
|
|
1265
|
-
},
|
|
999
|
+
var BORDER_SIDE_PROPS = {
|
|
1000
|
+
"border-t": ["borderTopWidth", "borderTopColor"],
|
|
1001
|
+
"border-r": ["borderRightWidth", "borderRightColor"],
|
|
1002
|
+
"border-b": ["borderBottomWidth", "borderBottomColor"],
|
|
1003
|
+
"border-l": ["borderLeftWidth", "borderLeftColor"]
|
|
1004
|
+
};
|
|
1005
|
+
var borderResolvers = {
|
|
1266
1006
|
// ── Border width ───────────────────────────────────────────────────────────
|
|
1267
1007
|
border: ({ value, isArbitrary }, { colors, borderWidth, spacing }) => {
|
|
1268
1008
|
if (!value) return { borderWidth: borderWidth["DEFAULT"] ?? 1 };
|
|
@@ -1319,188 +1059,128 @@ var RESOLVERS = {
|
|
|
1319
1059
|
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1320
1060
|
return r !== null ? { borderBottomRightRadius: r } : null;
|
|
1321
1061
|
},
|
|
1322
|
-
// ──
|
|
1323
|
-
|
|
1324
|
-
if (!value) return null;
|
|
1325
|
-
if (isArbitrary) return { display: "grid", gridTemplateColumns: value };
|
|
1326
|
-
const n = parseInt(value, 10);
|
|
1327
|
-
if (isNaN(n) || n < 1 || n > 12) return null;
|
|
1328
|
-
return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
|
|
1329
|
-
},
|
|
1330
|
-
// ── Grid template columns/rows (Tailwind-style aliases, web-only) ──────────
|
|
1331
|
-
"grid-cols": ({ value, isArbitrary }) => {
|
|
1062
|
+
// ── Outline extended (web-only) ───────────────────────────────────────────
|
|
1063
|
+
outline: ({ value, isArbitrary }, { colors }) => {
|
|
1332
1064
|
if (!getEffectiveIsWeb()) return null;
|
|
1333
|
-
if (!value) return
|
|
1334
|
-
if (
|
|
1335
|
-
if (
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1065
|
+
if (!value) return { outline: "2px solid transparent", outlineOffset: "2px" };
|
|
1066
|
+
if (value === "none") return { outline: "none", outlineOffset: "0" };
|
|
1067
|
+
if (isArbitrary) {
|
|
1068
|
+
if (/^\d/.test(value) || value.startsWith("calc(")) return { outlineWidth: value };
|
|
1069
|
+
return { outlineColor: value };
|
|
1070
|
+
}
|
|
1071
|
+
const widths = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
|
|
1072
|
+
if (value in widths) return { outlineWidth: widths[value] };
|
|
1073
|
+
const color = resolveColor(value, colors, false);
|
|
1074
|
+
return color ? { outlineColor: color } : null;
|
|
1339
1075
|
},
|
|
1340
|
-
"
|
|
1076
|
+
"outline-offset": ({ value, isArbitrary }) => {
|
|
1341
1077
|
if (!getEffectiveIsWeb()) return null;
|
|
1342
|
-
if (
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
const n = parseInt(value, 10);
|
|
1346
|
-
if (isNaN(n) || n < 1) return null;
|
|
1347
|
-
return { gridTemplateRows: `repeat(${n}, minmax(0, 1fr))` };
|
|
1078
|
+
if (isArbitrary) return { outlineOffset: value };
|
|
1079
|
+
const offsets = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
|
|
1080
|
+
return offsets[value] ? { outlineOffset: offsets[value] } : null;
|
|
1348
1081
|
},
|
|
1349
|
-
// ──
|
|
1350
|
-
|
|
1082
|
+
// ── Divide (child combinator CSS, web-only) ───────────────────────────────
|
|
1083
|
+
// These return special __divide* markers that resolver.ts converts to
|
|
1084
|
+
// .cls > * + * { border-... } CSS rules. No inline style is applied.
|
|
1085
|
+
"divide-x": ({ value, isArbitrary }) => {
|
|
1351
1086
|
if (!getEffectiveIsWeb()) return null;
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
"row-dense": "row dense",
|
|
1357
|
-
"col-dense": "column dense"
|
|
1358
|
-
};
|
|
1359
|
-
const flow = flows[value];
|
|
1360
|
-
return flow ? { gridAutoFlow: flow } : null;
|
|
1087
|
+
if (value === "reverse") return null;
|
|
1088
|
+
if (!value) return { __divideX: 1 };
|
|
1089
|
+
const n = parseFloat(value);
|
|
1090
|
+
return isNaN(n) ? null : { __divideX: n };
|
|
1361
1091
|
},
|
|
1362
|
-
|
|
1363
|
-
"auto-cols": ({ value, isArbitrary }) => {
|
|
1092
|
+
"divide-y": ({ value, isArbitrary }) => {
|
|
1364
1093
|
if (!getEffectiveIsWeb()) return null;
|
|
1365
|
-
if (
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
max: "max-content",
|
|
1370
|
-
fr: "minmax(0, 1fr)"
|
|
1371
|
-
};
|
|
1372
|
-
const v = presets[value];
|
|
1373
|
-
return v ? { gridAutoColumns: v } : null;
|
|
1094
|
+
if (value === "reverse") return null;
|
|
1095
|
+
if (!value) return { __divideY: 1 };
|
|
1096
|
+
const n = parseFloat(value);
|
|
1097
|
+
return isNaN(n) ? null : { __divideY: n };
|
|
1374
1098
|
},
|
|
1375
|
-
|
|
1099
|
+
divide: ({ value, isArbitrary }, { colors }) => {
|
|
1376
1100
|
if (!getEffectiveIsWeb()) return null;
|
|
1377
|
-
if (isArbitrary) return {
|
|
1378
|
-
const
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1101
|
+
if (isArbitrary) return { __divideColor: value };
|
|
1102
|
+
const styleTokens = {
|
|
1103
|
+
solid: "solid",
|
|
1104
|
+
dashed: "dashed",
|
|
1105
|
+
dotted: "dotted",
|
|
1106
|
+
double: "double",
|
|
1107
|
+
none: "none"
|
|
1383
1108
|
};
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
// ── Grid column placement (web-only) ──────────────────────────────────────
|
|
1388
|
-
"col-span": ({ value }) => {
|
|
1389
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1390
|
-
if (value === "full") return { gridColumn: "1 / -1" };
|
|
1391
|
-
const n = parseInt(value, 10);
|
|
1392
|
-
return isNaN(n) ? null : { gridColumn: `span ${n} / span ${n}` };
|
|
1393
|
-
},
|
|
1394
|
-
"col-start": ({ value, isArbitrary }) => {
|
|
1395
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1396
|
-
if (value === "auto") return { gridColumnStart: "auto" };
|
|
1397
|
-
if (isArbitrary) return { gridColumnStart: value };
|
|
1398
|
-
const n = parseInt(value, 10);
|
|
1399
|
-
return isNaN(n) ? null : { gridColumnStart: n };
|
|
1400
|
-
},
|
|
1401
|
-
"col-end": ({ value, isArbitrary }) => {
|
|
1402
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1403
|
-
if (value === "auto") return { gridColumnEnd: "auto" };
|
|
1404
|
-
if (isArbitrary) return { gridColumnEnd: value };
|
|
1405
|
-
const n = parseInt(value, 10);
|
|
1406
|
-
return isNaN(n) ? null : { gridColumnEnd: n };
|
|
1407
|
-
},
|
|
1408
|
-
col: ({ value, isArbitrary }) => {
|
|
1409
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1410
|
-
if (!value || value === "auto") return { gridColumn: "auto" };
|
|
1411
|
-
if (isArbitrary) return { gridColumn: value };
|
|
1412
|
-
return null;
|
|
1413
|
-
},
|
|
1414
|
-
// ── Grid row placement (web-only) ─────────────────────────────────────────
|
|
1415
|
-
"row-span": ({ value }) => {
|
|
1416
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1417
|
-
if (value === "full") return { gridRow: "1 / -1" };
|
|
1418
|
-
const n = parseInt(value, 10);
|
|
1419
|
-
return isNaN(n) ? null : { gridRow: `span ${n} / span ${n}` };
|
|
1420
|
-
},
|
|
1421
|
-
"row-start": ({ value, isArbitrary }) => {
|
|
1422
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1423
|
-
if (value === "auto") return { gridRowStart: "auto" };
|
|
1424
|
-
if (isArbitrary) return { gridRowStart: value };
|
|
1425
|
-
const n = parseInt(value, 10);
|
|
1426
|
-
return isNaN(n) ? null : { gridRowStart: n };
|
|
1427
|
-
},
|
|
1428
|
-
"row-end": ({ value, isArbitrary }) => {
|
|
1429
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1430
|
-
if (value === "auto") return { gridRowEnd: "auto" };
|
|
1431
|
-
if (isArbitrary) return { gridRowEnd: value };
|
|
1432
|
-
const n = parseInt(value, 10);
|
|
1433
|
-
return isNaN(n) ? null : { gridRowEnd: n };
|
|
1109
|
+
if (value in styleTokens) return { __divideStyle: styleTokens[value] };
|
|
1110
|
+
const color = resolveColor(value, colors, false);
|
|
1111
|
+
return color ? { __divideColor: color } : null;
|
|
1434
1112
|
},
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1113
|
+
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
1114
|
+
// Web: box-shadow outline ring (doesn't affect layout).
|
|
1115
|
+
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
1116
|
+
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
1117
|
+
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
1118
|
+
// and it shares its properties with the `border` utility — combining
|
|
1119
|
+
// `border-*` and `ring-*` on the same native element means whichever class
|
|
1120
|
+
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
1121
|
+
ring: ({ value, isArbitrary }, { colors }) => {
|
|
1122
|
+
const onWeb = getEffectiveIsWeb();
|
|
1123
|
+
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
1124
|
+
const DEFAULT_WIDTH = 3;
|
|
1125
|
+
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
1126
|
+
if (!value) {
|
|
1127
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
1128
|
+
}
|
|
1129
|
+
if (value === "inset") {
|
|
1130
|
+
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
1131
|
+
}
|
|
1132
|
+
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
1133
|
+
if (!isArbitrary && value in widthTokens) {
|
|
1134
|
+
const w = widthTokens[value];
|
|
1135
|
+
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
1136
|
+
}
|
|
1137
|
+
if (isArbitrary) {
|
|
1138
|
+
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
1139
|
+
if (numMatch) {
|
|
1140
|
+
const unit = numMatch[2] ?? "px";
|
|
1141
|
+
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
1142
|
+
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
1143
|
+
}
|
|
1144
|
+
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
1145
|
+
}
|
|
1146
|
+
const color = resolveColor(value, colors, false);
|
|
1147
|
+
if (color) {
|
|
1148
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
1149
|
+
}
|
|
1439
1150
|
return null;
|
|
1440
1151
|
},
|
|
1441
|
-
//
|
|
1442
|
-
//
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
end: "end",
|
|
1448
|
-
center: "center",
|
|
1449
|
-
stretch: "stretch",
|
|
1450
|
-
baseline: "baseline"
|
|
1451
|
-
};
|
|
1452
|
-
return map[value] ? { placeItems: map[value] } : null;
|
|
1453
|
-
},
|
|
1454
|
-
// place-content is shorthand for align-content + justify-content on a grid container
|
|
1455
|
-
"place-content": ({ value }) => {
|
|
1456
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1457
|
-
const map = {
|
|
1458
|
-
start: "start",
|
|
1459
|
-
end: "end",
|
|
1460
|
-
center: "center",
|
|
1461
|
-
stretch: "stretch",
|
|
1462
|
-
between: "space-between",
|
|
1463
|
-
around: "space-around",
|
|
1464
|
-
evenly: "space-evenly",
|
|
1465
|
-
baseline: "baseline"
|
|
1466
|
-
};
|
|
1467
|
-
return map[value] ? { placeContent: map[value] } : null;
|
|
1468
|
-
},
|
|
1469
|
-
// justify-items controls inline-axis alignment of grid items within their cells
|
|
1470
|
-
"justify-items": ({ value }) => {
|
|
1471
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1472
|
-
const map = {
|
|
1473
|
-
start: "start",
|
|
1474
|
-
end: "end",
|
|
1475
|
-
center: "center",
|
|
1476
|
-
stretch: "stretch"
|
|
1477
|
-
};
|
|
1478
|
-
return map[value] ? { justifyItems: map[value] } : null;
|
|
1479
|
-
},
|
|
1480
|
-
// place-self is shorthand for align-self + justify-self on a grid item
|
|
1481
|
-
"place-self": ({ value }) => {
|
|
1482
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1483
|
-
const map = {
|
|
1484
|
-
auto: "auto",
|
|
1485
|
-
start: "start",
|
|
1486
|
-
end: "end",
|
|
1487
|
-
center: "center",
|
|
1488
|
-
stretch: "stretch"
|
|
1489
|
-
};
|
|
1490
|
-
return map[value] ? { placeSelf: map[value] } : null;
|
|
1491
|
-
},
|
|
1492
|
-
// justify-self controls inline-axis self-alignment of a grid item
|
|
1493
|
-
"justify-self": ({ value }) => {
|
|
1152
|
+
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
1153
|
+
// create a gap between the element and the ring. There's no native
|
|
1154
|
+
// equivalent to approximate that with (a border can't create a gap outside
|
|
1155
|
+
// its own element without an extra wrapper view), so this stays a no-op
|
|
1156
|
+
// on native rather than rendering a misleading half-translation.
|
|
1157
|
+
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
1494
1158
|
if (!getEffectiveIsWeb()) return null;
|
|
1495
|
-
const
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1159
|
+
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
1160
|
+
const DEFAULT_RING_WIDTH = 3;
|
|
1161
|
+
const offsetTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
1162
|
+
let offsetWidth;
|
|
1163
|
+
if (!isArbitrary) {
|
|
1164
|
+
offsetWidth = value in offsetTokens ? offsetTokens[value] : null;
|
|
1165
|
+
} else {
|
|
1166
|
+
offsetWidth = /^-?\d+(\.\d+)?$/.test(value) ? parseFloat(value) : value;
|
|
1167
|
+
}
|
|
1168
|
+
if (offsetWidth === null || typeof offsetWidth === "number" && isNaN(offsetWidth)) return null;
|
|
1169
|
+
const isZero = offsetWidth === 0 || offsetWidth === "0";
|
|
1170
|
+
const offsetCss = typeof offsetWidth === "number" ? `${offsetWidth}px` : offsetWidth;
|
|
1171
|
+
return {
|
|
1172
|
+
boxShadow: isZero ? `0 0 0 ${DEFAULT_RING_WIDTH}px ${DEFAULT_RING_COLOR}` : `0 0 0 ${offsetCss} #fff, 0 0 0 calc(${offsetCss} + ${DEFAULT_RING_WIDTH}px) ${DEFAULT_RING_COLOR}`
|
|
1501
1173
|
};
|
|
1502
|
-
|
|
1503
|
-
|
|
1174
|
+
}
|
|
1175
|
+
};
|
|
1176
|
+
for (const [utility, [widthProp, colorProp]] of Object.entries(BORDER_SIDE_PROPS)) {
|
|
1177
|
+
borderResolvers[utility] = makeBorderSideResolver(widthProp, colorProp);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// src/core/resolvers/filters.ts
|
|
1181
|
+
var FILTER_COMPOSE = "var(--kb-blur,) var(--kb-brightness,) var(--kb-contrast,) var(--kb-grayscale,) var(--kb-hue-rotate,) var(--kb-invert,) var(--kb-saturate,) var(--kb-sepia,) var(--kb-drop-shadow,)";
|
|
1182
|
+
var BACKDROP_FILTER_COMPOSE = "var(--kb-backdrop-blur,) var(--kb-backdrop-brightness,) var(--kb-backdrop-contrast,) var(--kb-backdrop-grayscale,) var(--kb-backdrop-hue-rotate,) var(--kb-backdrop-invert,) var(--kb-backdrop-opacity,) var(--kb-backdrop-saturate,) var(--kb-backdrop-sepia,)";
|
|
1183
|
+
var filterResolvers = {
|
|
1504
1184
|
// ── CSS Filters (composable via CSS variables, web-only) ─────────────────
|
|
1505
1185
|
blur: ({ value, isArbitrary }) => {
|
|
1506
1186
|
if (!getEffectiveIsWeb()) return null;
|
|
@@ -1635,410 +1315,606 @@ var RESOLVERS = {
|
|
|
1635
1315
|
if (value === "none") return { backdropFilter: "none" };
|
|
1636
1316
|
return null;
|
|
1637
1317
|
},
|
|
1638
|
-
// ──
|
|
1639
|
-
"
|
|
1640
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1641
|
-
const directions = {
|
|
1642
|
-
t: "to top",
|
|
1643
|
-
tr: "to top right",
|
|
1644
|
-
r: "to right",
|
|
1645
|
-
br: "to bottom right",
|
|
1646
|
-
b: "to bottom",
|
|
1647
|
-
bl: "to bottom left",
|
|
1648
|
-
l: "to left",
|
|
1649
|
-
tl: "to top left"
|
|
1650
|
-
};
|
|
1651
|
-
const dir = directions[value];
|
|
1652
|
-
if (!dir) return null;
|
|
1653
|
-
return {
|
|
1654
|
-
backgroundImage: `linear-gradient(${dir}, var(--kb-gradient-from, transparent), var(--kb-gradient-stops, transparent))`
|
|
1655
|
-
};
|
|
1656
|
-
},
|
|
1657
|
-
from: ({ value, isArbitrary }, { colors }) => {
|
|
1658
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1659
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1660
|
-
if (!color) return null;
|
|
1661
|
-
return {
|
|
1662
|
-
"--kb-gradient-from": color,
|
|
1663
|
-
"--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-to, transparent)`
|
|
1664
|
-
};
|
|
1665
|
-
},
|
|
1666
|
-
via: ({ value, isArbitrary }, { colors }) => {
|
|
1667
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1668
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1669
|
-
if (!color) return null;
|
|
1670
|
-
return {
|
|
1671
|
-
"--kb-gradient-via": color,
|
|
1672
|
-
"--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-via), var(--kb-gradient-to, transparent)`
|
|
1673
|
-
};
|
|
1674
|
-
},
|
|
1675
|
-
to: ({ value, isArbitrary }, { colors }) => {
|
|
1676
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1677
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1678
|
-
if (!color) return null;
|
|
1679
|
-
return { "--kb-gradient-to": color };
|
|
1680
|
-
},
|
|
1681
|
-
// ── Transform extras (web-only) ───────────────────────────────────────────
|
|
1682
|
-
"skew-x": ({ value, negative, isArbitrary }) => {
|
|
1683
|
-
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
1684
|
-
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
1685
|
-
return getEffectiveIsWeb() ? { transform: `skewX(${deg})` } : { transform: [{ skewX: deg }] };
|
|
1686
|
-
},
|
|
1687
|
-
"skew-y": ({ value, negative, isArbitrary }) => {
|
|
1688
|
-
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
1689
|
-
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
1690
|
-
return getEffectiveIsWeb() ? { transform: `skewY(${deg})` } : { transform: [{ skewY: deg }] };
|
|
1691
|
-
},
|
|
1692
|
-
// Arbitrary full transform string: transform-[rotate(45deg)_scale(1.5)]
|
|
1693
|
-
transform: ({ value, isArbitrary }) => {
|
|
1694
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1695
|
-
if (isArbitrary) return { transform: value.replace(/_/g, " ") };
|
|
1696
|
-
if (value === "none") return { transform: "none" };
|
|
1697
|
-
return null;
|
|
1698
|
-
},
|
|
1699
|
-
// Transform origin
|
|
1700
|
-
origin: ({ value, isArbitrary }) => {
|
|
1318
|
+
// ── Mix / background blend mode (web-only) ───────────────────────────────
|
|
1319
|
+
"mix-blend": ({ value }) => {
|
|
1701
1320
|
if (!getEffectiveIsWeb()) return null;
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
"
|
|
1707
|
-
|
|
1708
|
-
"
|
|
1709
|
-
|
|
1710
|
-
"
|
|
1711
|
-
|
|
1712
|
-
"
|
|
1713
|
-
|
|
1714
|
-
|
|
1321
|
+
const modes = [
|
|
1322
|
+
"normal",
|
|
1323
|
+
"multiply",
|
|
1324
|
+
"screen",
|
|
1325
|
+
"overlay",
|
|
1326
|
+
"darken",
|
|
1327
|
+
"lighten",
|
|
1328
|
+
"color-dodge",
|
|
1329
|
+
"color-burn",
|
|
1330
|
+
"hard-light",
|
|
1331
|
+
"soft-light",
|
|
1332
|
+
"difference",
|
|
1333
|
+
"exclusion",
|
|
1334
|
+
"hue",
|
|
1335
|
+
"saturation",
|
|
1336
|
+
"color",
|
|
1337
|
+
"luminosity",
|
|
1338
|
+
"plus-lighter"
|
|
1339
|
+
];
|
|
1340
|
+
return modes.includes(value) ? { mixBlendMode: value } : null;
|
|
1715
1341
|
},
|
|
1716
|
-
|
|
1717
|
-
decoration: ({ value, isArbitrary }, { colors }) => {
|
|
1342
|
+
"bg-blend": ({ value }) => {
|
|
1718
1343
|
if (!getEffectiveIsWeb()) return null;
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
"
|
|
1726
|
-
"
|
|
1727
|
-
"
|
|
1728
|
-
"
|
|
1729
|
-
"
|
|
1730
|
-
"
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
wavy: "wavy"
|
|
1739
|
-
};
|
|
1740
|
-
if (value in styleTokens) return { textDecorationStyle: styleTokens[value] };
|
|
1741
|
-
const color = resolveColor(value, colors, false);
|
|
1742
|
-
return color ? { textDecorationColor: color } : null;
|
|
1344
|
+
const modes = [
|
|
1345
|
+
"normal",
|
|
1346
|
+
"multiply",
|
|
1347
|
+
"screen",
|
|
1348
|
+
"overlay",
|
|
1349
|
+
"darken",
|
|
1350
|
+
"lighten",
|
|
1351
|
+
"color-dodge",
|
|
1352
|
+
"color-burn",
|
|
1353
|
+
"hard-light",
|
|
1354
|
+
"soft-light",
|
|
1355
|
+
"difference",
|
|
1356
|
+
"exclusion",
|
|
1357
|
+
"hue",
|
|
1358
|
+
"saturation",
|
|
1359
|
+
"color",
|
|
1360
|
+
"luminosity"
|
|
1361
|
+
];
|
|
1362
|
+
return modes.includes(value) ? { backgroundBlendMode: value } : null;
|
|
1743
1363
|
},
|
|
1744
|
-
|
|
1364
|
+
// ── Will-change (web-only) ─────────────────────────────────────────────────
|
|
1365
|
+
"will-change": ({ value, isArbitrary }) => {
|
|
1745
1366
|
if (!getEffectiveIsWeb()) return null;
|
|
1746
|
-
if (isArbitrary) return {
|
|
1747
|
-
const
|
|
1367
|
+
if (isArbitrary) return { willChange: value.replace(/_/g, ", ") };
|
|
1368
|
+
const presets = {
|
|
1748
1369
|
auto: "auto",
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
"4": "4px",
|
|
1753
|
-
"8": "8px"
|
|
1370
|
+
scroll: "scroll-position",
|
|
1371
|
+
contents: "contents",
|
|
1372
|
+
transform: "transform"
|
|
1754
1373
|
};
|
|
1755
|
-
return
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1374
|
+
return presets[value] ? { willChange: presets[value] } : null;
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
// src/core/resolvers/layout.ts
|
|
1379
|
+
var _standalone = null;
|
|
1380
|
+
function buildStandalone() {
|
|
1381
|
+
const web = getEffectiveIsWeb();
|
|
1382
|
+
return {
|
|
1383
|
+
// Display
|
|
1384
|
+
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
1385
|
+
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
1386
|
+
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
1387
|
+
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
1388
|
+
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
1389
|
+
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
1390
|
+
// native either (null → no style applied → still display:'none').
|
|
1391
|
+
flex: { display: "flex" },
|
|
1392
|
+
block: web ? { display: "block" } : null,
|
|
1393
|
+
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
1394
|
+
inline: { display: web ? "inline" : "flex" },
|
|
1395
|
+
grid: web ? { display: "grid" } : null,
|
|
1396
|
+
grd: web ? { display: "grid" } : null,
|
|
1397
|
+
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
1398
|
+
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
1399
|
+
hidden: { display: "none" },
|
|
1400
|
+
contents: web ? { display: "contents" } : null,
|
|
1401
|
+
"flow-root": web ? { display: "flow-root" } : null,
|
|
1402
|
+
// Flex direction (both web and native)
|
|
1403
|
+
"flex-row": { flexDirection: "row" },
|
|
1404
|
+
"flex-col": { flexDirection: "column" },
|
|
1405
|
+
"flex-row-reverse": { flexDirection: "row-reverse" },
|
|
1406
|
+
"flex-col-reverse": { flexDirection: "column-reverse" },
|
|
1407
|
+
// Flex wrap (both)
|
|
1408
|
+
"flex-wrap": { flexWrap: "wrap" },
|
|
1409
|
+
"flex-wrap-reverse": { flexWrap: "wrap-reverse" },
|
|
1410
|
+
"flex-nowrap": { flexWrap: "nowrap" },
|
|
1411
|
+
// Flex grow / shrink (both)
|
|
1412
|
+
"flex-grow": { flexGrow: 1 },
|
|
1413
|
+
"flex-grow-0": { flexGrow: 0 },
|
|
1414
|
+
"flex-shrink": { flexShrink: 1 },
|
|
1415
|
+
"flex-shrink-0": { flexShrink: 0 },
|
|
1416
|
+
// Align items (both)
|
|
1417
|
+
"items-start": { alignItems: "flex-start" },
|
|
1418
|
+
"items-end": { alignItems: "flex-end" },
|
|
1419
|
+
"items-center": { alignItems: "center" },
|
|
1420
|
+
"items-baseline": { alignItems: "baseline" },
|
|
1421
|
+
"items-stretch": { alignItems: "stretch" },
|
|
1422
|
+
// Justify content (both)
|
|
1423
|
+
"justify-start": { justifyContent: "flex-start" },
|
|
1424
|
+
"justify-end": { justifyContent: "flex-end" },
|
|
1425
|
+
"justify-center": { justifyContent: "center" },
|
|
1426
|
+
"justify-between": { justifyContent: "space-between" },
|
|
1427
|
+
"justify-around": { justifyContent: "space-around" },
|
|
1428
|
+
"justify-evenly": { justifyContent: "space-evenly" },
|
|
1429
|
+
// Align content (both)
|
|
1430
|
+
"content-start": { alignContent: "flex-start" },
|
|
1431
|
+
"content-end": { alignContent: "flex-end" },
|
|
1432
|
+
"content-center": { alignContent: "center" },
|
|
1433
|
+
"content-between": { alignContent: "space-between" },
|
|
1434
|
+
"content-around": { alignContent: "space-around" },
|
|
1435
|
+
"content-evenly": { alignContent: "space-evenly" },
|
|
1436
|
+
"content-stretch": { alignContent: "stretch" },
|
|
1437
|
+
// Align self (both)
|
|
1438
|
+
"self-auto": { alignSelf: "auto" },
|
|
1439
|
+
"self-start": { alignSelf: "flex-start" },
|
|
1440
|
+
"self-end": { alignSelf: "flex-end" },
|
|
1441
|
+
"self-center": { alignSelf: "center" },
|
|
1442
|
+
"self-stretch": { alignSelf: "stretch" },
|
|
1443
|
+
"self-baseline": { alignSelf: "baseline" },
|
|
1444
|
+
// Text align (both)
|
|
1445
|
+
"text-left": { textAlign: "left" },
|
|
1446
|
+
"text-right": { textAlign: "right" },
|
|
1447
|
+
"text-center": { textAlign: "center" },
|
|
1448
|
+
"text-justify": { textAlign: "justify" },
|
|
1449
|
+
// Font weight shortcuts (both)
|
|
1450
|
+
"font-thin": { fontWeight: "100" },
|
|
1451
|
+
"font-extralight": { fontWeight: "200" },
|
|
1452
|
+
"font-light": { fontWeight: "300" },
|
|
1453
|
+
"font-normal": { fontWeight: "400" },
|
|
1454
|
+
"font-medium": { fontWeight: "500" },
|
|
1455
|
+
"font-semibold": { fontWeight: "600" },
|
|
1456
|
+
"font-bold": { fontWeight: "700" },
|
|
1457
|
+
"font-extrabold": { fontWeight: "800" },
|
|
1458
|
+
"font-black": { fontWeight: "900" },
|
|
1459
|
+
// Text decoration (overline is web-only)
|
|
1460
|
+
underline: { textDecorationLine: "underline" },
|
|
1461
|
+
overline: web ? { textDecorationLine: "overline" } : null,
|
|
1462
|
+
"line-through": { textDecorationLine: "line-through" },
|
|
1463
|
+
"no-underline": { textDecorationLine: "none" },
|
|
1464
|
+
// Text transform (both)
|
|
1465
|
+
uppercase: { textTransform: "uppercase" },
|
|
1466
|
+
lowercase: { textTransform: "lowercase" },
|
|
1467
|
+
capitalize: { textTransform: "capitalize" },
|
|
1468
|
+
"normal-case": { textTransform: "none" },
|
|
1469
|
+
// Font style (both)
|
|
1470
|
+
italic: { fontStyle: "italic" },
|
|
1471
|
+
"non-italic": { fontStyle: "normal" },
|
|
1472
|
+
// Position (fixed/sticky/static are web-only; RN only supports relative/absolute)
|
|
1473
|
+
relative: { position: "relative" },
|
|
1474
|
+
absolute: { position: "absolute" },
|
|
1475
|
+
fixed: web ? { position: "fixed" } : null,
|
|
1476
|
+
sticky: web ? { position: "sticky" } : null,
|
|
1477
|
+
static: web ? { position: "static" } : null,
|
|
1478
|
+
// Visibility (no `visibility` prop on native; use opacity instead)
|
|
1479
|
+
visible: web ? { visibility: "visible" } : null,
|
|
1480
|
+
invisible: web ? { visibility: "hidden" } : { opacity: 0 },
|
|
1481
|
+
// Overflow (RN supports 'hidden' | 'visible' | 'scroll'; not 'auto')
|
|
1482
|
+
"overflow-hidden": { overflow: "hidden" },
|
|
1483
|
+
"overflow-visible": { overflow: "visible" },
|
|
1484
|
+
"overflow-scroll": { overflow: "scroll" },
|
|
1485
|
+
"overflow-auto": web ? { overflow: "auto" } : { overflow: "scroll" },
|
|
1486
|
+
// overflowX / overflowY are web-only
|
|
1487
|
+
"overflow-x-hidden": web ? { overflowX: "hidden" } : null,
|
|
1488
|
+
"overflow-x-scroll": web ? { overflowX: "scroll" } : null,
|
|
1489
|
+
"overflow-x-auto": web ? { overflowX: "auto" } : null,
|
|
1490
|
+
"overflow-y-hidden": web ? { overflowY: "hidden" } : null,
|
|
1491
|
+
"overflow-y-scroll": web ? { overflowY: "scroll" } : null,
|
|
1492
|
+
"overflow-y-auto": web ? { overflowY: "auto" } : null,
|
|
1493
|
+
// Object fit (web-only; use resizeMode prop on RN Image)
|
|
1494
|
+
"object-contain": web ? { objectFit: "contain" } : null,
|
|
1495
|
+
"object-cover": web ? { objectFit: "cover" } : null,
|
|
1496
|
+
"object-fill": web ? { objectFit: "fill" } : null,
|
|
1497
|
+
"object-none": web ? { objectFit: "none" } : null,
|
|
1498
|
+
"object-scale-down": web ? { objectFit: "scale-down" } : null,
|
|
1499
|
+
// Border style (both)
|
|
1500
|
+
"border-solid": { borderStyle: "solid" },
|
|
1501
|
+
"border-dashed": { borderStyle: "dashed" },
|
|
1502
|
+
"border-dotted": { borderStyle: "dotted" },
|
|
1503
|
+
"border-none": { borderWidth: 0 },
|
|
1504
|
+
// Border sides default width (both)
|
|
1505
|
+
"border-t": { borderTopWidth: 1 },
|
|
1506
|
+
"border-r": { borderRightWidth: 1 },
|
|
1507
|
+
"border-b": { borderBottomWidth: 1 },
|
|
1508
|
+
"border-l": { borderLeftWidth: 1 },
|
|
1509
|
+
// Cursor (web-only)
|
|
1510
|
+
"cursor-auto": web ? { cursor: "auto" } : null,
|
|
1511
|
+
"cursor-default": web ? { cursor: "default" } : null,
|
|
1512
|
+
"cursor-pointer": web ? { cursor: "pointer" } : null,
|
|
1513
|
+
"cursor-wait": web ? { cursor: "wait" } : null,
|
|
1514
|
+
"cursor-text": web ? { cursor: "text" } : null,
|
|
1515
|
+
"cursor-move": web ? { cursor: "move" } : null,
|
|
1516
|
+
"cursor-not-allowed": web ? { cursor: "not-allowed" } : null,
|
|
1517
|
+
// User select (web-only)
|
|
1518
|
+
"select-none": web ? { userSelect: "none" } : null,
|
|
1519
|
+
"select-text": web ? { userSelect: "text" } : null,
|
|
1520
|
+
"select-all": web ? { userSelect: "all" } : null,
|
|
1521
|
+
"select-auto": web ? { userSelect: "auto" } : null,
|
|
1522
|
+
// Pointer events (both)
|
|
1523
|
+
"pointer-events-none": { pointerEvents: "none" },
|
|
1524
|
+
"pointer-events-auto": { pointerEvents: "auto" },
|
|
1525
|
+
// Whitespace (web-only; RN Text uses numberOfLines prop instead)
|
|
1526
|
+
"whitespace-normal": web ? { whiteSpace: "normal" } : null,
|
|
1527
|
+
"whitespace-nowrap": web ? { whiteSpace: "nowrap" } : null,
|
|
1528
|
+
"whitespace-pre": web ? { whiteSpace: "pre" } : null,
|
|
1529
|
+
"whitespace-pre-wrap": web ? { whiteSpace: "pre-wrap" } : null,
|
|
1530
|
+
"whitespace-pre-line": web ? { whiteSpace: "pre-line" } : null,
|
|
1531
|
+
// Word break (web-only)
|
|
1532
|
+
"break-normal": web ? { overflowWrap: "normal", wordBreak: "normal" } : null,
|
|
1533
|
+
"break-words": web ? { overflowWrap: "break-word" } : null,
|
|
1534
|
+
"break-all": web ? { wordBreak: "break-all" } : null,
|
|
1535
|
+
// Misc web-only
|
|
1536
|
+
truncate: web ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } : null,
|
|
1537
|
+
"box-border": web ? { boxSizing: "border-box" } : null,
|
|
1538
|
+
"box-content": web ? { boxSizing: "content-box" } : null,
|
|
1539
|
+
"appearance-none": web ? { appearance: "none" } : null,
|
|
1540
|
+
"outline-none": web ? { outline: "none", outlineOffset: "0" } : null,
|
|
1541
|
+
outline: web ? { outline: "2px solid transparent", outlineOffset: "2px" } : null,
|
|
1542
|
+
resize: web ? { resize: "both" } : null,
|
|
1543
|
+
"resize-none": web ? { resize: "none" } : null,
|
|
1544
|
+
"resize-y": web ? { resize: "vertical" } : null,
|
|
1545
|
+
"resize-x": web ? { resize: "horizontal" } : null,
|
|
1546
|
+
antialiased: web ? { WebkitFontSmoothing: "antialiased", MozOsxFontSmoothing: "grayscale" } : null,
|
|
1547
|
+
"subpixel-antialiased": web ? { WebkitFontSmoothing: "subpixel-antialiased", MozOsxFontSmoothing: "auto" } : null,
|
|
1548
|
+
"overflow-ellipsis": web ? { textOverflow: "ellipsis" } : null,
|
|
1549
|
+
"sr-only": web ? {
|
|
1550
|
+
position: "absolute",
|
|
1551
|
+
width: 1,
|
|
1552
|
+
height: 1,
|
|
1553
|
+
padding: 0,
|
|
1554
|
+
margin: -1,
|
|
1555
|
+
overflow: "hidden",
|
|
1556
|
+
clip: "rect(0,0,0,0)",
|
|
1557
|
+
whiteSpace: "nowrap",
|
|
1558
|
+
border: 0
|
|
1559
|
+
} : null,
|
|
1560
|
+
"not-sr-only": web ? {
|
|
1561
|
+
position: "static",
|
|
1562
|
+
width: "auto",
|
|
1563
|
+
height: "auto",
|
|
1564
|
+
padding: 0,
|
|
1565
|
+
margin: 0,
|
|
1566
|
+
overflow: "visible",
|
|
1567
|
+
clip: "auto",
|
|
1568
|
+
whiteSpace: "normal"
|
|
1569
|
+
} : null,
|
|
1570
|
+
// Lists (web-only)
|
|
1571
|
+
"list-none": web ? { listStyleType: "none" } : null,
|
|
1572
|
+
"list-disc": web ? { listStyleType: "disc" } : null,
|
|
1573
|
+
"list-decimal": web ? { listStyleType: "decimal" } : null,
|
|
1574
|
+
// Background clip (web-only)
|
|
1575
|
+
"bg-clip-border": web ? { backgroundClip: "border-box" } : null,
|
|
1576
|
+
"bg-clip-padding": web ? { backgroundClip: "padding-box" } : null,
|
|
1577
|
+
"bg-clip-content": web ? { backgroundClip: "content-box" } : null,
|
|
1578
|
+
"bg-clip-text": web ? { backgroundClip: "text", WebkitBackgroundClip: "text" } : null,
|
|
1579
|
+
// Background image
|
|
1580
|
+
"bg-none": web ? { backgroundImage: "none" } : null,
|
|
1581
|
+
// Background size (web-only)
|
|
1582
|
+
"bg-auto": web ? { backgroundSize: "auto" } : null,
|
|
1583
|
+
"bg-cover": web ? { backgroundSize: "cover" } : null,
|
|
1584
|
+
"bg-contain": web ? { backgroundSize: "contain" } : null,
|
|
1585
|
+
// Background position (web-only)
|
|
1586
|
+
"bg-center": web ? { backgroundPosition: "center" } : null,
|
|
1587
|
+
"bg-top": web ? { backgroundPosition: "top" } : null,
|
|
1588
|
+
"bg-bottom": web ? { backgroundPosition: "bottom" } : null,
|
|
1589
|
+
"bg-left": web ? { backgroundPosition: "left" } : null,
|
|
1590
|
+
"bg-right": web ? { backgroundPosition: "right" } : null,
|
|
1591
|
+
"bg-left-top": web ? { backgroundPosition: "left top" } : null,
|
|
1592
|
+
"bg-left-bottom": web ? { backgroundPosition: "left bottom" } : null,
|
|
1593
|
+
"bg-right-top": web ? { backgroundPosition: "right top" } : null,
|
|
1594
|
+
"bg-right-bottom": web ? { backgroundPosition: "right bottom" } : null,
|
|
1595
|
+
// Background repeat (web-only)
|
|
1596
|
+
"bg-repeat": web ? { backgroundRepeat: "repeat" } : null,
|
|
1597
|
+
"bg-no-repeat": web ? { backgroundRepeat: "no-repeat" } : null,
|
|
1598
|
+
"bg-repeat-x": web ? { backgroundRepeat: "repeat-x" } : null,
|
|
1599
|
+
"bg-repeat-y": web ? { backgroundRepeat: "repeat-y" } : null,
|
|
1600
|
+
"bg-repeat-round": web ? { backgroundRepeat: "round" } : null,
|
|
1601
|
+
"bg-repeat-space": web ? { backgroundRepeat: "space" } : null,
|
|
1602
|
+
// Background attachment (web-only)
|
|
1603
|
+
"bg-fixed": web ? { backgroundAttachment: "fixed" } : null,
|
|
1604
|
+
"bg-local": web ? { backgroundAttachment: "local" } : null,
|
|
1605
|
+
"bg-scroll": web ? { backgroundAttachment: "scroll" } : null,
|
|
1606
|
+
// Object position (web-only)
|
|
1607
|
+
"object-center": web ? { objectPosition: "center" } : null,
|
|
1608
|
+
"object-top": web ? { objectPosition: "top" } : null,
|
|
1609
|
+
"object-bottom": web ? { objectPosition: "bottom" } : null,
|
|
1610
|
+
"object-left": web ? { objectPosition: "left" } : null,
|
|
1611
|
+
"object-right": web ? { objectPosition: "right" } : null,
|
|
1612
|
+
"object-left-top": web ? { objectPosition: "left top" } : null,
|
|
1613
|
+
"object-left-bottom": web ? { objectPosition: "left bottom" } : null,
|
|
1614
|
+
"object-right-top": web ? { objectPosition: "right top" } : null,
|
|
1615
|
+
"object-right-bottom": web ? { objectPosition: "right bottom" } : null,
|
|
1616
|
+
// Table (web-only)
|
|
1617
|
+
table: web ? { display: "table" } : null,
|
|
1618
|
+
"table-auto": web ? { tableLayout: "auto" } : null,
|
|
1619
|
+
"table-fixed": web ? { tableLayout: "fixed" } : null,
|
|
1620
|
+
"caption-top": web ? { captionSide: "top" } : null,
|
|
1621
|
+
"caption-bottom": web ? { captionSide: "bottom" } : null,
|
|
1622
|
+
"border-collapse": web ? { borderCollapse: "collapse" } : null,
|
|
1623
|
+
"border-separate": web ? { borderCollapse: "separate" } : null,
|
|
1624
|
+
// List style position (web-only)
|
|
1625
|
+
"list-inside": web ? { listStylePosition: "inside" } : null,
|
|
1626
|
+
"list-outside": web ? { listStylePosition: "outside" } : null,
|
|
1627
|
+
// Font variant numeric (web-only)
|
|
1628
|
+
"normal-nums": web ? { fontVariantNumeric: "normal" } : null,
|
|
1629
|
+
ordinal: web ? { fontVariantNumeric: "ordinal" } : null,
|
|
1630
|
+
"slashed-zero": web ? { fontVariantNumeric: "slashed-zero" } : null,
|
|
1631
|
+
"lining-nums": web ? { fontVariantNumeric: "lining-nums" } : null,
|
|
1632
|
+
"oldstyle-nums": web ? { fontVariantNumeric: "oldstyle-nums" } : null,
|
|
1633
|
+
"proportional-nums": web ? { fontVariantNumeric: "proportional-nums" } : null,
|
|
1634
|
+
"tabular-nums": web ? { fontVariantNumeric: "tabular-nums" } : null,
|
|
1635
|
+
"diagonal-fractions": web ? { fontVariantNumeric: "diagonal-fractions" } : null,
|
|
1636
|
+
"stacked-fractions": web ? { fontVariantNumeric: "stacked-fractions" } : null,
|
|
1637
|
+
// Isolation (web-only)
|
|
1638
|
+
isolate: web ? { isolation: "isolate" } : null,
|
|
1639
|
+
"isolation-auto": web ? { isolation: "auto" } : null,
|
|
1640
|
+
// Backface visibility (both iOS and Android)
|
|
1641
|
+
"backface-visible": { backfaceVisibility: "visible" },
|
|
1642
|
+
"backface-hidden": { backfaceVisibility: "hidden" },
|
|
1643
|
+
// CSS filters — standalone = default/full effect (web-only)
|
|
1644
|
+
grayscale: web ? { "--kb-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
|
|
1645
|
+
invert: web ? { "--kb-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
|
|
1646
|
+
sepia: web ? { "--kb-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
|
|
1647
|
+
// Divide none
|
|
1648
|
+
"divide-none": web ? { __divideX: 0, __divideY: 0 } : null,
|
|
1649
|
+
// Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
|
|
1650
|
+
group: web ? {} : null,
|
|
1651
|
+
peer: web ? {} : null,
|
|
1652
|
+
// Text-wrap (web-only)
|
|
1653
|
+
"text-wrap": web ? { textWrap: "wrap" } : null,
|
|
1654
|
+
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1655
|
+
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1656
|
+
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1657
|
+
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1658
|
+
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1659
|
+
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1660
|
+
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1661
|
+
// is unchanged since there's no dynamic chrome to account for.
|
|
1662
|
+
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1663
|
+
"w-screen": web ? { width: "100dvw" } : null,
|
|
1664
|
+
"min-h-screen": { minHeight: "100dvh" },
|
|
1665
|
+
"max-h-screen": { maxHeight: "100dvh" },
|
|
1666
|
+
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1667
|
+
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1668
|
+
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1669
|
+
"max-w-none": { maxWidth: "none" },
|
|
1670
|
+
"max-w-xs": { maxWidth: 320 },
|
|
1671
|
+
"max-w-sm": { maxWidth: 384 },
|
|
1672
|
+
"max-w-md": { maxWidth: 448 },
|
|
1673
|
+
"max-w-lg": { maxWidth: 512 },
|
|
1674
|
+
"max-w-xl": { maxWidth: 576 },
|
|
1675
|
+
"max-w-2xl": { maxWidth: 672 },
|
|
1676
|
+
"max-w-3xl": { maxWidth: 768 },
|
|
1677
|
+
"max-w-4xl": { maxWidth: 896 },
|
|
1678
|
+
"max-w-5xl": { maxWidth: 1024 },
|
|
1679
|
+
"max-w-6xl": { maxWidth: 1152 },
|
|
1680
|
+
"max-w-7xl": { maxWidth: 1280 },
|
|
1681
|
+
"max-w-prose": web ? { maxWidth: "65ch" } : null,
|
|
1682
|
+
// Extended cursors (web-only)
|
|
1683
|
+
"cursor-grab": web ? { cursor: "grab" } : null,
|
|
1684
|
+
"cursor-grabbing": web ? { cursor: "grabbing" } : null,
|
|
1685
|
+
"cursor-zoom-in": web ? { cursor: "zoom-in" } : null,
|
|
1686
|
+
"cursor-zoom-out": web ? { cursor: "zoom-out" } : null,
|
|
1687
|
+
"cursor-crosshair": web ? { cursor: "crosshair" } : null,
|
|
1688
|
+
"cursor-help": web ? { cursor: "help" } : null,
|
|
1689
|
+
"cursor-none": web ? { cursor: "none" } : null,
|
|
1690
|
+
// Overflow clip (web-only)
|
|
1691
|
+
"overflow-clip": web ? { overflow: "clip" } : null,
|
|
1692
|
+
"overflow-x-clip": web ? { overflowX: "clip" } : null,
|
|
1693
|
+
"overflow-y-clip": web ? { overflowY: "clip" } : null,
|
|
1694
|
+
// Scroll behavior (web-only)
|
|
1695
|
+
"scroll-smooth": web ? { scrollBehavior: "smooth" } : null,
|
|
1696
|
+
"scroll-auto": web ? { scrollBehavior: "auto" } : null,
|
|
1697
|
+
// Float (web-only)
|
|
1698
|
+
"float-left": web ? { float: "left" } : null,
|
|
1699
|
+
"float-right": web ? { float: "right" } : null,
|
|
1700
|
+
"float-start": web ? { float: "inline-start" } : null,
|
|
1701
|
+
"float-end": web ? { float: "inline-end" } : null,
|
|
1702
|
+
"float-none": web ? { float: "none" } : null,
|
|
1703
|
+
// Clear (web-only)
|
|
1704
|
+
"clear-left": web ? { clear: "left" } : null,
|
|
1705
|
+
"clear-right": web ? { clear: "right" } : null,
|
|
1706
|
+
"clear-both": web ? { clear: "both" } : null,
|
|
1707
|
+
"clear-start": web ? { clear: "inline-start" } : null,
|
|
1708
|
+
"clear-end": web ? { clear: "inline-end" } : null,
|
|
1709
|
+
"clear-none": web ? { clear: "none" } : null,
|
|
1710
|
+
// Vertical align (web-only)
|
|
1711
|
+
"align-baseline": web ? { verticalAlign: "baseline" } : null,
|
|
1712
|
+
"align-top": web ? { verticalAlign: "top" } : null,
|
|
1713
|
+
"align-middle": web ? { verticalAlign: "middle" } : null,
|
|
1714
|
+
"align-bottom": web ? { verticalAlign: "bottom" } : null,
|
|
1715
|
+
"align-text-top": web ? { verticalAlign: "text-top" } : null,
|
|
1716
|
+
"align-text-bottom": web ? { verticalAlign: "text-bottom" } : null,
|
|
1717
|
+
"align-sub": web ? { verticalAlign: "sub" } : null,
|
|
1718
|
+
"align-super": web ? { verticalAlign: "super" } : null,
|
|
1719
|
+
// Touch action (web-only)
|
|
1720
|
+
"touch-auto": web ? { touchAction: "auto" } : null,
|
|
1721
|
+
"touch-none": web ? { touchAction: "none" } : null,
|
|
1722
|
+
"touch-pan-x": web ? { touchAction: "pan-x" } : null,
|
|
1723
|
+
"touch-pan-y": web ? { touchAction: "pan-y" } : null,
|
|
1724
|
+
"touch-pan-left": web ? { touchAction: "pan-left" } : null,
|
|
1725
|
+
"touch-pan-right": web ? { touchAction: "pan-right" } : null,
|
|
1726
|
+
"touch-pan-up": web ? { touchAction: "pan-up" } : null,
|
|
1727
|
+
"touch-pan-down": web ? { touchAction: "pan-down" } : null,
|
|
1728
|
+
"touch-pinch-zoom": web ? { touchAction: "pinch-zoom" } : null,
|
|
1729
|
+
"touch-manipulation": web ? { touchAction: "manipulation" } : null
|
|
1730
|
+
};
|
|
1731
|
+
}
|
|
1732
|
+
function getStandalone() {
|
|
1733
|
+
if (!_standalone) _standalone = buildStandalone();
|
|
1734
|
+
return _standalone;
|
|
1735
|
+
}
|
|
1736
|
+
var layoutResolvers = {
|
|
1737
|
+
// ── Grid (responsive column count: grid-1 … grid-12, or arbitrary) ───────
|
|
1738
|
+
grid: ({ value, isArbitrary }) => {
|
|
1739
|
+
if (!value) return null;
|
|
1740
|
+
if (isArbitrary) return { display: "grid", gridTemplateColumns: value };
|
|
1741
|
+
const n = parseInt(value, 10);
|
|
1742
|
+
if (isNaN(n) || n < 1 || n > 12) return null;
|
|
1743
|
+
return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
|
|
1808
1744
|
},
|
|
1809
|
-
// ──
|
|
1810
|
-
|
|
1745
|
+
// ── Grid template columns/rows (Tailwind-style aliases, web-only) ──────────
|
|
1746
|
+
"grid-cols": ({ value, isArbitrary }) => {
|
|
1811
1747
|
if (!getEffectiveIsWeb()) return null;
|
|
1812
|
-
if (
|
|
1813
|
-
if (
|
|
1748
|
+
if (!value) return null;
|
|
1749
|
+
if (isArbitrary) return { display: "grid", gridTemplateColumns: value };
|
|
1750
|
+
if (value === "none") return { display: "grid", gridTemplateColumns: "none" };
|
|
1814
1751
|
const n = parseInt(value, 10);
|
|
1815
|
-
if (
|
|
1816
|
-
|
|
1817
|
-
"3xs": "16rem",
|
|
1818
|
-
"2xs": "18rem",
|
|
1819
|
-
xs: "20rem",
|
|
1820
|
-
sm: "24rem",
|
|
1821
|
-
md: "28rem",
|
|
1822
|
-
lg: "32rem",
|
|
1823
|
-
xl: "36rem",
|
|
1824
|
-
"2xl": "42rem",
|
|
1825
|
-
"3xl": "48rem",
|
|
1826
|
-
"4xl": "56rem",
|
|
1827
|
-
"5xl": "64rem",
|
|
1828
|
-
"6xl": "72rem",
|
|
1829
|
-
"7xl": "80rem"
|
|
1830
|
-
};
|
|
1831
|
-
return widths[value] ? { columnWidth: widths[value] } : null;
|
|
1752
|
+
if (isNaN(n) || n < 1 || n > 12) return null;
|
|
1753
|
+
return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
|
|
1832
1754
|
},
|
|
1833
|
-
|
|
1834
|
-
"mix-blend": ({ value }) => {
|
|
1755
|
+
"grid-rows": ({ value, isArbitrary }) => {
|
|
1835
1756
|
if (!getEffectiveIsWeb()) return null;
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
"lighten",
|
|
1843
|
-
"color-dodge",
|
|
1844
|
-
"color-burn",
|
|
1845
|
-
"hard-light",
|
|
1846
|
-
"soft-light",
|
|
1847
|
-
"difference",
|
|
1848
|
-
"exclusion",
|
|
1849
|
-
"hue",
|
|
1850
|
-
"saturation",
|
|
1851
|
-
"color",
|
|
1852
|
-
"luminosity",
|
|
1853
|
-
"plus-lighter"
|
|
1854
|
-
];
|
|
1855
|
-
return modes.includes(value) ? { mixBlendMode: value } : null;
|
|
1757
|
+
if (!value) return null;
|
|
1758
|
+
if (isArbitrary) return { gridTemplateRows: value };
|
|
1759
|
+
if (value === "none") return { gridTemplateRows: "none" };
|
|
1760
|
+
const n = parseInt(value, 10);
|
|
1761
|
+
if (isNaN(n) || n < 1) return null;
|
|
1762
|
+
return { gridTemplateRows: `repeat(${n}, minmax(0, 1fr))` };
|
|
1856
1763
|
},
|
|
1857
|
-
|
|
1764
|
+
// ── Grid auto flow (web-only) ─────────────────────────────────────────────
|
|
1765
|
+
"grid-flow": ({ value }) => {
|
|
1858
1766
|
if (!getEffectiveIsWeb()) return null;
|
|
1859
|
-
const
|
|
1860
|
-
"
|
|
1861
|
-
"
|
|
1862
|
-
"
|
|
1863
|
-
"
|
|
1864
|
-
"
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
"hard-light",
|
|
1869
|
-
"soft-light",
|
|
1870
|
-
"difference",
|
|
1871
|
-
"exclusion",
|
|
1872
|
-
"hue",
|
|
1873
|
-
"saturation",
|
|
1874
|
-
"color",
|
|
1875
|
-
"luminosity"
|
|
1876
|
-
];
|
|
1877
|
-
return modes.includes(value) ? { backgroundBlendMode: value } : null;
|
|
1767
|
+
const flows = {
|
|
1768
|
+
row: "row",
|
|
1769
|
+
col: "column",
|
|
1770
|
+
dense: "dense",
|
|
1771
|
+
"row-dense": "row dense",
|
|
1772
|
+
"col-dense": "column dense"
|
|
1773
|
+
};
|
|
1774
|
+
const flow = flows[value];
|
|
1775
|
+
return flow ? { gridAutoFlow: flow } : null;
|
|
1878
1776
|
},
|
|
1879
|
-
// ──
|
|
1880
|
-
"
|
|
1777
|
+
// ── Grid auto sizing (web-only) ───────────────────────────────────────────
|
|
1778
|
+
"auto-cols": ({ value, isArbitrary }) => {
|
|
1881
1779
|
if (!getEffectiveIsWeb()) return null;
|
|
1882
|
-
if (isArbitrary) return {
|
|
1780
|
+
if (isArbitrary) return { gridAutoColumns: value };
|
|
1883
1781
|
const presets = {
|
|
1884
1782
|
auto: "auto",
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1783
|
+
min: "min-content",
|
|
1784
|
+
max: "max-content",
|
|
1785
|
+
fr: "minmax(0, 1fr)"
|
|
1888
1786
|
};
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
// ── Divide (child combinator CSS, web-only) ───────────────────────────────
|
|
1892
|
-
// These return special __divide* markers that resolver.ts converts to
|
|
1893
|
-
// .cls > * + * { border-... } CSS rules. No inline style is applied.
|
|
1894
|
-
"divide-x": ({ value, isArbitrary }) => {
|
|
1895
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1896
|
-
if (value === "reverse") return null;
|
|
1897
|
-
if (!value) return { __divideX: 1 };
|
|
1898
|
-
const n = parseFloat(value);
|
|
1899
|
-
return isNaN(n) ? null : { __divideX: n };
|
|
1900
|
-
},
|
|
1901
|
-
"divide-y": ({ value, isArbitrary }) => {
|
|
1902
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1903
|
-
if (value === "reverse") return null;
|
|
1904
|
-
if (!value) return { __divideY: 1 };
|
|
1905
|
-
const n = parseFloat(value);
|
|
1906
|
-
return isNaN(n) ? null : { __divideY: n };
|
|
1787
|
+
const v = presets[value];
|
|
1788
|
+
return v ? { gridAutoColumns: v } : null;
|
|
1907
1789
|
},
|
|
1908
|
-
|
|
1790
|
+
"auto-rows": ({ value, isArbitrary }) => {
|
|
1909
1791
|
if (!getEffectiveIsWeb()) return null;
|
|
1910
|
-
if (isArbitrary) return {
|
|
1911
|
-
const
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
none: "none"
|
|
1917
|
-
};
|
|
1918
|
-
if (value in styleTokens) return { __divideStyle: styleTokens[value] };
|
|
1919
|
-
const color = resolveColor(value, colors, false);
|
|
1920
|
-
return color ? { __divideColor: color } : null;
|
|
1921
|
-
},
|
|
1922
|
-
// ── Text shadow (cross-platform: iOS, Android, web) ─────────────────────
|
|
1923
|
-
// Named presets give cross-platform shadow; arbitrary is web-only.
|
|
1924
|
-
"text-shadow": ({ value, isArbitrary }, { colors }) => {
|
|
1925
|
-
if (value === "none") {
|
|
1926
|
-
return getEffectiveIsWeb() ? { textShadow: "none" } : { textShadowColor: "transparent", textShadowOffset: { width: 0, height: 0 }, textShadowRadius: 0 };
|
|
1927
|
-
}
|
|
1928
|
-
const webPresets = {
|
|
1929
|
-
"": "0 2px 4px rgba(0,0,0,0.3)",
|
|
1930
|
-
sm: "0 1px 2px rgba(0,0,0,0.3)",
|
|
1931
|
-
md: "0 4px 6px rgba(0,0,0,0.3)",
|
|
1932
|
-
lg: "0 8px 16px rgba(0,0,0,0.5)",
|
|
1933
|
-
xl: "0 16px 32px rgba(0,0,0,0.5)"
|
|
1934
|
-
};
|
|
1935
|
-
const nativePresets = {
|
|
1936
|
-
"": { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 2 }, textShadowRadius: 4 },
|
|
1937
|
-
sm: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 1 }, textShadowRadius: 2 },
|
|
1938
|
-
md: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 4 }, textShadowRadius: 6 },
|
|
1939
|
-
lg: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 8 }, textShadowRadius: 16 },
|
|
1940
|
-
xl: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 16 }, textShadowRadius: 32 }
|
|
1792
|
+
if (isArbitrary) return { gridAutoRows: value };
|
|
1793
|
+
const presets = {
|
|
1794
|
+
auto: "auto",
|
|
1795
|
+
min: "min-content",
|
|
1796
|
+
max: "max-content",
|
|
1797
|
+
fr: "minmax(0, 1fr)"
|
|
1941
1798
|
};
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
return nativePresets[value] ?? null;
|
|
1945
|
-
}
|
|
1946
|
-
if (isArbitrary) {
|
|
1947
|
-
return getEffectiveIsWeb() ? { textShadow: value.replace(/_/g, " ") } : null;
|
|
1948
|
-
}
|
|
1949
|
-
const color = resolveColor(value, colors, false);
|
|
1950
|
-
if (color) {
|
|
1951
|
-
return getEffectiveIsWeb() ? { textShadow: `0 2px 4px ${color}` } : { textShadowColor: color };
|
|
1952
|
-
}
|
|
1953
|
-
return null;
|
|
1799
|
+
const v = presets[value];
|
|
1800
|
+
return v ? { gridAutoRows: v } : null;
|
|
1954
1801
|
},
|
|
1955
|
-
// ──
|
|
1956
|
-
|
|
1957
|
-
if (
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
}
|
|
1962
|
-
if (value === "none") return getEffectiveIsWeb() ? { transform: "none" } : null;
|
|
1963
|
-
const n = parseFloat(value);
|
|
1964
|
-
if (isNaN(n)) return null;
|
|
1965
|
-
return getEffectiveIsWeb() ? { transform: `perspective(${n}px)` } : { transform: [{ perspective: n }] };
|
|
1802
|
+
// ── Grid column placement (web-only) ──────────────────────────────────────
|
|
1803
|
+
"col-span": ({ value }) => {
|
|
1804
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1805
|
+
if (value === "full") return { gridColumn: "1 / -1" };
|
|
1806
|
+
const n = parseInt(value, 10);
|
|
1807
|
+
return isNaN(n) ? null : { gridColumn: `span ${n} / span ${n}` };
|
|
1966
1808
|
},
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
if (
|
|
1970
|
-
|
|
1971
|
-
|
|
1809
|
+
"col-start": ({ value, isArbitrary }) => {
|
|
1810
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1811
|
+
if (value === "auto") return { gridColumnStart: "auto" };
|
|
1812
|
+
if (isArbitrary) return { gridColumnStart: value };
|
|
1813
|
+
const n = parseInt(value, 10);
|
|
1814
|
+
return isNaN(n) ? null : { gridColumnStart: n };
|
|
1972
1815
|
},
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1816
|
+
"col-end": ({ value, isArbitrary }) => {
|
|
1817
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1818
|
+
if (value === "auto") return { gridColumnEnd: "auto" };
|
|
1819
|
+
if (isArbitrary) return { gridColumnEnd: value };
|
|
1820
|
+
const n = parseInt(value, 10);
|
|
1821
|
+
return isNaN(n) ? null : { gridColumnEnd: n };
|
|
1977
1822
|
},
|
|
1978
|
-
|
|
1979
|
-
// Each variant injects a @keyframes rule once via the __keyframe marker.
|
|
1980
|
-
// resolver.ts detects __keyframe, injects the rule, then strips the marker
|
|
1981
|
-
// so it never reaches element inline styles.
|
|
1982
|
-
animate: ({ value, isArbitrary }, theme) => {
|
|
1823
|
+
col: ({ value, isArbitrary }) => {
|
|
1983
1824
|
if (!getEffectiveIsWeb()) return null;
|
|
1984
|
-
if (
|
|
1985
|
-
if (
|
|
1986
|
-
|
|
1987
|
-
return custom ? buildAnimationValue(custom, theme.keyframes) : null;
|
|
1825
|
+
if (!value || value === "auto") return { gridColumn: "auto" };
|
|
1826
|
+
if (isArbitrary) return { gridColumn: value };
|
|
1827
|
+
return null;
|
|
1988
1828
|
},
|
|
1989
|
-
// ──
|
|
1990
|
-
"
|
|
1829
|
+
// ── Grid row placement (web-only) ─────────────────────────────────────────
|
|
1830
|
+
"row-span": ({ value }) => {
|
|
1991
1831
|
if (!getEffectiveIsWeb()) return null;
|
|
1992
|
-
if (value === "
|
|
1832
|
+
if (value === "full") return { gridRow: "1 / -1" };
|
|
1993
1833
|
const n = parseInt(value, 10);
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
1834
|
+
return isNaN(n) ? null : { gridRow: `span ${n} / span ${n}` };
|
|
1835
|
+
},
|
|
1836
|
+
"row-start": ({ value, isArbitrary }) => {
|
|
1837
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1838
|
+
if (value === "auto") return { gridRowStart: "auto" };
|
|
1839
|
+
if (isArbitrary) return { gridRowStart: value };
|
|
1840
|
+
const n = parseInt(value, 10);
|
|
1841
|
+
return isNaN(n) ? null : { gridRowStart: n };
|
|
1842
|
+
},
|
|
1843
|
+
"row-end": ({ value, isArbitrary }) => {
|
|
1844
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1845
|
+
if (value === "auto") return { gridRowEnd: "auto" };
|
|
1846
|
+
if (isArbitrary) return { gridRowEnd: value };
|
|
1847
|
+
const n = parseInt(value, 10);
|
|
1848
|
+
return isNaN(n) ? null : { gridRowEnd: n };
|
|
1849
|
+
},
|
|
1850
|
+
row: ({ value, isArbitrary }) => {
|
|
1851
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1852
|
+
if (!value || value === "auto") return { gridRow: "auto" };
|
|
1853
|
+
if (isArbitrary) return { gridRow: value };
|
|
1854
|
+
return null;
|
|
1855
|
+
},
|
|
1856
|
+
// ── Grid alignment (web-only) ──────────────────────────────────────────────
|
|
1857
|
+
// place-items is shorthand for align-items + justify-items on a grid container
|
|
1858
|
+
"place-items": ({ value }) => {
|
|
1859
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1860
|
+
const map = {
|
|
1861
|
+
start: "start",
|
|
1862
|
+
end: "end",
|
|
1863
|
+
center: "center",
|
|
1864
|
+
stretch: "stretch",
|
|
1865
|
+
baseline: "baseline"
|
|
2000
1866
|
};
|
|
1867
|
+
return map[value] ? { placeItems: map[value] } : null;
|
|
2001
1868
|
},
|
|
2002
|
-
//
|
|
2003
|
-
|
|
1869
|
+
// place-content is shorthand for align-content + justify-content on a grid container
|
|
1870
|
+
"place-content": ({ value }) => {
|
|
2004
1871
|
if (!getEffectiveIsWeb()) return null;
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
1872
|
+
const map = {
|
|
1873
|
+
start: "start",
|
|
1874
|
+
end: "end",
|
|
1875
|
+
center: "center",
|
|
1876
|
+
stretch: "stretch",
|
|
1877
|
+
between: "space-between",
|
|
1878
|
+
around: "space-around",
|
|
1879
|
+
evenly: "space-evenly",
|
|
1880
|
+
baseline: "baseline"
|
|
1881
|
+
};
|
|
1882
|
+
return map[value] ? { placeContent: map[value] } : null;
|
|
2008
1883
|
},
|
|
2009
|
-
//
|
|
2010
|
-
|
|
1884
|
+
// justify-items controls inline-axis alignment of grid items within their cells
|
|
1885
|
+
"justify-items": ({ value }) => {
|
|
2011
1886
|
if (!getEffectiveIsWeb()) return null;
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
1887
|
+
const map = {
|
|
1888
|
+
start: "start",
|
|
1889
|
+
end: "end",
|
|
1890
|
+
center: "center",
|
|
1891
|
+
stretch: "stretch"
|
|
1892
|
+
};
|
|
1893
|
+
return map[value] ? { justifyItems: map[value] } : null;
|
|
2015
1894
|
},
|
|
2016
|
-
//
|
|
2017
|
-
|
|
2018
|
-
// take stroke/fill as component PROPS, not style entries, so there's no
|
|
2019
|
-
// reliable way to apply a resolved color through the `style` prop there.
|
|
2020
|
-
// `stroke-{n}` sets strokeWidth (a plain number, unlike a color) — same
|
|
2021
|
-
// color-first-then-numeric-fallback disambiguation `border` uses above.
|
|
2022
|
-
stroke: ({ value, isArbitrary }, { colors }) => {
|
|
1895
|
+
// place-self is shorthand for align-self + justify-self on a grid item
|
|
1896
|
+
"place-self": ({ value }) => {
|
|
2023
1897
|
if (!getEffectiveIsWeb()) return null;
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
const n = parseFloat(value);
|
|
2033
|
-
return isNaN(n) ? null : { strokeWidth: n };
|
|
1898
|
+
const map = {
|
|
1899
|
+
auto: "auto",
|
|
1900
|
+
start: "start",
|
|
1901
|
+
end: "end",
|
|
1902
|
+
center: "center",
|
|
1903
|
+
stretch: "stretch"
|
|
1904
|
+
};
|
|
1905
|
+
return map[value] ? { placeSelf: map[value] } : null;
|
|
2034
1906
|
},
|
|
2035
|
-
|
|
1907
|
+
// justify-self controls inline-axis self-alignment of a grid item
|
|
1908
|
+
"justify-self": ({ value }) => {
|
|
2036
1909
|
if (!getEffectiveIsWeb()) return null;
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
1910
|
+
const map = {
|
|
1911
|
+
auto: "auto",
|
|
1912
|
+
start: "start",
|
|
1913
|
+
end: "end",
|
|
1914
|
+
center: "center",
|
|
1915
|
+
stretch: "stretch"
|
|
1916
|
+
};
|
|
1917
|
+
return map[value] ? { justifySelf: map[value] } : null;
|
|
2042
1918
|
},
|
|
2043
1919
|
// ── Flex ───────────────────────────────────────────────────────────────────
|
|
2044
1920
|
flex: ({ value, isArbitrary }, { flex }) => {
|
|
@@ -2059,10 +1935,6 @@ var RESOLVERS = {
|
|
|
2059
1935
|
const n = parseFloat(value);
|
|
2060
1936
|
return isNaN(n) ? null : { flex: n };
|
|
2061
1937
|
},
|
|
2062
|
-
basis: ({ value, isArbitrary }, { spacing }) => {
|
|
2063
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
2064
|
-
return v !== null ? { flexBasis: v } : null;
|
|
2065
|
-
},
|
|
2066
1938
|
grow: ({ value }, _) => {
|
|
2067
1939
|
if (!value) return { flexGrow: 1 };
|
|
2068
1940
|
const n = parseFloat(value);
|
|
@@ -2077,72 +1949,132 @@ var RESOLVERS = {
|
|
|
2077
1949
|
const n = parseInt(value, 10);
|
|
2078
1950
|
return isNaN(n) ? null : { order: negative ? -n : n };
|
|
2079
1951
|
},
|
|
2080
|
-
// ── Gap ────────────────────────────────────────────────────────────────────
|
|
2081
|
-
gap: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2082
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2083
|
-
return v !== null ? { gap: v } : null;
|
|
2084
|
-
},
|
|
2085
|
-
"gap-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2086
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2087
|
-
return v !== null ? { columnGap: v } : null;
|
|
2088
|
-
},
|
|
2089
|
-
"gap-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2090
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2091
|
-
return v !== null ? { rowGap: v } : null;
|
|
2092
|
-
},
|
|
2093
|
-
// ── Position ───────────────────────────────────────────────────────────────
|
|
2094
|
-
top: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2095
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2096
|
-
return v !== null ? { top: v } : null;
|
|
2097
|
-
},
|
|
2098
|
-
right: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2099
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2100
|
-
return v !== null ? { right: v } : null;
|
|
2101
|
-
},
|
|
2102
|
-
bottom: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2103
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2104
|
-
return v !== null ? { bottom: v } : null;
|
|
2105
|
-
},
|
|
2106
|
-
left: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2107
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2108
|
-
return v !== null ? { left: v } : null;
|
|
2109
|
-
},
|
|
2110
|
-
inset: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2111
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2112
|
-
return v !== null ? { top: v, right: v, bottom: v, left: v } : null;
|
|
2113
|
-
},
|
|
2114
|
-
"inset-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2115
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2116
|
-
return v !== null ? { left: v, right: v } : null;
|
|
2117
|
-
},
|
|
2118
|
-
"inset-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2119
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2120
|
-
return v !== null ? { top: v, bottom: v } : null;
|
|
2121
|
-
},
|
|
2122
1952
|
// ── Z-index ────────────────────────────────────────────────────────────────
|
|
2123
1953
|
z: ({ value, isArbitrary }, { zIndex }) => {
|
|
2124
1954
|
if (isArbitrary) {
|
|
2125
|
-
const n2 = parseInt(value);
|
|
2126
|
-
return isNaN(n2) ? null : { zIndex: n2 };
|
|
2127
|
-
}
|
|
2128
|
-
const v = zIndex[value];
|
|
2129
|
-
if (v !== void 0) {
|
|
2130
|
-
if (v === "auto") return getEffectiveIsWeb() ? { zIndex: "auto" } : null;
|
|
2131
|
-
return { zIndex: v };
|
|
1955
|
+
const n2 = parseInt(value);
|
|
1956
|
+
return isNaN(n2) ? null : { zIndex: n2 };
|
|
1957
|
+
}
|
|
1958
|
+
const v = zIndex[value];
|
|
1959
|
+
if (v !== void 0) {
|
|
1960
|
+
if (v === "auto") return getEffectiveIsWeb() ? { zIndex: "auto" } : null;
|
|
1961
|
+
return { zIndex: v };
|
|
1962
|
+
}
|
|
1963
|
+
const n = parseInt(value);
|
|
1964
|
+
return isNaN(n) ? null : { zIndex: n };
|
|
1965
|
+
},
|
|
1966
|
+
// ── Aspect ratio ───────────────────────────────────────────────────────────
|
|
1967
|
+
aspect: ({ value, isArbitrary }) => {
|
|
1968
|
+
if (isArbitrary) return { aspectRatio: value };
|
|
1969
|
+
const presets = { auto: "auto", square: 1, video: 16 / 9 };
|
|
1970
|
+
if (!(value in presets)) return null;
|
|
1971
|
+
const v = presets[value];
|
|
1972
|
+
if (v === "auto") return getEffectiveIsWeb() ? { aspectRatio: "auto" } : null;
|
|
1973
|
+
return { aspectRatio: v };
|
|
1974
|
+
},
|
|
1975
|
+
// ── Columns (web-only) ─────────────────────────────────────────────────────
|
|
1976
|
+
columns: ({ value, isArbitrary }) => {
|
|
1977
|
+
if (!getEffectiveIsWeb()) return null;
|
|
1978
|
+
if (isArbitrary) return { columnCount: value };
|
|
1979
|
+
if (value === "auto") return { columnCount: "auto" };
|
|
1980
|
+
const n = parseInt(value, 10);
|
|
1981
|
+
if (!isNaN(n)) return { columnCount: n };
|
|
1982
|
+
const widths = {
|
|
1983
|
+
"3xs": "16rem",
|
|
1984
|
+
"2xs": "18rem",
|
|
1985
|
+
xs: "20rem",
|
|
1986
|
+
sm: "24rem",
|
|
1987
|
+
md: "28rem",
|
|
1988
|
+
lg: "32rem",
|
|
1989
|
+
xl: "36rem",
|
|
1990
|
+
"2xl": "42rem",
|
|
1991
|
+
"3xl": "48rem",
|
|
1992
|
+
"4xl": "56rem",
|
|
1993
|
+
"5xl": "64rem",
|
|
1994
|
+
"6xl": "72rem",
|
|
1995
|
+
"7xl": "80rem"
|
|
1996
|
+
};
|
|
1997
|
+
return widths[value] ? { columnWidth: widths[value] } : null;
|
|
1998
|
+
}
|
|
1999
|
+
};
|
|
2000
|
+
|
|
2001
|
+
// src/core/resolvers/typography.ts
|
|
2002
|
+
function resolveFontSize(value, fontSizes, isArbitrary) {
|
|
2003
|
+
if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
|
|
2004
|
+
return fontSizes[value] ?? null;
|
|
2005
|
+
}
|
|
2006
|
+
var typographyResolvers = {
|
|
2007
|
+
// ── Text ───────────────────────────────────────────────────────────────────
|
|
2008
|
+
text: ({ value, isArbitrary }, { colors, fontSize }) => {
|
|
2009
|
+
const size = resolveFontSize(value, fontSize, false);
|
|
2010
|
+
if (!isArbitrary && size !== null) return { fontSize: size };
|
|
2011
|
+
if (isArbitrary) {
|
|
2012
|
+
if (/^\d/.test(value) || /^(calc|min|max|clamp)/.test(value)) {
|
|
2013
|
+
return { fontSize: getEffectiveIsWeb() ? value : toNativeValue(value) };
|
|
2014
|
+
}
|
|
2015
|
+
return { color: getEffectiveIsWeb() ? withOpacityVar(value, "--text-opacity") : value };
|
|
2132
2016
|
}
|
|
2133
|
-
const
|
|
2134
|
-
|
|
2017
|
+
const color = resolveColor(value, colors, false);
|
|
2018
|
+
if (!color) return null;
|
|
2019
|
+
return { color: getEffectiveIsWeb() ? withOpacityVar(color, "--text-opacity") : color };
|
|
2135
2020
|
},
|
|
2136
|
-
|
|
2137
|
-
|
|
2021
|
+
"text-opacity": ({ value, isArbitrary }, _) => {
|
|
2022
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2023
|
+
const n = parseFloat(value);
|
|
2024
|
+
if (isNaN(n)) return null;
|
|
2025
|
+
const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
|
|
2026
|
+
return { "--text-opacity": v };
|
|
2027
|
+
},
|
|
2028
|
+
// ── Text decoration advanced (web-only) ───────────────────────────────────
|
|
2029
|
+
decoration: ({ value, isArbitrary }, { colors }) => {
|
|
2030
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2138
2031
|
if (isArbitrary) {
|
|
2139
|
-
|
|
2140
|
-
return
|
|
2032
|
+
if (/^\d/.test(value) || value.startsWith("calc(")) return { textDecorationThickness: value };
|
|
2033
|
+
return { textDecorationColor: value };
|
|
2141
2034
|
}
|
|
2142
|
-
const
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2035
|
+
const thickTokens = {
|
|
2036
|
+
auto: "auto",
|
|
2037
|
+
"from-font": "from-font",
|
|
2038
|
+
"0": "0px",
|
|
2039
|
+
"1": "1px",
|
|
2040
|
+
"2": "2px",
|
|
2041
|
+
"4": "4px",
|
|
2042
|
+
"8": "8px"
|
|
2043
|
+
};
|
|
2044
|
+
if (value in thickTokens) return { textDecorationThickness: thickTokens[value] };
|
|
2045
|
+
const styleTokens = {
|
|
2046
|
+
solid: "solid",
|
|
2047
|
+
dashed: "dashed",
|
|
2048
|
+
dotted: "dotted",
|
|
2049
|
+
double: "double",
|
|
2050
|
+
wavy: "wavy"
|
|
2051
|
+
};
|
|
2052
|
+
if (value in styleTokens) return { textDecorationStyle: styleTokens[value] };
|
|
2053
|
+
const color = resolveColor(value, colors, false);
|
|
2054
|
+
return color ? { textDecorationColor: color } : null;
|
|
2055
|
+
},
|
|
2056
|
+
"underline-offset": ({ value, isArbitrary }) => {
|
|
2057
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2058
|
+
if (isArbitrary) return { textUnderlineOffset: value };
|
|
2059
|
+
const offsets = {
|
|
2060
|
+
auto: "auto",
|
|
2061
|
+
"0": "0px",
|
|
2062
|
+
"1": "1px",
|
|
2063
|
+
"2": "2px",
|
|
2064
|
+
"4": "4px",
|
|
2065
|
+
"8": "8px"
|
|
2066
|
+
};
|
|
2067
|
+
return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
|
|
2068
|
+
},
|
|
2069
|
+
// ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
|
|
2070
|
+
// Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
|
|
2071
|
+
// the literal string 'you can see it' quotes included), so it passes straight through as a
|
|
2072
|
+
// valid `content: '*'` CSS value with no extra wrapping needed.
|
|
2073
|
+
content: ({ value, isArbitrary }) => {
|
|
2074
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2075
|
+
if (isArbitrary) return { content: value };
|
|
2076
|
+
const presets = { none: "none" };
|
|
2077
|
+
return value in presets ? { content: presets[value] } : null;
|
|
2146
2078
|
},
|
|
2147
2079
|
// ── Font ───────────────────────────────────────────────────────────────────
|
|
2148
2080
|
font: ({ value, isArbitrary }, { fontFamily, fontWeight }) => {
|
|
@@ -2168,10 +2100,57 @@ var RESOLVERS = {
|
|
|
2168
2100
|
const v = letterSpacing[value];
|
|
2169
2101
|
return v !== void 0 ? { letterSpacing: v } : null;
|
|
2170
2102
|
},
|
|
2171
|
-
// ──
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
return
|
|
2103
|
+
// ── Line-clamp (web-only) ─────────────────────────────────────────────────
|
|
2104
|
+
"line-clamp": ({ value }) => {
|
|
2105
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2106
|
+
if (value === "none") return { overflow: "visible", display: "block", WebkitLineClamp: "unset" };
|
|
2107
|
+
const n = parseInt(value, 10);
|
|
2108
|
+
if (isNaN(n) || n < 1) return null;
|
|
2109
|
+
return {
|
|
2110
|
+
overflow: "hidden",
|
|
2111
|
+
display: "-webkit-box",
|
|
2112
|
+
WebkitBoxOrient: "vertical",
|
|
2113
|
+
WebkitLineClamp: n
|
|
2114
|
+
};
|
|
2115
|
+
}
|
|
2116
|
+
};
|
|
2117
|
+
|
|
2118
|
+
// src/core/resolvers/transform.ts
|
|
2119
|
+
var transformResolvers = {
|
|
2120
|
+
// ── Transform extras (web-only) ───────────────────────────────────────────
|
|
2121
|
+
"skew-x": ({ value, negative, isArbitrary }) => {
|
|
2122
|
+
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
2123
|
+
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
2124
|
+
return getEffectiveIsWeb() ? { transform: `skewX(${deg})` } : { transform: [{ skewX: deg }] };
|
|
2125
|
+
},
|
|
2126
|
+
"skew-y": ({ value, negative, isArbitrary }) => {
|
|
2127
|
+
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
2128
|
+
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
2129
|
+
return getEffectiveIsWeb() ? { transform: `skewY(${deg})` } : { transform: [{ skewY: deg }] };
|
|
2130
|
+
},
|
|
2131
|
+
// Arbitrary full transform string: transform-[rotate(45deg)_scale(1.5)]
|
|
2132
|
+
transform: ({ value, isArbitrary }) => {
|
|
2133
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2134
|
+
if (isArbitrary) return { transform: value.replace(/_/g, " ") };
|
|
2135
|
+
if (value === "none") return { transform: "none" };
|
|
2136
|
+
return null;
|
|
2137
|
+
},
|
|
2138
|
+
// Transform origin
|
|
2139
|
+
origin: ({ value, isArbitrary }) => {
|
|
2140
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2141
|
+
if (isArbitrary) return { transformOrigin: value.replace(/_/g, " ") };
|
|
2142
|
+
const origins = {
|
|
2143
|
+
center: "center",
|
|
2144
|
+
top: "top",
|
|
2145
|
+
"top-right": "top right",
|
|
2146
|
+
right: "right",
|
|
2147
|
+
"bottom-right": "bottom right",
|
|
2148
|
+
bottom: "bottom",
|
|
2149
|
+
"bottom-left": "bottom left",
|
|
2150
|
+
left: "left",
|
|
2151
|
+
"top-left": "top left"
|
|
2152
|
+
};
|
|
2153
|
+
return origins[value] ? { transformOrigin: origins[value] } : null;
|
|
2175
2154
|
},
|
|
2176
2155
|
// ── Scale ──────────────────────────────────────────────────────────────────
|
|
2177
2156
|
// Non-arbitrary: scale-150 → value='150' → 150/100 = 1.5
|
|
@@ -2202,35 +2181,86 @@ var RESOLVERS = {
|
|
|
2202
2181
|
const finalDeg = negative ? -deg : deg;
|
|
2203
2182
|
return getEffectiveIsWeb() ? { transform: `rotate(${finalDeg}deg)` } : { transform: [{ rotate: `${finalDeg}deg` }] };
|
|
2204
2183
|
},
|
|
2205
|
-
// ──
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
const n = parseFloat(v);
|
|
2212
|
-
return isNaN(n) ? null : { transform: [{ translateX: n }] };
|
|
2184
|
+
// ── Perspective transform (cross-platform: iOS, Android, web) ────────────
|
|
2185
|
+
perspective: ({ value, isArbitrary }) => {
|
|
2186
|
+
if (isArbitrary) {
|
|
2187
|
+
const numPx = parseFloat(value);
|
|
2188
|
+
if (getEffectiveIsWeb()) return { transform: `perspective(${value})` };
|
|
2189
|
+
return isNaN(numPx) ? null : { transform: [{ perspective: numPx }] };
|
|
2213
2190
|
}
|
|
2214
|
-
return
|
|
2191
|
+
if (value === "none") return getEffectiveIsWeb() ? { transform: "none" } : null;
|
|
2192
|
+
const n = parseFloat(value);
|
|
2193
|
+
if (isNaN(n)) return null;
|
|
2194
|
+
return getEffectiveIsWeb() ? { transform: `perspective(${n}px)` } : { transform: [{ perspective: n }] };
|
|
2195
|
+
}
|
|
2196
|
+
};
|
|
2197
|
+
|
|
2198
|
+
// src/core/resolvers/effects.ts
|
|
2199
|
+
function keyframeDeclToCSS(decl) {
|
|
2200
|
+
return Object.entries(decl).map(([prop, val]) => `${prop.replace(/([A-Z])/g, "-$1").toLowerCase()}: ${val}`).join("; ");
|
|
2201
|
+
}
|
|
2202
|
+
function buildKeyframeCSS(name, steps) {
|
|
2203
|
+
const body = Object.entries(steps).map(([selector, decl]) => `${selector} { ${keyframeDeclToCSS(decl)} }`).join(" ");
|
|
2204
|
+
return `@keyframes ${name} { ${body} }`;
|
|
2205
|
+
}
|
|
2206
|
+
var BUILTIN_ANIMATIONS = {
|
|
2207
|
+
none: { animation: "none" },
|
|
2208
|
+
spin: {
|
|
2209
|
+
animation: "kb-spin 1s linear infinite",
|
|
2210
|
+
__keyframe: "@keyframes kb-spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }"
|
|
2215
2211
|
},
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2212
|
+
ping: {
|
|
2213
|
+
animation: "kb-ping 1s cubic-bezier(0,0,0.2,1) infinite",
|
|
2214
|
+
__keyframe: "@keyframes kb-ping { 75%, 100% { transform: scale(2); opacity: 0 } }"
|
|
2215
|
+
},
|
|
2216
|
+
pulse: {
|
|
2217
|
+
animation: "kb-pulse 2s cubic-bezier(0.4,0,0.6,1) infinite",
|
|
2218
|
+
__keyframe: "@keyframes kb-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }"
|
|
2219
|
+
},
|
|
2220
|
+
bounce: {
|
|
2221
|
+
animation: "kb-bounce 1s infinite",
|
|
2222
|
+
__keyframe: "@keyframes kb-bounce { 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8,0,1,1) } 50% { transform: none; animation-timing-function: cubic-bezier(0,0,0.2,1) } }"
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
function buildAnimationValue(animation, keyframes) {
|
|
2226
|
+
const words = animation.trim().split(/\s+/);
|
|
2227
|
+
const name = words[0];
|
|
2228
|
+
if (!name) return { animation };
|
|
2229
|
+
const builtin = BUILTIN_ANIMATIONS[name];
|
|
2230
|
+
if (builtin?.__keyframe) {
|
|
2231
|
+
const kbName = builtin.animation.split(/\s+/, 1)[0];
|
|
2232
|
+
return { animation: [kbName, ...words.slice(1)].join(" "), __keyframe: builtin.__keyframe };
|
|
2233
|
+
}
|
|
2234
|
+
const steps = keyframes?.[name];
|
|
2235
|
+
return steps ? { animation, __keyframe: buildKeyframeCSS(name, steps) } : { animation };
|
|
2236
|
+
}
|
|
2237
|
+
var effectResolvers = {
|
|
2238
|
+
// ── Opacity ────────────────────────────────────────────────────────────────
|
|
2239
|
+
opacity: ({ value, isArbitrary }, { opacity }) => {
|
|
2240
|
+
if (isArbitrary) {
|
|
2241
|
+
const v2 = parseFloat(value);
|
|
2242
|
+
return isNaN(v2) ? null : { opacity: v2 > 1 ? v2 / 100 : v2 };
|
|
2223
2243
|
}
|
|
2224
|
-
|
|
2244
|
+
const v = opacity[value];
|
|
2245
|
+
if (v !== void 0) return { opacity: v };
|
|
2246
|
+
const n = parseFloat(value);
|
|
2247
|
+
return isNaN(n) ? null : { opacity: n > 1 ? n / 100 : n };
|
|
2225
2248
|
},
|
|
2226
|
-
// ──
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2249
|
+
// ── Shadow ─────────────────────────────────────────────────────────────────
|
|
2250
|
+
shadow: ({ value }, { shadow }) => {
|
|
2251
|
+
const key = value === "" ? "DEFAULT" : value;
|
|
2252
|
+
return shadow[key] ?? null;
|
|
2253
|
+
},
|
|
2254
|
+
// ── Animations (CSS keyframe animations, web-only) ────────────────────────
|
|
2255
|
+
// Each variant injects a @keyframes rule once via the __keyframe marker.
|
|
2256
|
+
// resolver.ts detects __keyframe, injects the rule, then strips the marker
|
|
2257
|
+
// so it never reaches element inline styles.
|
|
2258
|
+
animate: ({ value, isArbitrary }, theme) => {
|
|
2259
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2260
|
+
if (isArbitrary) return buildAnimationValue(value.replace(/_/g, " "), theme.keyframes);
|
|
2261
|
+
if (value in BUILTIN_ANIMATIONS) return BUILTIN_ANIMATIONS[value];
|
|
2262
|
+
const custom = theme.animation?.[value];
|
|
2263
|
+
return custom ? buildAnimationValue(custom, theme.keyframes) : null;
|
|
2234
2264
|
},
|
|
2235
2265
|
// ── Transition (web-only; use Animated API on native) ─────────────────────
|
|
2236
2266
|
transition: ({ value }) => {
|
|
@@ -2258,91 +2288,107 @@ var RESOLVERS = {
|
|
|
2258
2288
|
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
2259
2289
|
const ms = isArbitrary ? value : `${value}ms`;
|
|
2260
2290
|
return { transitionDelay: ms };
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2293
|
+
|
|
2294
|
+
// src/core/resolvers/misc.ts
|
|
2295
|
+
var miscResolvers = {
|
|
2296
|
+
// ── Arbitrary CSS property (web-only): [property:value] with no utility prefix ──
|
|
2297
|
+
// e.g. [mask-type:luminance], [--my-var:10px]. parser.ts already isolates this case
|
|
2298
|
+
// as utility: '' — it's ALSO how a stray, prefix-less negative bracket ("-[10px]",
|
|
2299
|
+
// presumably a typo) parses, which is why this only fires when the arbitrary value
|
|
2300
|
+
// itself contains a "property:value" pair; anything else (no colon) still resolves
|
|
2301
|
+
// to null exactly as before this resolver existed, rather than guessing a property.
|
|
2302
|
+
//
|
|
2303
|
+
// Only the FIRST colon splits property from value — the value itself may contain
|
|
2304
|
+
// more colons (a URL's "http://…") and must stay intact: [background:url(http://x/a.png)].
|
|
2305
|
+
// camelToKebab() in resolver.ts is a no-op on an already-kebab-case (or "--"-prefixed
|
|
2306
|
+
// custom property) key, so it can be used as the style object key as-written with no
|
|
2307
|
+
// extra case conversion — it only needs to look like a plausible CSS property name.
|
|
2308
|
+
"": ({ value, isArbitrary, negative }) => {
|
|
2309
|
+
if (!getEffectiveIsWeb() || !isArbitrary || !value) return null;
|
|
2310
|
+
if (negative) return null;
|
|
2311
|
+
const colonIdx = value.indexOf(":");
|
|
2312
|
+
if (colonIdx <= 0) return null;
|
|
2313
|
+
const prop = value.slice(0, colonIdx).trim();
|
|
2314
|
+
const cssValue = value.slice(colonIdx + 1).trim();
|
|
2315
|
+
if (!cssValue || !/^(--[\w-]+|[a-zA-Z-]+)$/.test(prop)) return null;
|
|
2316
|
+
return { [prop]: cssValue };
|
|
2261
2317
|
},
|
|
2262
|
-
// ──
|
|
2263
|
-
//
|
|
2264
|
-
//
|
|
2265
|
-
//
|
|
2266
|
-
//
|
|
2267
|
-
//
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
if (!value) {
|
|
2276
|
-
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2318
|
+
// ── SVG stroke/fill (web-only) ────────────────────────────────────────────
|
|
2319
|
+
// Native is intentionally excluded: react-native-svg's <Path>/<Circle>/etc.
|
|
2320
|
+
// take stroke/fill as component PROPS, not style entries, so there's no
|
|
2321
|
+
// reliable way to apply a resolved color through the `style` prop there.
|
|
2322
|
+
// `stroke-{n}` sets strokeWidth (a plain number, unlike a color) — same
|
|
2323
|
+
// color-first-then-numeric-fallback disambiguation `border` uses above.
|
|
2324
|
+
stroke: ({ value, isArbitrary }, { colors }) => {
|
|
2325
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2326
|
+
if (!value) return null;
|
|
2327
|
+
if (value === "none") return { stroke: "none" };
|
|
2328
|
+
if (isArbitrary) {
|
|
2329
|
+
const w = toNativeValue(value);
|
|
2330
|
+
return typeof w === "number" ? { strokeWidth: w } : { stroke: value };
|
|
2277
2331
|
}
|
|
2278
|
-
|
|
2279
|
-
|
|
2332
|
+
const color = resolveColor(value, colors, false);
|
|
2333
|
+
if (color) return { stroke: color };
|
|
2334
|
+
const n = parseFloat(value);
|
|
2335
|
+
return isNaN(n) ? null : { strokeWidth: n };
|
|
2336
|
+
},
|
|
2337
|
+
fill: ({ value, isArbitrary }, { colors }) => {
|
|
2338
|
+
if (!getEffectiveIsWeb()) return null;
|
|
2339
|
+
if (!value) return null;
|
|
2340
|
+
if (value === "none") return { fill: "none" };
|
|
2341
|
+
if (isArbitrary) return { fill: value };
|
|
2342
|
+
const color = resolveColor(value, colors, false);
|
|
2343
|
+
return color ? { fill: color } : null;
|
|
2344
|
+
},
|
|
2345
|
+
// ── Text shadow (cross-platform: iOS, Android, web) ─────────────────────
|
|
2346
|
+
// Named presets give cross-platform shadow; arbitrary is web-only.
|
|
2347
|
+
"text-shadow": ({ value, isArbitrary }, { colors }) => {
|
|
2348
|
+
if (value === "none") {
|
|
2349
|
+
return getEffectiveIsWeb() ? { textShadow: "none" } : { textShadowColor: "transparent", textShadowOffset: { width: 0, height: 0 }, textShadowRadius: 0 };
|
|
2280
2350
|
}
|
|
2281
|
-
const
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2351
|
+
const webPresets = {
|
|
2352
|
+
"": "0 2px 4px rgba(0,0,0,0.3)",
|
|
2353
|
+
sm: "0 1px 2px rgba(0,0,0,0.3)",
|
|
2354
|
+
md: "0 4px 6px rgba(0,0,0,0.3)",
|
|
2355
|
+
lg: "0 8px 16px rgba(0,0,0,0.5)",
|
|
2356
|
+
xl: "0 16px 32px rgba(0,0,0,0.5)"
|
|
2357
|
+
};
|
|
2358
|
+
const nativePresets = {
|
|
2359
|
+
"": { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 2 }, textShadowRadius: 4 },
|
|
2360
|
+
sm: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 1 }, textShadowRadius: 2 },
|
|
2361
|
+
md: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 4 }, textShadowRadius: 6 },
|
|
2362
|
+
lg: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 8 }, textShadowRadius: 16 },
|
|
2363
|
+
xl: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 16 }, textShadowRadius: 32 }
|
|
2364
|
+
};
|
|
2365
|
+
if (value in webPresets) {
|
|
2366
|
+
if (getEffectiveIsWeb()) return { textShadow: webPresets[value] };
|
|
2367
|
+
return nativePresets[value] ?? null;
|
|
2285
2368
|
}
|
|
2286
2369
|
if (isArbitrary) {
|
|
2287
|
-
|
|
2288
|
-
if (numMatch) {
|
|
2289
|
-
const unit = numMatch[2] ?? "px";
|
|
2290
|
-
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2291
|
-
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2292
|
-
}
|
|
2293
|
-
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2370
|
+
return getEffectiveIsWeb() ? { textShadow: value.replace(/_/g, " ") } : null;
|
|
2294
2371
|
}
|
|
2295
2372
|
const color = resolveColor(value, colors, false);
|
|
2296
2373
|
if (color) {
|
|
2297
|
-
return
|
|
2374
|
+
return getEffectiveIsWeb() ? { textShadow: `0 2px 4px ${color}` } : { textShadowColor: color };
|
|
2298
2375
|
}
|
|
2299
2376
|
return null;
|
|
2300
|
-
},
|
|
2301
|
-
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2302
|
-
// create a gap between the element and the ring. There's no native
|
|
2303
|
-
// equivalent to approximate that with (a border can't create a gap outside
|
|
2304
|
-
// its own element without an extra wrapper view), so this stays a no-op
|
|
2305
|
-
// on native rather than rendering a misleading half-translation.
|
|
2306
|
-
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2307
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2308
|
-
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2309
|
-
const DEFAULT_RING_WIDTH = 3;
|
|
2310
|
-
const offsetTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2311
|
-
let offsetWidth;
|
|
2312
|
-
if (!isArbitrary) {
|
|
2313
|
-
offsetWidth = value in offsetTokens ? offsetTokens[value] : null;
|
|
2314
|
-
} else {
|
|
2315
|
-
offsetWidth = /^-?\d+(\.\d+)?$/.test(value) ? parseFloat(value) : value;
|
|
2316
|
-
}
|
|
2317
|
-
if (offsetWidth === null || typeof offsetWidth === "number" && isNaN(offsetWidth)) return null;
|
|
2318
|
-
const isZero = offsetWidth === 0 || offsetWidth === "0";
|
|
2319
|
-
const offsetCss = typeof offsetWidth === "number" ? `${offsetWidth}px` : offsetWidth;
|
|
2320
|
-
return {
|
|
2321
|
-
boxShadow: isZero ? `0 0 0 ${DEFAULT_RING_WIDTH}px ${DEFAULT_RING_COLOR}` : `0 0 0 ${offsetCss} #fff, 0 0 0 calc(${offsetCss} + ${DEFAULT_RING_WIDTH}px) ${DEFAULT_RING_COLOR}`
|
|
2322
|
-
};
|
|
2323
|
-
},
|
|
2324
|
-
// ── Space between ─────────────────────────────────────────────────────────
|
|
2325
|
-
// On web: emits __spaceX/__spaceY markers → resolver generates > * + * CSS rules.
|
|
2326
|
-
// On native (RN 0.71+): uses columnGap/rowGap directly.
|
|
2327
|
-
"space-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2328
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2329
|
-
if (v === null) return null;
|
|
2330
|
-
if (getEffectiveIsWeb()) return { __spaceX: v };
|
|
2331
|
-
return { columnGap: v };
|
|
2332
|
-
},
|
|
2333
|
-
"space-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2334
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2335
|
-
if (v === null) return null;
|
|
2336
|
-
if (getEffectiveIsWeb()) return { __spaceY: v };
|
|
2337
|
-
return { rowGap: v };
|
|
2338
2377
|
}
|
|
2339
2378
|
};
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2379
|
+
|
|
2380
|
+
// src/core/utilities.ts
|
|
2381
|
+
var RESOLVERS = {
|
|
2382
|
+
...colorResolvers,
|
|
2383
|
+
...spacingResolvers,
|
|
2384
|
+
...borderResolvers,
|
|
2385
|
+
...layoutResolvers,
|
|
2386
|
+
...typographyResolvers,
|
|
2387
|
+
...filterResolvers,
|
|
2388
|
+
...transformResolvers,
|
|
2389
|
+
...effectResolvers,
|
|
2390
|
+
...miscResolvers
|
|
2391
|
+
};
|
|
2346
2392
|
var NAMED_GROUP_PEER_MARKER_RE = /^(group|peer)\/.+$/;
|
|
2347
2393
|
function resolveUtility(parsed, theme) {
|
|
2348
2394
|
if (!parsed.value) {
|
|
@@ -2390,6 +2436,47 @@ function kbachWarn(message) {
|
|
|
2390
2436
|
);
|
|
2391
2437
|
}
|
|
2392
2438
|
|
|
2439
|
+
// src/core/cache.ts
|
|
2440
|
+
var LRUCache = class {
|
|
2441
|
+
constructor(capacity = 1e4, onEvict) {
|
|
2442
|
+
this.capacity = capacity;
|
|
2443
|
+
if (capacity <= 0) throw new Error("LRUCache: capacity must be a positive integer");
|
|
2444
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
2445
|
+
this.onEvict = onEvict;
|
|
2446
|
+
}
|
|
2447
|
+
get(key) {
|
|
2448
|
+
if (!this.cache.has(key)) return void 0;
|
|
2449
|
+
const value = this.cache.get(key);
|
|
2450
|
+
this.cache.delete(key);
|
|
2451
|
+
this.cache.set(key, value);
|
|
2452
|
+
return value;
|
|
2453
|
+
}
|
|
2454
|
+
set(key, value) {
|
|
2455
|
+
if (this.cache.has(key)) {
|
|
2456
|
+
this.cache.delete(key);
|
|
2457
|
+
} else if (this.cache.size >= this.capacity) {
|
|
2458
|
+
const oldestKey = this.cache.keys().next().value;
|
|
2459
|
+
const oldestValue = this.cache.get(oldestKey);
|
|
2460
|
+
this.cache.delete(oldestKey);
|
|
2461
|
+
this.onEvict?.(oldestKey, oldestValue);
|
|
2462
|
+
}
|
|
2463
|
+
this.cache.set(key, value);
|
|
2464
|
+
return this;
|
|
2465
|
+
}
|
|
2466
|
+
has(key) {
|
|
2467
|
+
return this.cache.has(key);
|
|
2468
|
+
}
|
|
2469
|
+
delete(key) {
|
|
2470
|
+
return this.cache.delete(key);
|
|
2471
|
+
}
|
|
2472
|
+
clear() {
|
|
2473
|
+
this.cache.clear();
|
|
2474
|
+
}
|
|
2475
|
+
get size() {
|
|
2476
|
+
return this.cache.size;
|
|
2477
|
+
}
|
|
2478
|
+
};
|
|
2479
|
+
|
|
2393
2480
|
// src/core/registry.ts
|
|
2394
2481
|
var BUILTIN_MODIFIERS = {
|
|
2395
2482
|
// ── Mode ─────────────────────────────────────────────────────────────────
|
|
@@ -2476,7 +2563,7 @@ function clearPluginModifiers() {
|
|
|
2476
2563
|
_invalidate();
|
|
2477
2564
|
}
|
|
2478
2565
|
var NAMED_GROUP_PEER_RE = /^(group|peer)-(hover|focus)\/(.+)$/;
|
|
2479
|
-
var _namedModifierCache =
|
|
2566
|
+
var _namedModifierCache = new LRUCache(1e4);
|
|
2480
2567
|
function getNamedGroupPeerModifier(name) {
|
|
2481
2568
|
const cached = _namedModifierCache.get(name);
|
|
2482
2569
|
if (cached) return cached;
|
|
@@ -2647,51 +2734,10 @@ function findOuterColon(s) {
|
|
|
2647
2734
|
return -1;
|
|
2648
2735
|
}
|
|
2649
2736
|
|
|
2650
|
-
// src/core/cache.ts
|
|
2651
|
-
var LRUCache = class {
|
|
2652
|
-
constructor(capacity = 1e4, onEvict) {
|
|
2653
|
-
this.capacity = capacity;
|
|
2654
|
-
if (capacity <= 0) throw new Error("LRUCache: capacity must be a positive integer");
|
|
2655
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
2656
|
-
this.onEvict = onEvict;
|
|
2657
|
-
}
|
|
2658
|
-
get(key) {
|
|
2659
|
-
if (!this.cache.has(key)) return void 0;
|
|
2660
|
-
const value = this.cache.get(key);
|
|
2661
|
-
this.cache.delete(key);
|
|
2662
|
-
this.cache.set(key, value);
|
|
2663
|
-
return value;
|
|
2664
|
-
}
|
|
2665
|
-
set(key, value) {
|
|
2666
|
-
if (this.cache.has(key)) {
|
|
2667
|
-
this.cache.delete(key);
|
|
2668
|
-
} else if (this.cache.size >= this.capacity) {
|
|
2669
|
-
const oldestKey = this.cache.keys().next().value;
|
|
2670
|
-
const oldestValue = this.cache.get(oldestKey);
|
|
2671
|
-
this.cache.delete(oldestKey);
|
|
2672
|
-
this.onEvict?.(oldestKey, oldestValue);
|
|
2673
|
-
}
|
|
2674
|
-
this.cache.set(key, value);
|
|
2675
|
-
return this;
|
|
2676
|
-
}
|
|
2677
|
-
has(key) {
|
|
2678
|
-
return this.cache.has(key);
|
|
2679
|
-
}
|
|
2680
|
-
delete(key) {
|
|
2681
|
-
return this.cache.delete(key);
|
|
2682
|
-
}
|
|
2683
|
-
clear() {
|
|
2684
|
-
this.cache.clear();
|
|
2685
|
-
}
|
|
2686
|
-
get size() {
|
|
2687
|
-
return this.cache.size;
|
|
2688
|
-
}
|
|
2689
|
-
};
|
|
2690
|
-
|
|
2691
2737
|
// src/core/resolver.ts
|
|
2692
|
-
var
|
|
2738
|
+
var _defaultFontFamily;
|
|
2693
2739
|
function setDefaultFontFamily(font) {
|
|
2694
|
-
|
|
2740
|
+
_defaultFontFamily = font;
|
|
2695
2741
|
}
|
|
2696
2742
|
var _styleEl = null;
|
|
2697
2743
|
var _ruleIndexByKey = /* @__PURE__ */ new Map();
|
|
@@ -2711,9 +2757,9 @@ function evictInjectedRule(rule) {
|
|
|
2711
2757
|
}
|
|
2712
2758
|
}
|
|
2713
2759
|
var _injectedRules = new LRUCache(5e4, evictInjectedRule);
|
|
2714
|
-
var
|
|
2760
|
+
var _runtimeCSSDisabled = false;
|
|
2715
2761
|
function isRuntimeCSSDisabled() {
|
|
2716
|
-
return
|
|
2762
|
+
return _runtimeCSSDisabled;
|
|
2717
2763
|
}
|
|
2718
2764
|
function getStyleEl() {
|
|
2719
2765
|
if (_styleEl) return _styleEl;
|
|
@@ -2936,14 +2982,7 @@ function deepMerge(base, override) {
|
|
|
2936
2982
|
}
|
|
2937
2983
|
return result;
|
|
2938
2984
|
}
|
|
2939
|
-
var
|
|
2940
|
-
function getConfigStore() {
|
|
2941
|
-
const g = globalThis;
|
|
2942
|
-
if (!g[CONFIG_KEY]) {
|
|
2943
|
-
g[CONFIG_KEY] = { resolved: null, listeners: /* @__PURE__ */ new Set(), customVariants: {} };
|
|
2944
|
-
}
|
|
2945
|
-
return g[CONFIG_KEY];
|
|
2946
|
-
}
|
|
2985
|
+
var configStore = { resolved: null, listeners: /* @__PURE__ */ new Set(), customVariants: {} };
|
|
2947
2986
|
function resolveOneRef(ref, colors) {
|
|
2948
2987
|
const lastDash = ref.lastIndexOf("-");
|
|
2949
2988
|
if (lastDash <= 0) return null;
|
|
@@ -3017,8 +3056,7 @@ function buildConfig(userConfig) {
|
|
|
3017
3056
|
clearPluginUtilities();
|
|
3018
3057
|
clearPluginModifiers();
|
|
3019
3058
|
}
|
|
3020
|
-
const
|
|
3021
|
-
for (const k of Object.keys(_store.customVariants)) delete _store.customVariants[k];
|
|
3059
|
+
for (const k of Object.keys(configStore.customVariants)) delete configStore.customVariants[k];
|
|
3022
3060
|
const pluginAPI = makePluginAPI(resolved.theme);
|
|
3023
3061
|
for (const plugin of resolved.plugins) {
|
|
3024
3062
|
plugin(pluginAPI);
|
|
@@ -3065,26 +3103,7 @@ function makePluginAPI(theme) {
|
|
|
3065
3103
|
}
|
|
3066
3104
|
};
|
|
3067
3105
|
}
|
|
3068
|
-
var customVariants =
|
|
3069
|
-
{},
|
|
3070
|
-
{
|
|
3071
|
-
get(_t, p) {
|
|
3072
|
-
return typeof p === "string" ? getConfigStore().customVariants[p] : void 0;
|
|
3073
|
-
},
|
|
3074
|
-
set(_t, p, v) {
|
|
3075
|
-
if (typeof p === "string") getConfigStore().customVariants[p] = v;
|
|
3076
|
-
return true;
|
|
3077
|
-
},
|
|
3078
|
-
ownKeys() {
|
|
3079
|
-
return Object.keys(getConfigStore().customVariants);
|
|
3080
|
-
},
|
|
3081
|
-
getOwnPropertyDescriptor(_t, p) {
|
|
3082
|
-
if (typeof p !== "string") return void 0;
|
|
3083
|
-
const v = getConfigStore().customVariants[p];
|
|
3084
|
-
return v !== void 0 ? { value: v, writable: true, enumerable: true, configurable: true } : void 0;
|
|
3085
|
-
}
|
|
3086
|
-
}
|
|
3087
|
-
);
|
|
3106
|
+
var customVariants = configStore.customVariants;
|
|
3088
3107
|
|
|
3089
3108
|
// src/vite-plugin.ts
|
|
3090
3109
|
var process2 = import_node_process.default;
|
|
@@ -3444,7 +3463,9 @@ function pushTokens(str, into) {
|
|
|
3444
3463
|
if (tok && !NOT_A_CLASS_NAME_RE.test(tok)) into.add(tok);
|
|
3445
3464
|
}
|
|
3446
3465
|
}
|
|
3447
|
-
|
|
3466
|
+
var MAX_SCAN_DEPTH = 10;
|
|
3467
|
+
function scanDir(dir, onFile, depth = 0) {
|
|
3468
|
+
if (depth > MAX_SCAN_DEPTH) return;
|
|
3448
3469
|
let entries;
|
|
3449
3470
|
try {
|
|
3450
3471
|
entries = (0, import_fs.readdirSync)(dir);
|
|
@@ -3459,7 +3480,7 @@ function scanDir(dir, onFile) {
|
|
|
3459
3480
|
const full = (0, import_path.join)(dir, entry);
|
|
3460
3481
|
try {
|
|
3461
3482
|
const st = (0, import_fs.statSync)(full);
|
|
3462
|
-
if (st.isDirectory()) scanDir(full, onFile);
|
|
3483
|
+
if (st.isDirectory()) scanDir(full, onFile, depth + 1);
|
|
3463
3484
|
else if (/\.(tsx?|jsx?)$/.test(entry)) onFile(full, (0, import_fs.readFileSync)(full, "utf-8"));
|
|
3464
3485
|
} catch (err) {
|
|
3465
3486
|
warn(`Can't process ${full}: ${err.message}`);
|
|
@@ -3477,7 +3498,8 @@ function scanCssFileInto(filePath, into) {
|
|
|
3477
3498
|
} catch {
|
|
3478
3499
|
}
|
|
3479
3500
|
}
|
|
3480
|
-
function scanCssSelectorsInto(dir, into) {
|
|
3501
|
+
function scanCssSelectorsInto(dir, into, depth = 0) {
|
|
3502
|
+
if (depth > MAX_SCAN_DEPTH) return;
|
|
3481
3503
|
let entries;
|
|
3482
3504
|
try {
|
|
3483
3505
|
entries = (0, import_fs.readdirSync)(dir);
|
|
@@ -3489,7 +3511,7 @@ function scanCssSelectorsInto(dir, into) {
|
|
|
3489
3511
|
const full = (0, import_path.join)(dir, entry);
|
|
3490
3512
|
try {
|
|
3491
3513
|
const st = (0, import_fs.statSync)(full);
|
|
3492
|
-
if (st.isDirectory()) scanCssSelectorsInto(full, into);
|
|
3514
|
+
if (st.isDirectory()) scanCssSelectorsInto(full, into, depth + 1);
|
|
3493
3515
|
else if (CSS_FILE_RE.test(entry)) scanCssFileInto(full, into);
|
|
3494
3516
|
} catch {
|
|
3495
3517
|
}
|
|
@@ -3556,6 +3578,17 @@ function kbach(userConfigOrOptions) {
|
|
|
3556
3578
|
function generateCSS() {
|
|
3557
3579
|
return formatKbachCSS(buildTokenCSSView(), cfg.theme, responsiveRe);
|
|
3558
3580
|
}
|
|
3581
|
+
function syncMainCSSFile(server) {
|
|
3582
|
+
const active = /* @__PURE__ */ new Set();
|
|
3583
|
+
for (const tokens of fileTokens.values()) for (const t of tokens) active.add(t);
|
|
3584
|
+
for (const tok of tokenCSS.keys()) {
|
|
3585
|
+
if (!active.has(tok)) tokenCSS.delete(tok);
|
|
3586
|
+
}
|
|
3587
|
+
if (mainCSSFile) {
|
|
3588
|
+
const changed = writeKbachToFile(mainCSSFile, generateCSS());
|
|
3589
|
+
if (changed) server.watcher.emit("change", mainCSSFile);
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3559
3592
|
return {
|
|
3560
3593
|
name: "kbach",
|
|
3561
3594
|
enforce: "pre",
|
|
@@ -3615,6 +3648,37 @@ ${code}`,
|
|
|
3615
3648
|
initialScan();
|
|
3616
3649
|
if (mainCSSFile) writeKbachToFile(mainCSSFile, generateCSS());
|
|
3617
3650
|
},
|
|
3651
|
+
// Vite's `handleHotUpdate` hook only fires for `type === "update"` (plain
|
|
3652
|
+
// file edits) — it's never called for file create/delete, which land on
|
|
3653
|
+
// the watcher's own 'add'/'unlink' events instead (confirmed against
|
|
3654
|
+
// vite's own onHMRUpdate/handleHMRUpdate: the hook loop is gated on
|
|
3655
|
+
// `type === "update"`). Without also listening on those two events here,
|
|
3656
|
+
// creating a new file with new Kbach classes never adds them to
|
|
3657
|
+
// kbach.css, and deleting a file never removes its classes, until a full
|
|
3658
|
+
// dev-server restart. configureServer gives access to the raw watcher so
|
|
3659
|
+
// both cases can share the same sync logic as a plain edit.
|
|
3660
|
+
configureServer(server) {
|
|
3661
|
+
const onAddOrUnlink = (file, isUnlink) => {
|
|
3662
|
+
if (file.includes("node_modules")) return;
|
|
3663
|
+
if (CSS_FILE_RE.test(file)) {
|
|
3664
|
+
if (!isUnlink) scanCssFileInto(file, projectCssClasses);
|
|
3665
|
+
return;
|
|
3666
|
+
}
|
|
3667
|
+
if (!/\.(tsx?|jsx?)$/.test(file)) return;
|
|
3668
|
+
if (isUnlink) {
|
|
3669
|
+
fileTokens.delete(normPath(file));
|
|
3670
|
+
} else {
|
|
3671
|
+
try {
|
|
3672
|
+
processFile(file, (0, import_fs.readFileSync)(file, "utf-8"));
|
|
3673
|
+
} catch {
|
|
3674
|
+
fileTokens.delete(normPath(file));
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
syncMainCSSFile(server);
|
|
3678
|
+
};
|
|
3679
|
+
server.watcher.on("add", (file) => onAddOrUnlink(file, false));
|
|
3680
|
+
server.watcher.on("unlink", (file) => onAddOrUnlink(file, true));
|
|
3681
|
+
},
|
|
3618
3682
|
handleHotUpdate({ file, server }) {
|
|
3619
3683
|
if (file.includes("node_modules")) return;
|
|
3620
3684
|
if (CSS_FILE_RE.test(file)) {
|
|
@@ -3627,15 +3691,7 @@ ${code}`,
|
|
|
3627
3691
|
} catch {
|
|
3628
3692
|
fileTokens.delete(normPath(file));
|
|
3629
3693
|
}
|
|
3630
|
-
|
|
3631
|
-
for (const tokens of fileTokens.values()) for (const t of tokens) active.add(t);
|
|
3632
|
-
for (const tok of tokenCSS.keys()) {
|
|
3633
|
-
if (!active.has(tok)) tokenCSS.delete(tok);
|
|
3634
|
-
}
|
|
3635
|
-
if (mainCSSFile) {
|
|
3636
|
-
const changed = writeKbachToFile(mainCSSFile, generateCSS());
|
|
3637
|
-
if (changed) server.watcher.emit("change", mainCSSFile);
|
|
3638
|
-
}
|
|
3694
|
+
syncMainCSSFile(server);
|
|
3639
3695
|
}
|
|
3640
3696
|
};
|
|
3641
3697
|
}
|