@kbach/ui 0.1.0-beta.1 → 0.1.0-beta.2
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/KBACH.md +10 -1
- package/dist/{chunk-VBK6ORYJ.mjs → chunk-LY753XBX.mjs} +49 -9
- package/dist/{chunk-KHTZ244V.mjs → chunk-UVXTWGHQ.mjs} +1 -1
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.js +49 -9
- package/dist/index.mjs +1 -1
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.mjs +2 -2
- package/dist/vite-plugin.js +77 -11
- package/dist/vite-plugin.mjs +77 -11
- package/kbach-ui.md +12 -1
- package/package.json +1 -1
package/KBACH.md
CHANGED
|
@@ -625,8 +625,9 @@ rounded-tl/tr/bl/br border radius on one corner
|
|
|
625
625
|
|
|
626
626
|
### Shadow
|
|
627
627
|
```
|
|
628
|
-
shadow-sm/DEFAULT/md/lg/xl/2xl/none
|
|
628
|
+
shadow-sm/DEFAULT/md/lg/xl/2xl/inner/none
|
|
629
629
|
```
|
|
630
|
+
Web: real `box-shadow` (Tailwind's own default values). Native: RN's shadowColor/shadowOffset/shadowOpacity/shadowRadius/elevation, tuned independently for RN's elevation model — not derived from the web value. `shadow-inner` is web-only (no native inset-shadow equivalent). Customize/add sizes via `theme.extend.shadow` — each preset key merges independently (see Theme Configuration below).
|
|
630
631
|
|
|
631
632
|
### Opacity
|
|
632
633
|
```
|
|
@@ -906,6 +907,14 @@ module.exports = {
|
|
|
906
907
|
colors: { brand: { 6: '#6366f1' } },
|
|
907
908
|
spacing: { 18: 72, 22: 88 },
|
|
908
909
|
fontSize: { '10xl': 160 },
|
|
910
|
+
// Each preset key merges independently — overriding lg's boxShadow
|
|
911
|
+
// (the web value) leaves its native shadowColor/shadowOffset/etc.
|
|
912
|
+
// untouched, and a brand-new key (e.g. '3xl') adds a new shadow-3xl
|
|
913
|
+
// utility alongside the defaults.
|
|
914
|
+
shadow: {
|
|
915
|
+
lg: { boxShadow: '0 10px 40px -10px rgba(99, 102, 241, 0.4)' },
|
|
916
|
+
'3xl': { boxShadow: '0 35px 60px -15px rgba(0, 0, 0, 0.3)' },
|
|
917
|
+
},
|
|
909
918
|
// Custom @keyframes (web only) — declaration values are plain CSS strings.
|
|
910
919
|
// Reference by name from `animation`, then use that name as animate-{name}.
|
|
911
920
|
keyframes: {
|
|
@@ -25,7 +25,10 @@ function toNativeValue(raw) {
|
|
|
25
25
|
return raw;
|
|
26
26
|
}
|
|
27
27
|
function escapeCSSSelector(cls) {
|
|
28
|
-
|
|
28
|
+
const escaped = cls.replace(/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
29
|
+
if (!/^[0-9]/.test(escaped)) return escaped;
|
|
30
|
+
const hex = escaped.charCodeAt(0).toString(16);
|
|
31
|
+
return `\\${hex} ${escaped.slice(1)}`;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
// src/core/devWarn.ts
|
|
@@ -1863,9 +1866,23 @@ var effectResolvers = {
|
|
|
1863
1866
|
return isNaN(n) ? null : { opacity: n > 1 ? n / 100 : n };
|
|
1864
1867
|
},
|
|
1865
1868
|
// ── Shadow ─────────────────────────────────────────────────────────────────
|
|
1869
|
+
// Presets carry BOTH a web `boxShadow` string and native's shadow*/elevation
|
|
1870
|
+
// properties (theme.ts) — picked apart here rather than left for
|
|
1871
|
+
// styleValueToCSS's RN_ONLY_PROPS filter to sort out, since shadowOffset is
|
|
1872
|
+
// an object (filtered out as "not a flat style value" regardless of
|
|
1873
|
+
// platform) and boxShadow would otherwise leak into native's style prop as
|
|
1874
|
+
// an RN doesn't understand (silently ignored there, but better to not hand
|
|
1875
|
+
// native a property that was never meant for it — same branch-on-platform
|
|
1876
|
+
// pattern as bg-opacity/transition/animate above).
|
|
1866
1877
|
shadow: ({ value }, { shadow }) => {
|
|
1867
1878
|
const key = value === "" ? "DEFAULT" : value;
|
|
1868
|
-
|
|
1879
|
+
const preset = shadow[key];
|
|
1880
|
+
if (!preset) return null;
|
|
1881
|
+
if (getEffectiveIsWeb()) {
|
|
1882
|
+
return preset.boxShadow !== void 0 ? { boxShadow: preset.boxShadow } : null;
|
|
1883
|
+
}
|
|
1884
|
+
const { boxShadow, ...native } = preset;
|
|
1885
|
+
return Object.keys(native).length > 0 ? native : null;
|
|
1869
1886
|
},
|
|
1870
1887
|
// ── Animations (CSS keyframe animations, web-only) ────────────────────────
|
|
1871
1888
|
// Each variant injects a @keyframes rule once via the __keyframe marker.
|
|
@@ -2744,55 +2761,78 @@ var defaultTheme = {
|
|
|
2744
2761
|
none: "none"
|
|
2745
2762
|
// CSS: flex: none = 0 0 auto; native: mapped to 0
|
|
2746
2763
|
},
|
|
2764
|
+
// Each preset carries BOTH React Native's shadow*/elevation properties
|
|
2765
|
+
// (used on native) and a `boxShadow` string (used on web) — see the
|
|
2766
|
+
// `shadow` resolver in resolvers/effects.ts, which picks one or the other
|
|
2767
|
+
// via getEffectiveIsWeb() and strips the rest. The boxShadow values are
|
|
2768
|
+
// Tailwind's own default shadow scale verbatim (same offsets/blur/spread/
|
|
2769
|
+
// opacity), so shadow-sm/md/lg/xl/2xl look the same as their Tailwind
|
|
2770
|
+
// counterparts on web — the native shadowOffset/shadowRadius/shadowOpacity
|
|
2771
|
+
// numbers were tuned independently for RN's elevation model and don't need
|
|
2772
|
+
// to (and can't exactly) match the CSS values pixel-for-pixel.
|
|
2747
2773
|
shadow: {
|
|
2748
2774
|
sm: {
|
|
2749
2775
|
shadowColor: "#000",
|
|
2750
2776
|
shadowOffset: { width: 0, height: 1 },
|
|
2751
2777
|
shadowOpacity: 0.05,
|
|
2752
2778
|
shadowRadius: 2,
|
|
2753
|
-
elevation: 1
|
|
2779
|
+
elevation: 1,
|
|
2780
|
+
boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
2754
2781
|
},
|
|
2755
2782
|
DEFAULT: {
|
|
2756
2783
|
shadowColor: "#000",
|
|
2757
2784
|
shadowOffset: { width: 0, height: 2 },
|
|
2758
2785
|
shadowOpacity: 0.1,
|
|
2759
2786
|
shadowRadius: 4,
|
|
2760
|
-
elevation: 2
|
|
2787
|
+
elevation: 2,
|
|
2788
|
+
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"
|
|
2761
2789
|
},
|
|
2762
2790
|
md: {
|
|
2763
2791
|
shadowColor: "#000",
|
|
2764
2792
|
shadowOffset: { width: 0, height: 4 },
|
|
2765
2793
|
shadowOpacity: 0.1,
|
|
2766
2794
|
shadowRadius: 8,
|
|
2767
|
-
elevation: 3
|
|
2795
|
+
elevation: 3,
|
|
2796
|
+
boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
|
|
2768
2797
|
},
|
|
2769
2798
|
lg: {
|
|
2770
2799
|
shadowColor: "#000",
|
|
2771
2800
|
shadowOffset: { width: 0, height: 8 },
|
|
2772
2801
|
shadowOpacity: 0.1,
|
|
2773
2802
|
shadowRadius: 15,
|
|
2774
|
-
elevation: 4
|
|
2803
|
+
elevation: 4,
|
|
2804
|
+
boxShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
|
|
2775
2805
|
},
|
|
2776
2806
|
xl: {
|
|
2777
2807
|
shadowColor: "#000",
|
|
2778
2808
|
shadowOffset: { width: 0, height: 16 },
|
|
2779
2809
|
shadowOpacity: 0.1,
|
|
2780
2810
|
shadowRadius: 24,
|
|
2781
|
-
elevation: 6
|
|
2811
|
+
elevation: 6,
|
|
2812
|
+
boxShadow: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
|
|
2782
2813
|
},
|
|
2783
2814
|
"2xl": {
|
|
2784
2815
|
shadowColor: "#000",
|
|
2785
2816
|
shadowOffset: { width: 0, height: 24 },
|
|
2786
2817
|
shadowOpacity: 0.25,
|
|
2787
2818
|
shadowRadius: 48,
|
|
2788
|
-
elevation: 8
|
|
2819
|
+
elevation: 8,
|
|
2820
|
+
boxShadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)"
|
|
2821
|
+
},
|
|
2822
|
+
// Web-only — React Native has no inset-shadow equivalent (shadow*/
|
|
2823
|
+
// elevation only ever draw an outer shadow), so the native side of this
|
|
2824
|
+
// preset is intentionally empty rather than approximating something RN
|
|
2825
|
+
// can't actually do.
|
|
2826
|
+
inner: {
|
|
2827
|
+
boxShadow: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"
|
|
2789
2828
|
},
|
|
2790
2829
|
none: {
|
|
2791
2830
|
shadowColor: "transparent",
|
|
2792
2831
|
shadowOffset: { width: 0, height: 0 },
|
|
2793
2832
|
shadowOpacity: 0,
|
|
2794
2833
|
shadowRadius: 0,
|
|
2795
|
-
elevation: 0
|
|
2834
|
+
elevation: 0,
|
|
2835
|
+
boxShadow: "0 0 #0000"
|
|
2796
2836
|
}
|
|
2797
2837
|
},
|
|
2798
2838
|
screens: {
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1073,6 +1073,7 @@ declare const defaultTheme: {
|
|
|
1073
1073
|
shadowOpacity: number;
|
|
1074
1074
|
shadowRadius: number;
|
|
1075
1075
|
elevation: number;
|
|
1076
|
+
boxShadow: string;
|
|
1076
1077
|
};
|
|
1077
1078
|
DEFAULT: {
|
|
1078
1079
|
shadowColor: string;
|
|
@@ -1083,6 +1084,7 @@ declare const defaultTheme: {
|
|
|
1083
1084
|
shadowOpacity: number;
|
|
1084
1085
|
shadowRadius: number;
|
|
1085
1086
|
elevation: number;
|
|
1087
|
+
boxShadow: string;
|
|
1086
1088
|
};
|
|
1087
1089
|
md: {
|
|
1088
1090
|
shadowColor: string;
|
|
@@ -1093,6 +1095,7 @@ declare const defaultTheme: {
|
|
|
1093
1095
|
shadowOpacity: number;
|
|
1094
1096
|
shadowRadius: number;
|
|
1095
1097
|
elevation: number;
|
|
1098
|
+
boxShadow: string;
|
|
1096
1099
|
};
|
|
1097
1100
|
lg: {
|
|
1098
1101
|
shadowColor: string;
|
|
@@ -1103,6 +1106,7 @@ declare const defaultTheme: {
|
|
|
1103
1106
|
shadowOpacity: number;
|
|
1104
1107
|
shadowRadius: number;
|
|
1105
1108
|
elevation: number;
|
|
1109
|
+
boxShadow: string;
|
|
1106
1110
|
};
|
|
1107
1111
|
xl: {
|
|
1108
1112
|
shadowColor: string;
|
|
@@ -1113,6 +1117,7 @@ declare const defaultTheme: {
|
|
|
1113
1117
|
shadowOpacity: number;
|
|
1114
1118
|
shadowRadius: number;
|
|
1115
1119
|
elevation: number;
|
|
1120
|
+
boxShadow: string;
|
|
1116
1121
|
};
|
|
1117
1122
|
'2xl': {
|
|
1118
1123
|
shadowColor: string;
|
|
@@ -1123,6 +1128,10 @@ declare const defaultTheme: {
|
|
|
1123
1128
|
shadowOpacity: number;
|
|
1124
1129
|
shadowRadius: number;
|
|
1125
1130
|
elevation: number;
|
|
1131
|
+
boxShadow: string;
|
|
1132
|
+
};
|
|
1133
|
+
inner: {
|
|
1134
|
+
boxShadow: string;
|
|
1126
1135
|
};
|
|
1127
1136
|
none: {
|
|
1128
1137
|
shadowColor: string;
|
|
@@ -1133,6 +1142,7 @@ declare const defaultTheme: {
|
|
|
1133
1142
|
shadowOpacity: number;
|
|
1134
1143
|
shadowRadius: number;
|
|
1135
1144
|
elevation: number;
|
|
1145
|
+
boxShadow: string;
|
|
1136
1146
|
};
|
|
1137
1147
|
};
|
|
1138
1148
|
screens: {
|
|
@@ -1184,6 +1194,15 @@ declare function toNativeValue(raw: string): string | number;
|
|
|
1184
1194
|
/**
|
|
1185
1195
|
* Escape a class name for use inside a CSS selector.
|
|
1186
1196
|
* e.g. 'bg-[#fff]' → 'bg-\\[\\#fff\\]'
|
|
1197
|
+
*
|
|
1198
|
+
* Also escapes a leading digit: a CSS identifier can't start with an
|
|
1199
|
+
* unescaped digit — `.2xl\:text-lg { ... }` is invalid CSS and every browser
|
|
1200
|
+
* silently fails to match it, which is exactly what happens for a screen/
|
|
1201
|
+
* breakpoint literally named "2xl" (or any other numeric-leading class).
|
|
1202
|
+
* Escaped per the CSS spec — a backslash plus the character's hex code
|
|
1203
|
+
* point, followed by one space to terminate the hex escape (always safe to
|
|
1204
|
+
* include, and needed here since "2xl"'s next character "x" isn't itself a
|
|
1205
|
+
* hex digit that could otherwise be read as part of the escape by mistake).
|
|
1187
1206
|
*/
|
|
1188
1207
|
declare function escapeCSSSelector(cls: string): string;
|
|
1189
1208
|
|
package/dist/core/index.js
CHANGED
|
@@ -126,7 +126,10 @@ function toNativeValue(raw) {
|
|
|
126
126
|
return raw;
|
|
127
127
|
}
|
|
128
128
|
function escapeCSSSelector(cls) {
|
|
129
|
-
|
|
129
|
+
const escaped = cls.replace(/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
130
|
+
if (!/^[0-9]/.test(escaped)) return escaped;
|
|
131
|
+
const hex = escaped.charCodeAt(0).toString(16);
|
|
132
|
+
return `\\${hex} ${escaped.slice(1)}`;
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
// src/core/devWarn.ts
|
|
@@ -1958,9 +1961,23 @@ var effectResolvers = {
|
|
|
1958
1961
|
return isNaN(n) ? null : { opacity: n > 1 ? n / 100 : n };
|
|
1959
1962
|
},
|
|
1960
1963
|
// ── Shadow ─────────────────────────────────────────────────────────────────
|
|
1964
|
+
// Presets carry BOTH a web `boxShadow` string and native's shadow*/elevation
|
|
1965
|
+
// properties (theme.ts) — picked apart here rather than left for
|
|
1966
|
+
// styleValueToCSS's RN_ONLY_PROPS filter to sort out, since shadowOffset is
|
|
1967
|
+
// an object (filtered out as "not a flat style value" regardless of
|
|
1968
|
+
// platform) and boxShadow would otherwise leak into native's style prop as
|
|
1969
|
+
// an RN doesn't understand (silently ignored there, but better to not hand
|
|
1970
|
+
// native a property that was never meant for it — same branch-on-platform
|
|
1971
|
+
// pattern as bg-opacity/transition/animate above).
|
|
1961
1972
|
shadow: ({ value }, { shadow }) => {
|
|
1962
1973
|
const key = value === "" ? "DEFAULT" : value;
|
|
1963
|
-
|
|
1974
|
+
const preset = shadow[key];
|
|
1975
|
+
if (!preset) return null;
|
|
1976
|
+
if (getEffectiveIsWeb()) {
|
|
1977
|
+
return preset.boxShadow !== void 0 ? { boxShadow: preset.boxShadow } : null;
|
|
1978
|
+
}
|
|
1979
|
+
const { boxShadow, ...native } = preset;
|
|
1980
|
+
return Object.keys(native).length > 0 ? native : null;
|
|
1964
1981
|
},
|
|
1965
1982
|
// ── Animations (CSS keyframe animations, web-only) ────────────────────────
|
|
1966
1983
|
// Each variant injects a @keyframes rule once via the __keyframe marker.
|
|
@@ -2839,55 +2856,78 @@ var defaultTheme = {
|
|
|
2839
2856
|
none: "none"
|
|
2840
2857
|
// CSS: flex: none = 0 0 auto; native: mapped to 0
|
|
2841
2858
|
},
|
|
2859
|
+
// Each preset carries BOTH React Native's shadow*/elevation properties
|
|
2860
|
+
// (used on native) and a `boxShadow` string (used on web) — see the
|
|
2861
|
+
// `shadow` resolver in resolvers/effects.ts, which picks one or the other
|
|
2862
|
+
// via getEffectiveIsWeb() and strips the rest. The boxShadow values are
|
|
2863
|
+
// Tailwind's own default shadow scale verbatim (same offsets/blur/spread/
|
|
2864
|
+
// opacity), so shadow-sm/md/lg/xl/2xl look the same as their Tailwind
|
|
2865
|
+
// counterparts on web — the native shadowOffset/shadowRadius/shadowOpacity
|
|
2866
|
+
// numbers were tuned independently for RN's elevation model and don't need
|
|
2867
|
+
// to (and can't exactly) match the CSS values pixel-for-pixel.
|
|
2842
2868
|
shadow: {
|
|
2843
2869
|
sm: {
|
|
2844
2870
|
shadowColor: "#000",
|
|
2845
2871
|
shadowOffset: { width: 0, height: 1 },
|
|
2846
2872
|
shadowOpacity: 0.05,
|
|
2847
2873
|
shadowRadius: 2,
|
|
2848
|
-
elevation: 1
|
|
2874
|
+
elevation: 1,
|
|
2875
|
+
boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
2849
2876
|
},
|
|
2850
2877
|
DEFAULT: {
|
|
2851
2878
|
shadowColor: "#000",
|
|
2852
2879
|
shadowOffset: { width: 0, height: 2 },
|
|
2853
2880
|
shadowOpacity: 0.1,
|
|
2854
2881
|
shadowRadius: 4,
|
|
2855
|
-
elevation: 2
|
|
2882
|
+
elevation: 2,
|
|
2883
|
+
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"
|
|
2856
2884
|
},
|
|
2857
2885
|
md: {
|
|
2858
2886
|
shadowColor: "#000",
|
|
2859
2887
|
shadowOffset: { width: 0, height: 4 },
|
|
2860
2888
|
shadowOpacity: 0.1,
|
|
2861
2889
|
shadowRadius: 8,
|
|
2862
|
-
elevation: 3
|
|
2890
|
+
elevation: 3,
|
|
2891
|
+
boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
|
|
2863
2892
|
},
|
|
2864
2893
|
lg: {
|
|
2865
2894
|
shadowColor: "#000",
|
|
2866
2895
|
shadowOffset: { width: 0, height: 8 },
|
|
2867
2896
|
shadowOpacity: 0.1,
|
|
2868
2897
|
shadowRadius: 15,
|
|
2869
|
-
elevation: 4
|
|
2898
|
+
elevation: 4,
|
|
2899
|
+
boxShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
|
|
2870
2900
|
},
|
|
2871
2901
|
xl: {
|
|
2872
2902
|
shadowColor: "#000",
|
|
2873
2903
|
shadowOffset: { width: 0, height: 16 },
|
|
2874
2904
|
shadowOpacity: 0.1,
|
|
2875
2905
|
shadowRadius: 24,
|
|
2876
|
-
elevation: 6
|
|
2906
|
+
elevation: 6,
|
|
2907
|
+
boxShadow: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
|
|
2877
2908
|
},
|
|
2878
2909
|
"2xl": {
|
|
2879
2910
|
shadowColor: "#000",
|
|
2880
2911
|
shadowOffset: { width: 0, height: 24 },
|
|
2881
2912
|
shadowOpacity: 0.25,
|
|
2882
2913
|
shadowRadius: 48,
|
|
2883
|
-
elevation: 8
|
|
2914
|
+
elevation: 8,
|
|
2915
|
+
boxShadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)"
|
|
2916
|
+
},
|
|
2917
|
+
// Web-only — React Native has no inset-shadow equivalent (shadow*/
|
|
2918
|
+
// elevation only ever draw an outer shadow), so the native side of this
|
|
2919
|
+
// preset is intentionally empty rather than approximating something RN
|
|
2920
|
+
// can't actually do.
|
|
2921
|
+
inner: {
|
|
2922
|
+
boxShadow: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"
|
|
2884
2923
|
},
|
|
2885
2924
|
none: {
|
|
2886
2925
|
shadowColor: "transparent",
|
|
2887
2926
|
shadowOffset: { width: 0, height: 0 },
|
|
2888
2927
|
shadowOpacity: 0,
|
|
2889
2928
|
shadowRadius: 0,
|
|
2890
|
-
elevation: 0
|
|
2929
|
+
elevation: 0,
|
|
2930
|
+
boxShadow: "0 0 #0000"
|
|
2891
2931
|
}
|
|
2892
2932
|
},
|
|
2893
2933
|
screens: {
|
package/dist/index.mjs
CHANGED
package/dist/jsx-dev-runtime.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
Fragment,
|
|
4
4
|
jsx,
|
|
5
5
|
jsxs
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-UVXTWGHQ.mjs";
|
|
7
|
+
import "./chunk-LY753XBX.mjs";
|
|
8
8
|
|
|
9
9
|
// src/jsx-dev-runtime.tsx
|
|
10
10
|
function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
package/dist/jsx-runtime.mjs
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
_invalidateDefaultFontCache,
|
|
5
5
|
jsx,
|
|
6
6
|
jsxs
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-UVXTWGHQ.mjs";
|
|
8
8
|
import {
|
|
9
9
|
registerWebElement
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LY753XBX.mjs";
|
|
11
11
|
export {
|
|
12
12
|
Fragment,
|
|
13
13
|
_invalidateDefaultFontCache,
|
package/dist/vite-plugin.js
CHANGED
|
@@ -57,7 +57,10 @@ function toNativeValue(raw) {
|
|
|
57
57
|
return raw;
|
|
58
58
|
}
|
|
59
59
|
function escapeCSSSelector(cls) {
|
|
60
|
-
|
|
60
|
+
const escaped = cls.replace(/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
61
|
+
if (!/^[0-9]/.test(escaped)) return escaped;
|
|
62
|
+
const hex = escaped.charCodeAt(0).toString(16);
|
|
63
|
+
return `\\${hex} ${escaped.slice(1)}`;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
// src/core/reset.ts
|
|
@@ -589,55 +592,78 @@ var defaultTheme = {
|
|
|
589
592
|
none: "none"
|
|
590
593
|
// CSS: flex: none = 0 0 auto; native: mapped to 0
|
|
591
594
|
},
|
|
595
|
+
// Each preset carries BOTH React Native's shadow*/elevation properties
|
|
596
|
+
// (used on native) and a `boxShadow` string (used on web) — see the
|
|
597
|
+
// `shadow` resolver in resolvers/effects.ts, which picks one or the other
|
|
598
|
+
// via getEffectiveIsWeb() and strips the rest. The boxShadow values are
|
|
599
|
+
// Tailwind's own default shadow scale verbatim (same offsets/blur/spread/
|
|
600
|
+
// opacity), so shadow-sm/md/lg/xl/2xl look the same as their Tailwind
|
|
601
|
+
// counterparts on web — the native shadowOffset/shadowRadius/shadowOpacity
|
|
602
|
+
// numbers were tuned independently for RN's elevation model and don't need
|
|
603
|
+
// to (and can't exactly) match the CSS values pixel-for-pixel.
|
|
592
604
|
shadow: {
|
|
593
605
|
sm: {
|
|
594
606
|
shadowColor: "#000",
|
|
595
607
|
shadowOffset: { width: 0, height: 1 },
|
|
596
608
|
shadowOpacity: 0.05,
|
|
597
609
|
shadowRadius: 2,
|
|
598
|
-
elevation: 1
|
|
610
|
+
elevation: 1,
|
|
611
|
+
boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
599
612
|
},
|
|
600
613
|
DEFAULT: {
|
|
601
614
|
shadowColor: "#000",
|
|
602
615
|
shadowOffset: { width: 0, height: 2 },
|
|
603
616
|
shadowOpacity: 0.1,
|
|
604
617
|
shadowRadius: 4,
|
|
605
|
-
elevation: 2
|
|
618
|
+
elevation: 2,
|
|
619
|
+
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"
|
|
606
620
|
},
|
|
607
621
|
md: {
|
|
608
622
|
shadowColor: "#000",
|
|
609
623
|
shadowOffset: { width: 0, height: 4 },
|
|
610
624
|
shadowOpacity: 0.1,
|
|
611
625
|
shadowRadius: 8,
|
|
612
|
-
elevation: 3
|
|
626
|
+
elevation: 3,
|
|
627
|
+
boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
|
|
613
628
|
},
|
|
614
629
|
lg: {
|
|
615
630
|
shadowColor: "#000",
|
|
616
631
|
shadowOffset: { width: 0, height: 8 },
|
|
617
632
|
shadowOpacity: 0.1,
|
|
618
633
|
shadowRadius: 15,
|
|
619
|
-
elevation: 4
|
|
634
|
+
elevation: 4,
|
|
635
|
+
boxShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
|
|
620
636
|
},
|
|
621
637
|
xl: {
|
|
622
638
|
shadowColor: "#000",
|
|
623
639
|
shadowOffset: { width: 0, height: 16 },
|
|
624
640
|
shadowOpacity: 0.1,
|
|
625
641
|
shadowRadius: 24,
|
|
626
|
-
elevation: 6
|
|
642
|
+
elevation: 6,
|
|
643
|
+
boxShadow: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
|
|
627
644
|
},
|
|
628
645
|
"2xl": {
|
|
629
646
|
shadowColor: "#000",
|
|
630
647
|
shadowOffset: { width: 0, height: 24 },
|
|
631
648
|
shadowOpacity: 0.25,
|
|
632
649
|
shadowRadius: 48,
|
|
633
|
-
elevation: 8
|
|
650
|
+
elevation: 8,
|
|
651
|
+
boxShadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)"
|
|
652
|
+
},
|
|
653
|
+
// Web-only — React Native has no inset-shadow equivalent (shadow*/
|
|
654
|
+
// elevation only ever draw an outer shadow), so the native side of this
|
|
655
|
+
// preset is intentionally empty rather than approximating something RN
|
|
656
|
+
// can't actually do.
|
|
657
|
+
inner: {
|
|
658
|
+
boxShadow: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"
|
|
634
659
|
},
|
|
635
660
|
none: {
|
|
636
661
|
shadowColor: "transparent",
|
|
637
662
|
shadowOffset: { width: 0, height: 0 },
|
|
638
663
|
shadowOpacity: 0,
|
|
639
664
|
shadowRadius: 0,
|
|
640
|
-
elevation: 0
|
|
665
|
+
elevation: 0,
|
|
666
|
+
boxShadow: "0 0 #0000"
|
|
641
667
|
}
|
|
642
668
|
},
|
|
643
669
|
screens: {
|
|
@@ -2298,9 +2324,23 @@ var effectResolvers = {
|
|
|
2298
2324
|
return isNaN(n) ? null : { opacity: n > 1 ? n / 100 : n };
|
|
2299
2325
|
},
|
|
2300
2326
|
// ── Shadow ─────────────────────────────────────────────────────────────────
|
|
2327
|
+
// Presets carry BOTH a web `boxShadow` string and native's shadow*/elevation
|
|
2328
|
+
// properties (theme.ts) — picked apart here rather than left for
|
|
2329
|
+
// styleValueToCSS's RN_ONLY_PROPS filter to sort out, since shadowOffset is
|
|
2330
|
+
// an object (filtered out as "not a flat style value" regardless of
|
|
2331
|
+
// platform) and boxShadow would otherwise leak into native's style prop as
|
|
2332
|
+
// an RN doesn't understand (silently ignored there, but better to not hand
|
|
2333
|
+
// native a property that was never meant for it — same branch-on-platform
|
|
2334
|
+
// pattern as bg-opacity/transition/animate above).
|
|
2301
2335
|
shadow: ({ value }, { shadow }) => {
|
|
2302
2336
|
const key = value === "" ? "DEFAULT" : value;
|
|
2303
|
-
|
|
2337
|
+
const preset = shadow[key];
|
|
2338
|
+
if (!preset) return null;
|
|
2339
|
+
if (getEffectiveIsWeb()) {
|
|
2340
|
+
return preset.boxShadow !== void 0 ? { boxShadow: preset.boxShadow } : null;
|
|
2341
|
+
}
|
|
2342
|
+
const { boxShadow, ...native } = preset;
|
|
2343
|
+
return Object.keys(native).length > 0 ? native : null;
|
|
2304
2344
|
},
|
|
2305
2345
|
// ── Animations (CSS keyframe animations, web-only) ────────────────────────
|
|
2306
2346
|
// Each variant injects a @keyframes rule once via the __keyframe marker.
|
|
@@ -3505,6 +3545,31 @@ function prettifyCSS(css) {
|
|
|
3505
3545
|
if (trailing) out.push(trailing);
|
|
3506
3546
|
return out.join("\n");
|
|
3507
3547
|
}
|
|
3548
|
+
var RESPONSIVE_MEDIA_RE = /^@media \(min-width: (\d+)px\) \{ (.+) \}$/;
|
|
3549
|
+
function mergeResponsiveMediaBlocks(items) {
|
|
3550
|
+
const byWidth = /* @__PURE__ */ new Map();
|
|
3551
|
+
const widthOrder = [];
|
|
3552
|
+
const unwrapped = [];
|
|
3553
|
+
for (const { raw } of items) {
|
|
3554
|
+
for (const line of raw.split("\n")) {
|
|
3555
|
+
if (!line.trim()) continue;
|
|
3556
|
+
const m = RESPONSIVE_MEDIA_RE.exec(line);
|
|
3557
|
+
if (!m) {
|
|
3558
|
+
unwrapped.push(line);
|
|
3559
|
+
continue;
|
|
3560
|
+
}
|
|
3561
|
+
const width = Number(m[1]);
|
|
3562
|
+
if (!byWidth.has(width)) {
|
|
3563
|
+
byWidth.set(width, []);
|
|
3564
|
+
widthOrder.push(width);
|
|
3565
|
+
}
|
|
3566
|
+
byWidth.get(width).push(m[2]);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
widthOrder.sort((a, b) => a - b);
|
|
3570
|
+
const merged = widthOrder.map((w) => `@media (min-width: ${w}px) { ${byWidth.get(w).join(" ")} }`);
|
|
3571
|
+
return [...unwrapped, ...merged];
|
|
3572
|
+
}
|
|
3508
3573
|
function formatKbachCSS(tokenCSS, theme, responsiveRe) {
|
|
3509
3574
|
const allRaw = [...tokenCSS.values()].filter(Boolean).join("\n");
|
|
3510
3575
|
const colorVars = buildColorVarMap(theme, allRaw);
|
|
@@ -3524,7 +3589,7 @@ function formatKbachCSS(tokenCSS, theme, responsiveRe) {
|
|
|
3524
3589
|
if (!groups.has(label)) groups.set(label, []);
|
|
3525
3590
|
const parsedToken = parseClass(token);
|
|
3526
3591
|
const bucketKey = parsedToken && parsedToken.modifiers.length > 0 ? parsedToken.modifiers.join(":") : "base";
|
|
3527
|
-
groups.get(label).push({ order: getModifierOrder(bucketKey),
|
|
3592
|
+
groups.get(label).push({ order: getModifierOrder(bucketKey), raw: applyVars(css) });
|
|
3528
3593
|
}
|
|
3529
3594
|
const out = ["/* Generated by Kbach \u2014 do not edit */"];
|
|
3530
3595
|
if (declarations.size > 0) {
|
|
@@ -3542,7 +3607,8 @@ ${prettifyCSS(globalCSS)}`);
|
|
|
3542
3607
|
const sorted = [...items].sort((a, b) => a.order - b.order);
|
|
3543
3608
|
out.push(`
|
|
3544
3609
|
/* ${label} */`);
|
|
3545
|
-
|
|
3610
|
+
const rendered = label === "Responsive" ? mergeResponsiveMediaBlocks(sorted).map(prettifyCSS) : sorted.map((it) => prettifyCSS(it.raw));
|
|
3611
|
+
out.push(rendered.join("\n\n"));
|
|
3546
3612
|
}
|
|
3547
3613
|
return out.join("\n");
|
|
3548
3614
|
}
|
package/dist/vite-plugin.mjs
CHANGED
|
@@ -22,7 +22,10 @@ function toNativeValue(raw) {
|
|
|
22
22
|
return raw;
|
|
23
23
|
}
|
|
24
24
|
function escapeCSSSelector(cls) {
|
|
25
|
-
|
|
25
|
+
const escaped = cls.replace(/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
26
|
+
if (!/^[0-9]/.test(escaped)) return escaped;
|
|
27
|
+
const hex = escaped.charCodeAt(0).toString(16);
|
|
28
|
+
return `\\${hex} ${escaped.slice(1)}`;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
// src/core/reset.ts
|
|
@@ -554,55 +557,78 @@ var defaultTheme = {
|
|
|
554
557
|
none: "none"
|
|
555
558
|
// CSS: flex: none = 0 0 auto; native: mapped to 0
|
|
556
559
|
},
|
|
560
|
+
// Each preset carries BOTH React Native's shadow*/elevation properties
|
|
561
|
+
// (used on native) and a `boxShadow` string (used on web) — see the
|
|
562
|
+
// `shadow` resolver in resolvers/effects.ts, which picks one or the other
|
|
563
|
+
// via getEffectiveIsWeb() and strips the rest. The boxShadow values are
|
|
564
|
+
// Tailwind's own default shadow scale verbatim (same offsets/blur/spread/
|
|
565
|
+
// opacity), so shadow-sm/md/lg/xl/2xl look the same as their Tailwind
|
|
566
|
+
// counterparts on web — the native shadowOffset/shadowRadius/shadowOpacity
|
|
567
|
+
// numbers were tuned independently for RN's elevation model and don't need
|
|
568
|
+
// to (and can't exactly) match the CSS values pixel-for-pixel.
|
|
557
569
|
shadow: {
|
|
558
570
|
sm: {
|
|
559
571
|
shadowColor: "#000",
|
|
560
572
|
shadowOffset: { width: 0, height: 1 },
|
|
561
573
|
shadowOpacity: 0.05,
|
|
562
574
|
shadowRadius: 2,
|
|
563
|
-
elevation: 1
|
|
575
|
+
elevation: 1,
|
|
576
|
+
boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
564
577
|
},
|
|
565
578
|
DEFAULT: {
|
|
566
579
|
shadowColor: "#000",
|
|
567
580
|
shadowOffset: { width: 0, height: 2 },
|
|
568
581
|
shadowOpacity: 0.1,
|
|
569
582
|
shadowRadius: 4,
|
|
570
|
-
elevation: 2
|
|
583
|
+
elevation: 2,
|
|
584
|
+
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"
|
|
571
585
|
},
|
|
572
586
|
md: {
|
|
573
587
|
shadowColor: "#000",
|
|
574
588
|
shadowOffset: { width: 0, height: 4 },
|
|
575
589
|
shadowOpacity: 0.1,
|
|
576
590
|
shadowRadius: 8,
|
|
577
|
-
elevation: 3
|
|
591
|
+
elevation: 3,
|
|
592
|
+
boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
|
|
578
593
|
},
|
|
579
594
|
lg: {
|
|
580
595
|
shadowColor: "#000",
|
|
581
596
|
shadowOffset: { width: 0, height: 8 },
|
|
582
597
|
shadowOpacity: 0.1,
|
|
583
598
|
shadowRadius: 15,
|
|
584
|
-
elevation: 4
|
|
599
|
+
elevation: 4,
|
|
600
|
+
boxShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
|
|
585
601
|
},
|
|
586
602
|
xl: {
|
|
587
603
|
shadowColor: "#000",
|
|
588
604
|
shadowOffset: { width: 0, height: 16 },
|
|
589
605
|
shadowOpacity: 0.1,
|
|
590
606
|
shadowRadius: 24,
|
|
591
|
-
elevation: 6
|
|
607
|
+
elevation: 6,
|
|
608
|
+
boxShadow: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
|
|
592
609
|
},
|
|
593
610
|
"2xl": {
|
|
594
611
|
shadowColor: "#000",
|
|
595
612
|
shadowOffset: { width: 0, height: 24 },
|
|
596
613
|
shadowOpacity: 0.25,
|
|
597
614
|
shadowRadius: 48,
|
|
598
|
-
elevation: 8
|
|
615
|
+
elevation: 8,
|
|
616
|
+
boxShadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)"
|
|
617
|
+
},
|
|
618
|
+
// Web-only — React Native has no inset-shadow equivalent (shadow*/
|
|
619
|
+
// elevation only ever draw an outer shadow), so the native side of this
|
|
620
|
+
// preset is intentionally empty rather than approximating something RN
|
|
621
|
+
// can't actually do.
|
|
622
|
+
inner: {
|
|
623
|
+
boxShadow: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"
|
|
599
624
|
},
|
|
600
625
|
none: {
|
|
601
626
|
shadowColor: "transparent",
|
|
602
627
|
shadowOffset: { width: 0, height: 0 },
|
|
603
628
|
shadowOpacity: 0,
|
|
604
629
|
shadowRadius: 0,
|
|
605
|
-
elevation: 0
|
|
630
|
+
elevation: 0,
|
|
631
|
+
boxShadow: "0 0 #0000"
|
|
606
632
|
}
|
|
607
633
|
},
|
|
608
634
|
screens: {
|
|
@@ -2263,9 +2289,23 @@ var effectResolvers = {
|
|
|
2263
2289
|
return isNaN(n) ? null : { opacity: n > 1 ? n / 100 : n };
|
|
2264
2290
|
},
|
|
2265
2291
|
// ── Shadow ─────────────────────────────────────────────────────────────────
|
|
2292
|
+
// Presets carry BOTH a web `boxShadow` string and native's shadow*/elevation
|
|
2293
|
+
// properties (theme.ts) — picked apart here rather than left for
|
|
2294
|
+
// styleValueToCSS's RN_ONLY_PROPS filter to sort out, since shadowOffset is
|
|
2295
|
+
// an object (filtered out as "not a flat style value" regardless of
|
|
2296
|
+
// platform) and boxShadow would otherwise leak into native's style prop as
|
|
2297
|
+
// an RN doesn't understand (silently ignored there, but better to not hand
|
|
2298
|
+
// native a property that was never meant for it — same branch-on-platform
|
|
2299
|
+
// pattern as bg-opacity/transition/animate above).
|
|
2266
2300
|
shadow: ({ value }, { shadow }) => {
|
|
2267
2301
|
const key = value === "" ? "DEFAULT" : value;
|
|
2268
|
-
|
|
2302
|
+
const preset = shadow[key];
|
|
2303
|
+
if (!preset) return null;
|
|
2304
|
+
if (getEffectiveIsWeb()) {
|
|
2305
|
+
return preset.boxShadow !== void 0 ? { boxShadow: preset.boxShadow } : null;
|
|
2306
|
+
}
|
|
2307
|
+
const { boxShadow, ...native } = preset;
|
|
2308
|
+
return Object.keys(native).length > 0 ? native : null;
|
|
2269
2309
|
},
|
|
2270
2310
|
// ── Animations (CSS keyframe animations, web-only) ────────────────────────
|
|
2271
2311
|
// Each variant injects a @keyframes rule once via the __keyframe marker.
|
|
@@ -3470,6 +3510,31 @@ function prettifyCSS(css) {
|
|
|
3470
3510
|
if (trailing) out.push(trailing);
|
|
3471
3511
|
return out.join("\n");
|
|
3472
3512
|
}
|
|
3513
|
+
var RESPONSIVE_MEDIA_RE = /^@media \(min-width: (\d+)px\) \{ (.+) \}$/;
|
|
3514
|
+
function mergeResponsiveMediaBlocks(items) {
|
|
3515
|
+
const byWidth = /* @__PURE__ */ new Map();
|
|
3516
|
+
const widthOrder = [];
|
|
3517
|
+
const unwrapped = [];
|
|
3518
|
+
for (const { raw } of items) {
|
|
3519
|
+
for (const line of raw.split("\n")) {
|
|
3520
|
+
if (!line.trim()) continue;
|
|
3521
|
+
const m = RESPONSIVE_MEDIA_RE.exec(line);
|
|
3522
|
+
if (!m) {
|
|
3523
|
+
unwrapped.push(line);
|
|
3524
|
+
continue;
|
|
3525
|
+
}
|
|
3526
|
+
const width = Number(m[1]);
|
|
3527
|
+
if (!byWidth.has(width)) {
|
|
3528
|
+
byWidth.set(width, []);
|
|
3529
|
+
widthOrder.push(width);
|
|
3530
|
+
}
|
|
3531
|
+
byWidth.get(width).push(m[2]);
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
widthOrder.sort((a, b) => a - b);
|
|
3535
|
+
const merged = widthOrder.map((w) => `@media (min-width: ${w}px) { ${byWidth.get(w).join(" ")} }`);
|
|
3536
|
+
return [...unwrapped, ...merged];
|
|
3537
|
+
}
|
|
3473
3538
|
function formatKbachCSS(tokenCSS, theme, responsiveRe) {
|
|
3474
3539
|
const allRaw = [...tokenCSS.values()].filter(Boolean).join("\n");
|
|
3475
3540
|
const colorVars = buildColorVarMap(theme, allRaw);
|
|
@@ -3489,7 +3554,7 @@ function formatKbachCSS(tokenCSS, theme, responsiveRe) {
|
|
|
3489
3554
|
if (!groups.has(label)) groups.set(label, []);
|
|
3490
3555
|
const parsedToken = parseClass(token);
|
|
3491
3556
|
const bucketKey = parsedToken && parsedToken.modifiers.length > 0 ? parsedToken.modifiers.join(":") : "base";
|
|
3492
|
-
groups.get(label).push({ order: getModifierOrder(bucketKey),
|
|
3557
|
+
groups.get(label).push({ order: getModifierOrder(bucketKey), raw: applyVars(css) });
|
|
3493
3558
|
}
|
|
3494
3559
|
const out = ["/* Generated by Kbach \u2014 do not edit */"];
|
|
3495
3560
|
if (declarations.size > 0) {
|
|
@@ -3507,7 +3572,8 @@ ${prettifyCSS(globalCSS)}`);
|
|
|
3507
3572
|
const sorted = [...items].sort((a, b) => a.order - b.order);
|
|
3508
3573
|
out.push(`
|
|
3509
3574
|
/* ${label} */`);
|
|
3510
|
-
|
|
3575
|
+
const rendered = label === "Responsive" ? mergeResponsiveMediaBlocks(sorted).map(prettifyCSS) : sorted.map((it) => prettifyCSS(it.raw));
|
|
3576
|
+
out.push(rendered.join("\n\n"));
|
|
3511
3577
|
}
|
|
3512
3578
|
return out.join("\n");
|
|
3513
3579
|
}
|
package/kbach-ui.md
CHANGED
|
@@ -586,8 +586,9 @@ rounded-t/r/b/l rounded-tl/tr/bl/br
|
|
|
586
586
|
|
|
587
587
|
### Shadow
|
|
588
588
|
```
|
|
589
|
-
shadow-sm / shadow / shadow-md / shadow-lg / shadow-xl / shadow-2xl / shadow-none
|
|
589
|
+
shadow-sm / shadow / shadow-md / shadow-lg / shadow-xl / shadow-2xl / shadow-inner / shadow-none
|
|
590
590
|
```
|
|
591
|
+
Web: real `box-shadow` (Tailwind's own default values). Native: RN's shadowColor/shadowOffset/shadowOpacity/shadowRadius/elevation, tuned independently for RN's elevation model — not derived from the web value, so they don't need to match pixel-for-pixel. `shadow-inner` is web-only (RN has no inset-shadow equivalent). Customize or add sizes via `theme.extend.shadow` — see [Theme Configuration](#theme-configuration) below; each preset key merges independently, so overriding one size's `boxShadow` doesn't touch its native properties or any other size.
|
|
591
592
|
|
|
592
593
|
### Opacity
|
|
593
594
|
```
|
|
@@ -740,6 +741,16 @@ module.exports = {
|
|
|
740
741
|
fontFamily: {
|
|
741
742
|
sans: 'Inter, sans-serif',
|
|
742
743
|
},
|
|
744
|
+
shadow: {
|
|
745
|
+
// Deep-merged into the existing preset, not replaced — lg keeps its
|
|
746
|
+
// native shadowColor/shadowOffset/shadowOpacity/shadowRadius/
|
|
747
|
+
// elevation, only boxShadow (the web value) changes here.
|
|
748
|
+
lg: { boxShadow: '0 10px 40px -10px rgba(99, 102, 241, 0.4)' },
|
|
749
|
+
// A brand-new key adds a new shadow-3xl utility alongside the
|
|
750
|
+
// defaults (sm/DEFAULT/md/lg/xl/2xl/inner/none) — web-only here,
|
|
751
|
+
// since it has no native shadow*/elevation properties.
|
|
752
|
+
'3xl': { boxShadow: '0 35px 60px -15px rgba(0, 0, 0, 0.3)' },
|
|
753
|
+
},
|
|
743
754
|
},
|
|
744
755
|
},
|
|
745
756
|
|