@kbach/react 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-NWW57Q5Q.mjs → chunk-4A24NQ5X.mjs} +1 -1
- package/dist/{chunk-GRZ6MVIL.mjs → chunk-ZZWJK33J.mjs} +47 -19
- package/dist/index.js +47 -19
- package/dist/index.mjs +1 -1
- package/dist/jsx-dev-runtime.js +47 -19
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.js +47 -19
- package/dist/jsx-runtime.mjs +2 -2
- package/dist/vite-plugin.js +47 -19
- package/dist/vite-plugin.mjs +47 -19
- package/kbach-react.md +10 -4
- package/package.json +1 -1
|
@@ -361,7 +361,10 @@ var defaultTheme = {
|
|
|
361
361
|
"2/3": "66.666667%",
|
|
362
362
|
"1/4": "25%",
|
|
363
363
|
"3/4": "75%",
|
|
364
|
-
screen
|
|
364
|
+
// Dynamic viewport unit — see the comment on the 'screen' standalone utilities
|
|
365
|
+
// in utilities.ts for why dvh beats vh on mobile. Used by h-screen (w-screen
|
|
366
|
+
// has its own standalone entry so it never reaches this spacing lookup).
|
|
367
|
+
screen: "100dvh",
|
|
365
368
|
min: "min-content",
|
|
366
369
|
max: "max-content",
|
|
367
370
|
fit: "fit-content"
|
|
@@ -810,15 +813,19 @@ function buildStandalone() {
|
|
|
810
813
|
// Display
|
|
811
814
|
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
812
815
|
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
813
|
-
// `grid`, `
|
|
816
|
+
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
817
|
+
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
818
|
+
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
819
|
+
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
820
|
+
// native either (null → no style applied → still display:'none').
|
|
814
821
|
flex: { display: "flex" },
|
|
815
822
|
block: web ? { display: "block" } : null,
|
|
816
|
-
"inline-block":
|
|
817
|
-
inline: web ?
|
|
823
|
+
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
824
|
+
inline: { display: web ? "inline" : "flex" },
|
|
818
825
|
grid: web ? { display: "grid" } : null,
|
|
819
826
|
grd: web ? { display: "grid" } : null,
|
|
820
827
|
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
821
|
-
"inline-grid":
|
|
828
|
+
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
822
829
|
hidden: { display: "none" },
|
|
823
830
|
contents: web ? { display: "contents" } : null,
|
|
824
831
|
"flow-root": web ? { display: "flow-root" } : null,
|
|
@@ -1077,12 +1084,17 @@ function buildStandalone() {
|
|
|
1077
1084
|
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1078
1085
|
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1079
1086
|
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1080
|
-
// Screen sizing
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1087
|
+
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1088
|
+
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1089
|
+
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1090
|
+
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1091
|
+
// is unchanged since there's no dynamic chrome to account for.
|
|
1092
|
+
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1093
|
+
"w-screen": web ? { width: "100dvw" } : null,
|
|
1094
|
+
"min-h-screen": { minHeight: "100dvh" },
|
|
1095
|
+
"max-h-screen": { maxHeight: "100dvh" },
|
|
1096
|
+
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1097
|
+
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1086
1098
|
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1087
1099
|
"max-w-none": { maxWidth: "none" },
|
|
1088
1100
|
"max-w-xs": { maxWidth: 320 },
|
|
@@ -2208,34 +2220,50 @@ var RESOLVERS = {
|
|
|
2208
2220
|
const ms = isArbitrary ? value : `${value}ms`;
|
|
2209
2221
|
return { transitionDelay: ms };
|
|
2210
2222
|
},
|
|
2211
|
-
// ── Ring
|
|
2223
|
+
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
2224
|
+
// Web: box-shadow outline ring (doesn't affect layout).
|
|
2225
|
+
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
2226
|
+
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
2227
|
+
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
2228
|
+
// and it shares its properties with the `border` utility — combining
|
|
2229
|
+
// `border-*` and `ring-*` on the same native element means whichever class
|
|
2230
|
+
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
2212
2231
|
ring: ({ value, isArbitrary }, { colors }) => {
|
|
2213
|
-
|
|
2232
|
+
const onWeb = getEffectiveIsWeb();
|
|
2214
2233
|
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2215
2234
|
const DEFAULT_WIDTH = 3;
|
|
2235
|
+
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
2216
2236
|
if (!value) {
|
|
2217
|
-
return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2237
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2218
2238
|
}
|
|
2219
2239
|
if (value === "inset") {
|
|
2220
|
-
return { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2240
|
+
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2221
2241
|
}
|
|
2222
2242
|
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2223
2243
|
if (!isArbitrary && value in widthTokens) {
|
|
2224
2244
|
const w = widthTokens[value];
|
|
2225
|
-
return { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` };
|
|
2245
|
+
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
2226
2246
|
}
|
|
2227
2247
|
if (isArbitrary) {
|
|
2228
2248
|
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
2229
2249
|
if (numMatch) {
|
|
2230
2250
|
const unit = numMatch[2] ?? "px";
|
|
2231
|
-
return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2251
|
+
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2252
|
+
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2232
2253
|
}
|
|
2233
|
-
return { boxShadow: value.replace(/_/g, " ") };
|
|
2254
|
+
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2234
2255
|
}
|
|
2235
2256
|
const color = resolveColor(value, colors, false);
|
|
2236
|
-
if (color)
|
|
2257
|
+
if (color) {
|
|
2258
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
2259
|
+
}
|
|
2237
2260
|
return null;
|
|
2238
2261
|
},
|
|
2262
|
+
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2263
|
+
// create a gap between the element and the ring. There's no native
|
|
2264
|
+
// equivalent to approximate that with (a border can't create a gap outside
|
|
2265
|
+
// its own element without an extra wrapper view), so this stays a no-op
|
|
2266
|
+
// on native rather than rendering a misleading half-translation.
|
|
2239
2267
|
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2240
2268
|
if (!getEffectiveIsWeb()) return null;
|
|
2241
2269
|
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
package/dist/index.js
CHANGED
|
@@ -445,7 +445,10 @@ var defaultTheme = {
|
|
|
445
445
|
"2/3": "66.666667%",
|
|
446
446
|
"1/4": "25%",
|
|
447
447
|
"3/4": "75%",
|
|
448
|
-
screen
|
|
448
|
+
// Dynamic viewport unit — see the comment on the 'screen' standalone utilities
|
|
449
|
+
// in utilities.ts for why dvh beats vh on mobile. Used by h-screen (w-screen
|
|
450
|
+
// has its own standalone entry so it never reaches this spacing lookup).
|
|
451
|
+
screen: "100dvh",
|
|
449
452
|
min: "min-content",
|
|
450
453
|
max: "max-content",
|
|
451
454
|
fit: "fit-content"
|
|
@@ -929,15 +932,19 @@ function buildStandalone() {
|
|
|
929
932
|
// Display
|
|
930
933
|
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
931
934
|
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
932
|
-
// `grid`, `
|
|
935
|
+
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
936
|
+
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
937
|
+
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
938
|
+
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
939
|
+
// native either (null → no style applied → still display:'none').
|
|
933
940
|
flex: { display: "flex" },
|
|
934
941
|
block: web ? { display: "block" } : null,
|
|
935
|
-
"inline-block":
|
|
936
|
-
inline: web ?
|
|
942
|
+
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
943
|
+
inline: { display: web ? "inline" : "flex" },
|
|
937
944
|
grid: web ? { display: "grid" } : null,
|
|
938
945
|
grd: web ? { display: "grid" } : null,
|
|
939
946
|
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
940
|
-
"inline-grid":
|
|
947
|
+
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
941
948
|
hidden: { display: "none" },
|
|
942
949
|
contents: web ? { display: "contents" } : null,
|
|
943
950
|
"flow-root": web ? { display: "flow-root" } : null,
|
|
@@ -1196,12 +1203,17 @@ function buildStandalone() {
|
|
|
1196
1203
|
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1197
1204
|
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1198
1205
|
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1199
|
-
// Screen sizing
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1206
|
+
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1207
|
+
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1208
|
+
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1209
|
+
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1210
|
+
// is unchanged since there's no dynamic chrome to account for.
|
|
1211
|
+
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1212
|
+
"w-screen": web ? { width: "100dvw" } : null,
|
|
1213
|
+
"min-h-screen": { minHeight: "100dvh" },
|
|
1214
|
+
"max-h-screen": { maxHeight: "100dvh" },
|
|
1215
|
+
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1216
|
+
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1205
1217
|
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1206
1218
|
"max-w-none": { maxWidth: "none" },
|
|
1207
1219
|
"max-w-xs": { maxWidth: 320 },
|
|
@@ -2327,34 +2339,50 @@ var RESOLVERS = {
|
|
|
2327
2339
|
const ms = isArbitrary ? value : `${value}ms`;
|
|
2328
2340
|
return { transitionDelay: ms };
|
|
2329
2341
|
},
|
|
2330
|
-
// ── Ring
|
|
2342
|
+
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
2343
|
+
// Web: box-shadow outline ring (doesn't affect layout).
|
|
2344
|
+
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
2345
|
+
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
2346
|
+
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
2347
|
+
// and it shares its properties with the `border` utility — combining
|
|
2348
|
+
// `border-*` and `ring-*` on the same native element means whichever class
|
|
2349
|
+
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
2331
2350
|
ring: ({ value, isArbitrary }, { colors }) => {
|
|
2332
|
-
|
|
2351
|
+
const onWeb = getEffectiveIsWeb();
|
|
2333
2352
|
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2334
2353
|
const DEFAULT_WIDTH = 3;
|
|
2354
|
+
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
2335
2355
|
if (!value) {
|
|
2336
|
-
return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2356
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2337
2357
|
}
|
|
2338
2358
|
if (value === "inset") {
|
|
2339
|
-
return { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2359
|
+
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2340
2360
|
}
|
|
2341
2361
|
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2342
2362
|
if (!isArbitrary && value in widthTokens) {
|
|
2343
2363
|
const w = widthTokens[value];
|
|
2344
|
-
return { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` };
|
|
2364
|
+
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
2345
2365
|
}
|
|
2346
2366
|
if (isArbitrary) {
|
|
2347
2367
|
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
2348
2368
|
if (numMatch) {
|
|
2349
2369
|
const unit = numMatch[2] ?? "px";
|
|
2350
|
-
return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2370
|
+
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2371
|
+
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2351
2372
|
}
|
|
2352
|
-
return { boxShadow: value.replace(/_/g, " ") };
|
|
2373
|
+
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2353
2374
|
}
|
|
2354
2375
|
const color = resolveColor(value, colors, false);
|
|
2355
|
-
if (color)
|
|
2376
|
+
if (color) {
|
|
2377
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
2378
|
+
}
|
|
2356
2379
|
return null;
|
|
2357
2380
|
},
|
|
2381
|
+
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2382
|
+
// create a gap between the element and the ring. There's no native
|
|
2383
|
+
// equivalent to approximate that with (a border can't create a gap outside
|
|
2384
|
+
// its own element without an extra wrapper view), so this stays a no-op
|
|
2385
|
+
// on native rather than rendering a misleading half-translation.
|
|
2358
2386
|
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2359
2387
|
if (!getEffectiveIsWeb()) return null;
|
|
2360
2388
|
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
package/dist/index.mjs
CHANGED
package/dist/jsx-dev-runtime.js
CHANGED
|
@@ -401,7 +401,10 @@ var defaultTheme = {
|
|
|
401
401
|
"2/3": "66.666667%",
|
|
402
402
|
"1/4": "25%",
|
|
403
403
|
"3/4": "75%",
|
|
404
|
-
screen
|
|
404
|
+
// Dynamic viewport unit — see the comment on the 'screen' standalone utilities
|
|
405
|
+
// in utilities.ts for why dvh beats vh on mobile. Used by h-screen (w-screen
|
|
406
|
+
// has its own standalone entry so it never reaches this spacing lookup).
|
|
407
|
+
screen: "100dvh",
|
|
405
408
|
min: "min-content",
|
|
406
409
|
max: "max-content",
|
|
407
410
|
fit: "fit-content"
|
|
@@ -888,15 +891,19 @@ function buildStandalone() {
|
|
|
888
891
|
// Display
|
|
889
892
|
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
890
893
|
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
891
|
-
// `grid`, `
|
|
894
|
+
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
895
|
+
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
896
|
+
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
897
|
+
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
898
|
+
// native either (null → no style applied → still display:'none').
|
|
892
899
|
flex: { display: "flex" },
|
|
893
900
|
block: web ? { display: "block" } : null,
|
|
894
|
-
"inline-block":
|
|
895
|
-
inline: web ?
|
|
901
|
+
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
902
|
+
inline: { display: web ? "inline" : "flex" },
|
|
896
903
|
grid: web ? { display: "grid" } : null,
|
|
897
904
|
grd: web ? { display: "grid" } : null,
|
|
898
905
|
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
899
|
-
"inline-grid":
|
|
906
|
+
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
900
907
|
hidden: { display: "none" },
|
|
901
908
|
contents: web ? { display: "contents" } : null,
|
|
902
909
|
"flow-root": web ? { display: "flow-root" } : null,
|
|
@@ -1155,12 +1162,17 @@ function buildStandalone() {
|
|
|
1155
1162
|
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1156
1163
|
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1157
1164
|
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1158
|
-
// Screen sizing
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1165
|
+
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1166
|
+
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1167
|
+
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1168
|
+
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1169
|
+
// is unchanged since there's no dynamic chrome to account for.
|
|
1170
|
+
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1171
|
+
"w-screen": web ? { width: "100dvw" } : null,
|
|
1172
|
+
"min-h-screen": { minHeight: "100dvh" },
|
|
1173
|
+
"max-h-screen": { maxHeight: "100dvh" },
|
|
1174
|
+
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1175
|
+
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1164
1176
|
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1165
1177
|
"max-w-none": { maxWidth: "none" },
|
|
1166
1178
|
"max-w-xs": { maxWidth: 320 },
|
|
@@ -2286,34 +2298,50 @@ var RESOLVERS = {
|
|
|
2286
2298
|
const ms = isArbitrary ? value : `${value}ms`;
|
|
2287
2299
|
return { transitionDelay: ms };
|
|
2288
2300
|
},
|
|
2289
|
-
// ── Ring
|
|
2301
|
+
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
2302
|
+
// Web: box-shadow outline ring (doesn't affect layout).
|
|
2303
|
+
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
2304
|
+
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
2305
|
+
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
2306
|
+
// and it shares its properties with the `border` utility — combining
|
|
2307
|
+
// `border-*` and `ring-*` on the same native element means whichever class
|
|
2308
|
+
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
2290
2309
|
ring: ({ value, isArbitrary }, { colors }) => {
|
|
2291
|
-
|
|
2310
|
+
const onWeb = getEffectiveIsWeb();
|
|
2292
2311
|
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2293
2312
|
const DEFAULT_WIDTH = 3;
|
|
2313
|
+
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
2294
2314
|
if (!value) {
|
|
2295
|
-
return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2315
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2296
2316
|
}
|
|
2297
2317
|
if (value === "inset") {
|
|
2298
|
-
return { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2318
|
+
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2299
2319
|
}
|
|
2300
2320
|
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2301
2321
|
if (!isArbitrary && value in widthTokens) {
|
|
2302
2322
|
const w = widthTokens[value];
|
|
2303
|
-
return { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` };
|
|
2323
|
+
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
2304
2324
|
}
|
|
2305
2325
|
if (isArbitrary) {
|
|
2306
2326
|
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
2307
2327
|
if (numMatch) {
|
|
2308
2328
|
const unit = numMatch[2] ?? "px";
|
|
2309
|
-
return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2329
|
+
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2330
|
+
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2310
2331
|
}
|
|
2311
|
-
return { boxShadow: value.replace(/_/g, " ") };
|
|
2332
|
+
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2312
2333
|
}
|
|
2313
2334
|
const color = resolveColor(value, colors, false);
|
|
2314
|
-
if (color)
|
|
2335
|
+
if (color) {
|
|
2336
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
2337
|
+
}
|
|
2315
2338
|
return null;
|
|
2316
2339
|
},
|
|
2340
|
+
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2341
|
+
// create a gap between the element and the ring. There's no native
|
|
2342
|
+
// equivalent to approximate that with (a border can't create a gap outside
|
|
2343
|
+
// its own element without an extra wrapper view), so this stays a no-op
|
|
2344
|
+
// on native rather than rendering a misleading half-translation.
|
|
2317
2345
|
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2318
2346
|
if (!getEffectiveIsWeb()) return null;
|
|
2319
2347
|
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
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-4A24NQ5X.mjs";
|
|
7
|
+
import "./chunk-ZZWJK33J.mjs";
|
|
8
8
|
|
|
9
9
|
// src/jsx-dev-runtime.tsx
|
|
10
10
|
function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
package/dist/jsx-runtime.js
CHANGED
|
@@ -402,7 +402,10 @@ var defaultTheme = {
|
|
|
402
402
|
"2/3": "66.666667%",
|
|
403
403
|
"1/4": "25%",
|
|
404
404
|
"3/4": "75%",
|
|
405
|
-
screen
|
|
405
|
+
// Dynamic viewport unit — see the comment on the 'screen' standalone utilities
|
|
406
|
+
// in utilities.ts for why dvh beats vh on mobile. Used by h-screen (w-screen
|
|
407
|
+
// has its own standalone entry so it never reaches this spacing lookup).
|
|
408
|
+
screen: "100dvh",
|
|
406
409
|
min: "min-content",
|
|
407
410
|
max: "max-content",
|
|
408
411
|
fit: "fit-content"
|
|
@@ -889,15 +892,19 @@ function buildStandalone() {
|
|
|
889
892
|
// Display
|
|
890
893
|
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
891
894
|
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
892
|
-
// `grid`, `
|
|
895
|
+
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
896
|
+
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
897
|
+
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
898
|
+
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
899
|
+
// native either (null → no style applied → still display:'none').
|
|
893
900
|
flex: { display: "flex" },
|
|
894
901
|
block: web ? { display: "block" } : null,
|
|
895
|
-
"inline-block":
|
|
896
|
-
inline: web ?
|
|
902
|
+
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
903
|
+
inline: { display: web ? "inline" : "flex" },
|
|
897
904
|
grid: web ? { display: "grid" } : null,
|
|
898
905
|
grd: web ? { display: "grid" } : null,
|
|
899
906
|
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
900
|
-
"inline-grid":
|
|
907
|
+
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
901
908
|
hidden: { display: "none" },
|
|
902
909
|
contents: web ? { display: "contents" } : null,
|
|
903
910
|
"flow-root": web ? { display: "flow-root" } : null,
|
|
@@ -1156,12 +1163,17 @@ function buildStandalone() {
|
|
|
1156
1163
|
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1157
1164
|
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1158
1165
|
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1159
|
-
// Screen sizing
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1166
|
+
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1167
|
+
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1168
|
+
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1169
|
+
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1170
|
+
// is unchanged since there's no dynamic chrome to account for.
|
|
1171
|
+
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1172
|
+
"w-screen": web ? { width: "100dvw" } : null,
|
|
1173
|
+
"min-h-screen": { minHeight: "100dvh" },
|
|
1174
|
+
"max-h-screen": { maxHeight: "100dvh" },
|
|
1175
|
+
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1176
|
+
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1165
1177
|
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1166
1178
|
"max-w-none": { maxWidth: "none" },
|
|
1167
1179
|
"max-w-xs": { maxWidth: 320 },
|
|
@@ -2287,34 +2299,50 @@ var RESOLVERS = {
|
|
|
2287
2299
|
const ms = isArbitrary ? value : `${value}ms`;
|
|
2288
2300
|
return { transitionDelay: ms };
|
|
2289
2301
|
},
|
|
2290
|
-
// ── Ring
|
|
2302
|
+
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
2303
|
+
// Web: box-shadow outline ring (doesn't affect layout).
|
|
2304
|
+
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
2305
|
+
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
2306
|
+
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
2307
|
+
// and it shares its properties with the `border` utility — combining
|
|
2308
|
+
// `border-*` and `ring-*` on the same native element means whichever class
|
|
2309
|
+
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
2291
2310
|
ring: ({ value, isArbitrary }, { colors }) => {
|
|
2292
|
-
|
|
2311
|
+
const onWeb = getEffectiveIsWeb();
|
|
2293
2312
|
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2294
2313
|
const DEFAULT_WIDTH = 3;
|
|
2314
|
+
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
2295
2315
|
if (!value) {
|
|
2296
|
-
return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2316
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2297
2317
|
}
|
|
2298
2318
|
if (value === "inset") {
|
|
2299
|
-
return { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2319
|
+
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2300
2320
|
}
|
|
2301
2321
|
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2302
2322
|
if (!isArbitrary && value in widthTokens) {
|
|
2303
2323
|
const w = widthTokens[value];
|
|
2304
|
-
return { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` };
|
|
2324
|
+
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
2305
2325
|
}
|
|
2306
2326
|
if (isArbitrary) {
|
|
2307
2327
|
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
2308
2328
|
if (numMatch) {
|
|
2309
2329
|
const unit = numMatch[2] ?? "px";
|
|
2310
|
-
return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2330
|
+
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2331
|
+
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2311
2332
|
}
|
|
2312
|
-
return { boxShadow: value.replace(/_/g, " ") };
|
|
2333
|
+
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2313
2334
|
}
|
|
2314
2335
|
const color = resolveColor(value, colors, false);
|
|
2315
|
-
if (color)
|
|
2336
|
+
if (color) {
|
|
2337
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
2338
|
+
}
|
|
2316
2339
|
return null;
|
|
2317
2340
|
},
|
|
2341
|
+
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2342
|
+
// create a gap between the element and the ring. There's no native
|
|
2343
|
+
// equivalent to approximate that with (a border can't create a gap outside
|
|
2344
|
+
// its own element without an extra wrapper view), so this stays a no-op
|
|
2345
|
+
// on native rather than rendering a misleading half-translation.
|
|
2318
2346
|
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2319
2347
|
if (!getEffectiveIsWeb()) return null;
|
|
2320
2348
|
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
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-4A24NQ5X.mjs";
|
|
8
8
|
import {
|
|
9
9
|
registerWebElement
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZZWJK33J.mjs";
|
|
11
11
|
export {
|
|
12
12
|
Fragment,
|
|
13
13
|
_invalidateDefaultFontCache,
|
package/dist/vite-plugin.js
CHANGED
|
@@ -437,7 +437,10 @@ var defaultTheme = {
|
|
|
437
437
|
"2/3": "66.666667%",
|
|
438
438
|
"1/4": "25%",
|
|
439
439
|
"3/4": "75%",
|
|
440
|
-
screen
|
|
440
|
+
// Dynamic viewport unit — see the comment on the 'screen' standalone utilities
|
|
441
|
+
// in utilities.ts for why dvh beats vh on mobile. Used by h-screen (w-screen
|
|
442
|
+
// has its own standalone entry so it never reaches this spacing lookup).
|
|
443
|
+
screen: "100dvh",
|
|
441
444
|
min: "min-content",
|
|
442
445
|
max: "max-content",
|
|
443
446
|
fit: "fit-content"
|
|
@@ -748,15 +751,19 @@ function buildStandalone() {
|
|
|
748
751
|
// Display
|
|
749
752
|
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
750
753
|
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
751
|
-
// `grid`, `
|
|
754
|
+
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
755
|
+
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
756
|
+
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
757
|
+
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
758
|
+
// native either (null → no style applied → still display:'none').
|
|
752
759
|
flex: { display: "flex" },
|
|
753
760
|
block: web ? { display: "block" } : null,
|
|
754
|
-
"inline-block":
|
|
755
|
-
inline: web ?
|
|
761
|
+
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
762
|
+
inline: { display: web ? "inline" : "flex" },
|
|
756
763
|
grid: web ? { display: "grid" } : null,
|
|
757
764
|
grd: web ? { display: "grid" } : null,
|
|
758
765
|
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
759
|
-
"inline-grid":
|
|
766
|
+
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
760
767
|
hidden: { display: "none" },
|
|
761
768
|
contents: web ? { display: "contents" } : null,
|
|
762
769
|
"flow-root": web ? { display: "flow-root" } : null,
|
|
@@ -1015,12 +1022,17 @@ function buildStandalone() {
|
|
|
1015
1022
|
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1016
1023
|
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1017
1024
|
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1018
|
-
// Screen sizing
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1025
|
+
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1026
|
+
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1027
|
+
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1028
|
+
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1029
|
+
// is unchanged since there's no dynamic chrome to account for.
|
|
1030
|
+
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1031
|
+
"w-screen": web ? { width: "100dvw" } : null,
|
|
1032
|
+
"min-h-screen": { minHeight: "100dvh" },
|
|
1033
|
+
"max-h-screen": { maxHeight: "100dvh" },
|
|
1034
|
+
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1035
|
+
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1024
1036
|
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1025
1037
|
"max-w-none": { maxWidth: "none" },
|
|
1026
1038
|
"max-w-xs": { maxWidth: 320 },
|
|
@@ -2146,34 +2158,50 @@ var RESOLVERS = {
|
|
|
2146
2158
|
const ms = isArbitrary ? value : `${value}ms`;
|
|
2147
2159
|
return { transitionDelay: ms };
|
|
2148
2160
|
},
|
|
2149
|
-
// ── Ring
|
|
2161
|
+
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
2162
|
+
// Web: box-shadow outline ring (doesn't affect layout).
|
|
2163
|
+
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
2164
|
+
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
2165
|
+
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
2166
|
+
// and it shares its properties with the `border` utility — combining
|
|
2167
|
+
// `border-*` and `ring-*` on the same native element means whichever class
|
|
2168
|
+
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
2150
2169
|
ring: ({ value, isArbitrary }, { colors }) => {
|
|
2151
|
-
|
|
2170
|
+
const onWeb = getEffectiveIsWeb();
|
|
2152
2171
|
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2153
2172
|
const DEFAULT_WIDTH = 3;
|
|
2173
|
+
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
2154
2174
|
if (!value) {
|
|
2155
|
-
return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2175
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2156
2176
|
}
|
|
2157
2177
|
if (value === "inset") {
|
|
2158
|
-
return { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2178
|
+
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2159
2179
|
}
|
|
2160
2180
|
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2161
2181
|
if (!isArbitrary && value in widthTokens) {
|
|
2162
2182
|
const w = widthTokens[value];
|
|
2163
|
-
return { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` };
|
|
2183
|
+
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
2164
2184
|
}
|
|
2165
2185
|
if (isArbitrary) {
|
|
2166
2186
|
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
2167
2187
|
if (numMatch) {
|
|
2168
2188
|
const unit = numMatch[2] ?? "px";
|
|
2169
|
-
return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2189
|
+
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2190
|
+
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2170
2191
|
}
|
|
2171
|
-
return { boxShadow: value.replace(/_/g, " ") };
|
|
2192
|
+
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2172
2193
|
}
|
|
2173
2194
|
const color = resolveColor(value, colors, false);
|
|
2174
|
-
if (color)
|
|
2195
|
+
if (color) {
|
|
2196
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
2197
|
+
}
|
|
2175
2198
|
return null;
|
|
2176
2199
|
},
|
|
2200
|
+
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2201
|
+
// create a gap between the element and the ring. There's no native
|
|
2202
|
+
// equivalent to approximate that with (a border can't create a gap outside
|
|
2203
|
+
// its own element without an extra wrapper view), so this stays a no-op
|
|
2204
|
+
// on native rather than rendering a misleading half-translation.
|
|
2177
2205
|
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2178
2206
|
if (!getEffectiveIsWeb()) return null;
|
|
2179
2207
|
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
package/dist/vite-plugin.mjs
CHANGED
|
@@ -403,7 +403,10 @@ var defaultTheme = {
|
|
|
403
403
|
"2/3": "66.666667%",
|
|
404
404
|
"1/4": "25%",
|
|
405
405
|
"3/4": "75%",
|
|
406
|
-
screen
|
|
406
|
+
// Dynamic viewport unit — see the comment on the 'screen' standalone utilities
|
|
407
|
+
// in utilities.ts for why dvh beats vh on mobile. Used by h-screen (w-screen
|
|
408
|
+
// has its own standalone entry so it never reaches this spacing lookup).
|
|
409
|
+
screen: "100dvh",
|
|
407
410
|
min: "min-content",
|
|
408
411
|
max: "max-content",
|
|
409
412
|
fit: "fit-content"
|
|
@@ -714,15 +717,19 @@ function buildStandalone() {
|
|
|
714
717
|
// Display
|
|
715
718
|
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
716
719
|
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
717
|
-
// `grid`, `
|
|
720
|
+
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
721
|
+
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
722
|
+
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
723
|
+
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
724
|
+
// native either (null → no style applied → still display:'none').
|
|
718
725
|
flex: { display: "flex" },
|
|
719
726
|
block: web ? { display: "block" } : null,
|
|
720
|
-
"inline-block":
|
|
721
|
-
inline: web ?
|
|
727
|
+
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
728
|
+
inline: { display: web ? "inline" : "flex" },
|
|
722
729
|
grid: web ? { display: "grid" } : null,
|
|
723
730
|
grd: web ? { display: "grid" } : null,
|
|
724
731
|
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
725
|
-
"inline-grid":
|
|
732
|
+
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
726
733
|
hidden: { display: "none" },
|
|
727
734
|
contents: web ? { display: "contents" } : null,
|
|
728
735
|
"flow-root": web ? { display: "flow-root" } : null,
|
|
@@ -981,12 +988,17 @@ function buildStandalone() {
|
|
|
981
988
|
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
982
989
|
"text-balance": web ? { textWrap: "balance" } : null,
|
|
983
990
|
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
984
|
-
// Screen sizing
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
991
|
+
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
992
|
+
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
993
|
+
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
994
|
+
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
995
|
+
// is unchanged since there's no dynamic chrome to account for.
|
|
996
|
+
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
997
|
+
"w-screen": web ? { width: "100dvw" } : null,
|
|
998
|
+
"min-h-screen": { minHeight: "100dvh" },
|
|
999
|
+
"max-h-screen": { maxHeight: "100dvh" },
|
|
1000
|
+
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1001
|
+
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
990
1002
|
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
991
1003
|
"max-w-none": { maxWidth: "none" },
|
|
992
1004
|
"max-w-xs": { maxWidth: 320 },
|
|
@@ -2112,34 +2124,50 @@ var RESOLVERS = {
|
|
|
2112
2124
|
const ms = isArbitrary ? value : `${value}ms`;
|
|
2113
2125
|
return { transitionDelay: ms };
|
|
2114
2126
|
},
|
|
2115
|
-
// ── Ring
|
|
2127
|
+
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
2128
|
+
// Web: box-shadow outline ring (doesn't affect layout).
|
|
2129
|
+
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
2130
|
+
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
2131
|
+
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
2132
|
+
// and it shares its properties with the `border` utility — combining
|
|
2133
|
+
// `border-*` and `ring-*` on the same native element means whichever class
|
|
2134
|
+
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
2116
2135
|
ring: ({ value, isArbitrary }, { colors }) => {
|
|
2117
|
-
|
|
2136
|
+
const onWeb = getEffectiveIsWeb();
|
|
2118
2137
|
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2119
2138
|
const DEFAULT_WIDTH = 3;
|
|
2139
|
+
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
2120
2140
|
if (!value) {
|
|
2121
|
-
return { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2141
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2122
2142
|
}
|
|
2123
2143
|
if (value === "inset") {
|
|
2124
|
-
return { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` };
|
|
2144
|
+
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2125
2145
|
}
|
|
2126
2146
|
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2127
2147
|
if (!isArbitrary && value in widthTokens) {
|
|
2128
2148
|
const w = widthTokens[value];
|
|
2129
|
-
return { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` };
|
|
2149
|
+
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
2130
2150
|
}
|
|
2131
2151
|
if (isArbitrary) {
|
|
2132
2152
|
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
2133
2153
|
if (numMatch) {
|
|
2134
2154
|
const unit = numMatch[2] ?? "px";
|
|
2135
|
-
return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2155
|
+
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2156
|
+
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2136
2157
|
}
|
|
2137
|
-
return { boxShadow: value.replace(/_/g, " ") };
|
|
2158
|
+
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2138
2159
|
}
|
|
2139
2160
|
const color = resolveColor(value, colors, false);
|
|
2140
|
-
if (color)
|
|
2161
|
+
if (color) {
|
|
2162
|
+
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
2163
|
+
}
|
|
2141
2164
|
return null;
|
|
2142
2165
|
},
|
|
2166
|
+
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2167
|
+
// create a gap between the element and the ring. There's no native
|
|
2168
|
+
// equivalent to approximate that with (a border can't create a gap outside
|
|
2169
|
+
// its own element without an extra wrapper view), so this stays a no-op
|
|
2170
|
+
// on native rather than rendering a misleading half-translation.
|
|
2143
2171
|
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2144
2172
|
if (!getEffectiveIsWeb()) return null;
|
|
2145
2173
|
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
package/kbach-react.md
CHANGED
|
@@ -428,7 +428,7 @@ mx-auto (centers element)
|
|
|
428
428
|
```
|
|
429
429
|
|
|
430
430
|
Spacing scale (1 unit = 4px):
|
|
431
|
-
`px(1) 0 0.5(2) 1(4) 1.5(6) 2(8) 2.5(10) 3(12) 3.5(14) 4(16) 5(20) 6(24) 7(28) 8(32) 9(36) 10(40) 11(44) 12(48) 14(56) 16(64) 20(80) 24(96) 28(112) 32(128) 36(144) 40(160) 44(176) 48(192) 52(208) 56(224) 60(240) 64(256) 72(288) 80(320) 96(384) auto full(100%) 1/2 1/3 2/3 1/4 3/4 screen(
|
|
431
|
+
`px(1) 0 0.5(2) 1(4) 1.5(6) 2(8) 2.5(10) 3(12) 3.5(14) 4(16) 5(20) 6(24) 7(28) 8(32) 9(36) 10(40) 11(44) 12(48) 14(56) 16(64) 20(80) 24(96) 28(112) 32(128) 36(144) 40(160) 44(176) 48(192) 52(208) 56(224) 60(240) 64(256) 72(288) 80(320) 96(384) auto full(100%) 1/2 1/3 2/3 1/4 3/4 screen(100dvh) min max fit`
|
|
432
432
|
|
|
433
433
|
### Sizing
|
|
434
434
|
```
|
|
@@ -437,7 +437,9 @@ w-{n} h-{n} size-{n} min-w-{n} min-h-{n} max-w-{n} max-h-{n}
|
|
|
437
437
|
Named max-w: none xs(320) sm(384) md(448) lg(512) xl(576) 2xl(672) 3xl(768)
|
|
438
438
|
4xl(896) 5xl(1024) 6xl(1152) 7xl(1280) prose(65ch)
|
|
439
439
|
|
|
440
|
-
Screen
|
|
440
|
+
Screen (dvw/dvh — correct on mobile where browser chrome resizes the
|
|
441
|
+
visible viewport; vw/vh are pinned to the largest viewport and overflow
|
|
442
|
+
behind a shown address bar): w-screen(100dvw) h-screen(100dvh)
|
|
441
443
|
min-w-screen max-w-screen min-h-screen max-h-screen
|
|
442
444
|
```
|
|
443
445
|
|
|
@@ -517,11 +519,15 @@ opacity-0/5/10/15/20/25/30/40/50/60/70/75/80/90/95/100
|
|
|
517
519
|
```
|
|
518
520
|
|
|
519
521
|
### Ring
|
|
522
|
+
Web: box-shadow ring. Native: approximated via borderWidth/borderColor
|
|
523
|
+
(no box-shadow on RN) — affects layout there and shares properties with
|
|
524
|
+
`border-*` (last class wins if both are used). `ring-offset-*`/`ring-inset`
|
|
525
|
+
stay web-only, with no native equivalent.
|
|
520
526
|
```
|
|
521
527
|
ring / ring-{n}(0 1 2 4 8)
|
|
522
528
|
ring-{color}
|
|
523
|
-
ring-inset
|
|
524
|
-
ring-offset-{n}(0 1 2 4 8)
|
|
529
|
+
ring-inset (web only)
|
|
530
|
+
ring-offset-{n}(0 1 2 4 8) (web only)
|
|
525
531
|
```
|
|
526
532
|
|
|
527
533
|
### Outline
|