@kbach/react-native 1.0.0-beta.36 → 1.0.0-beta.37
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
CHANGED
|
@@ -307,6 +307,13 @@ parses without error but never takes effect. Supported today:
|
|
|
307
307
|
`hover:focus:opacity-100`) requires every named condition to hold at once
|
|
308
308
|
— chain order never matters (`dark:sm:` and `sm:dark:` are equivalent).
|
|
309
309
|
|
|
310
|
+
**Class order doesn't matter for a variant vs a base class.** When two
|
|
311
|
+
classes set the same property, the one with more active modifiers wins
|
|
312
|
+
regardless of which you write first — `dark:bg-black bg-white` and
|
|
313
|
+
`bg-white dark:bg-black` both render black in dark mode, matching how
|
|
314
|
+
Tailwind behaves on the web. Two equally-specific classes (`bg-white
|
|
315
|
+
bg-black`, or two `dark:` classes) still go last-one-wins.
|
|
316
|
+
|
|
310
317
|
`group-hover:`/`peer-hover:` and friends are NOT implemented on native —
|
|
311
318
|
doing so needs a React Context bridge (propagating an ancestor's hover/
|
|
312
319
|
press/focus state down to descendants, since there's no `.group`/`.peer`
|
|
Binary file
|
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -1605,7 +1605,9 @@ var Evaluator = class {
|
|
|
1605
1605
|
|
|
1606
1606
|
// src/jsEngine/resolveStyle.ts
|
|
1607
1607
|
var RESPONSIVE_BREAKPOINTS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
|
|
1608
|
+
var STATE_HOLD_MARKER = "_kbon";
|
|
1608
1609
|
function nativeModifierState(modifier, theme, colorScheme, pressed, width) {
|
|
1610
|
+
if (modifier === STATE_HOLD_MARKER) return true;
|
|
1609
1611
|
if (modifier === "dark") return colorScheme === "dark";
|
|
1610
1612
|
if (modifier === "active") return pressed;
|
|
1611
1613
|
if (RESPONSIVE_BREAKPOINTS.has(modifier)) {
|
|
@@ -1744,6 +1746,8 @@ function resolveStyleJsWithWarnings(classString, theme, colorScheme, pressed, wi
|
|
|
1744
1746
|
const warnings = [];
|
|
1745
1747
|
let shadowOffset = null;
|
|
1746
1748
|
const transformOps = /* @__PURE__ */ new Map();
|
|
1749
|
+
const keySpecificity = /* @__PURE__ */ new Map();
|
|
1750
|
+
const transformSpecificity = /* @__PURE__ */ new Map();
|
|
1747
1751
|
for (const rawToken of classString.split(/\s+/).filter(Boolean)) {
|
|
1748
1752
|
const token = substituteModeAwareColorToken(rawToken, theme, colorScheme);
|
|
1749
1753
|
const parsed = parseClass(token);
|
|
@@ -1753,31 +1757,44 @@ function resolveStyleJsWithWarnings(classString, theme, colorScheme, pressed, wi
|
|
|
1753
1757
|
if (!allModifiersHold) continue;
|
|
1754
1758
|
const decls = resolveUtilityNative(parsed, theme);
|
|
1755
1759
|
if (decls === null) continue;
|
|
1760
|
+
const spec = parsed.modifiers.length;
|
|
1756
1761
|
for (const d of decls) {
|
|
1757
1762
|
if (d.property.startsWith("__")) {
|
|
1758
1763
|
continue;
|
|
1759
1764
|
}
|
|
1760
1765
|
if (d.property === "shadow-offset-x" || d.property === "shadow-offset-y") {
|
|
1766
|
+
if (spec < (keySpecificity.get("shadowOffset") ?? 0)) continue;
|
|
1761
1767
|
const n = Number(d.value);
|
|
1762
1768
|
if (!Number.isFinite(n)) continue;
|
|
1763
1769
|
if (shadowOffset === null) shadowOffset = {};
|
|
1764
1770
|
shadowOffset[d.property === "shadow-offset-x" ? "width" : "height"] = n;
|
|
1771
|
+
keySpecificity.set("shadowOffset", spec);
|
|
1765
1772
|
continue;
|
|
1766
1773
|
}
|
|
1767
1774
|
if (d.property === "transform-op-none") {
|
|
1768
1775
|
transformOps.clear();
|
|
1776
|
+
transformSpecificity.clear();
|
|
1769
1777
|
continue;
|
|
1770
1778
|
}
|
|
1771
1779
|
const opKey = TRANSFORM_OP_KEYS.get(d.property);
|
|
1772
1780
|
if (opKey !== void 0) {
|
|
1781
|
+
if (spec < (transformSpecificity.get(opKey) ?? 0)) continue;
|
|
1773
1782
|
const { value: value2, warning: warning2 } = rnStyleValue(d.property, d.value);
|
|
1774
1783
|
if (warning2 !== null) warnings.push(warning2);
|
|
1775
|
-
if (value2 !== null)
|
|
1784
|
+
if (value2 !== null) {
|
|
1785
|
+
transformOps.set(opKey, value2);
|
|
1786
|
+
transformSpecificity.set(opKey, spec);
|
|
1787
|
+
}
|
|
1776
1788
|
continue;
|
|
1777
1789
|
}
|
|
1790
|
+
const key = kebabToCamel(d.property);
|
|
1791
|
+
if (spec < (keySpecificity.get(key) ?? 0)) continue;
|
|
1778
1792
|
const { value, warning } = rnStyleValue(d.property, d.value);
|
|
1779
1793
|
if (warning !== null) warnings.push(warning);
|
|
1780
|
-
if (value !== null)
|
|
1794
|
+
if (value !== null) {
|
|
1795
|
+
style[key] = value;
|
|
1796
|
+
keySpecificity.set(key, spec);
|
|
1797
|
+
}
|
|
1781
1798
|
}
|
|
1782
1799
|
}
|
|
1783
1800
|
if (shadowOffset !== null) {
|
package/dist/jsx-dev-runtime.js
CHANGED
|
@@ -725,9 +725,10 @@ function propBasedModifierState(name, states, hostRest) {
|
|
|
725
725
|
if (ariaInner !== null) return evalAttrCondition(hostRest, "aria-", ariaInner);
|
|
726
726
|
return null;
|
|
727
727
|
}
|
|
728
|
-
|
|
728
|
+
var STATE_HOLD_MARKER = "_kbon";
|
|
729
|
+
function markSatisfiedStateModifiers(parts, namesToReplace) {
|
|
729
730
|
const utility = parts[parts.length - 1] ?? "";
|
|
730
|
-
const modifiers = parts.slice(0, -1).
|
|
731
|
+
const modifiers = parts.slice(0, -1).map((m) => namesToReplace.has(m) ? STATE_HOLD_MARKER : m);
|
|
731
732
|
return [...modifiers, utility].join(":");
|
|
732
733
|
}
|
|
733
734
|
function substituteStateModifiers(classStrRaw, states, hostRest) {
|
|
@@ -745,7 +746,7 @@ function substituteStateModifiers(classStrRaw, states, hostRest) {
|
|
|
745
746
|
}
|
|
746
747
|
if (required.every(([, v]) => v === true)) {
|
|
747
748
|
const requiredNames = new Set(required.map(([m]) => m));
|
|
748
|
-
kept.push(
|
|
749
|
+
kept.push(markSatisfiedStateModifiers(parts, requiredNames));
|
|
749
750
|
}
|
|
750
751
|
}
|
|
751
752
|
return kept.join(" ");
|
|
@@ -1988,7 +1989,9 @@ function resolveUtilityNative(parsed, theme) {
|
|
|
1988
1989
|
|
|
1989
1990
|
// src/jsEngine/resolveStyle.ts
|
|
1990
1991
|
var RESPONSIVE_BREAKPOINTS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
|
|
1992
|
+
var STATE_HOLD_MARKER2 = "_kbon";
|
|
1991
1993
|
function nativeModifierState(modifier, theme, colorScheme, pressed, width) {
|
|
1994
|
+
if (modifier === STATE_HOLD_MARKER2) return true;
|
|
1992
1995
|
if (modifier === "dark") return colorScheme === "dark";
|
|
1993
1996
|
if (modifier === "active") return pressed;
|
|
1994
1997
|
if (RESPONSIVE_BREAKPOINTS.has(modifier)) {
|
|
@@ -2127,6 +2130,8 @@ function resolveStyleJsWithWarnings(classString, theme, colorScheme, pressed, wi
|
|
|
2127
2130
|
const warnings = [];
|
|
2128
2131
|
let shadowOffset = null;
|
|
2129
2132
|
const transformOps = /* @__PURE__ */ new Map();
|
|
2133
|
+
const keySpecificity = /* @__PURE__ */ new Map();
|
|
2134
|
+
const transformSpecificity = /* @__PURE__ */ new Map();
|
|
2130
2135
|
for (const rawToken of classString.split(/\s+/).filter(Boolean)) {
|
|
2131
2136
|
const token = substituteModeAwareColorToken(rawToken, theme, colorScheme);
|
|
2132
2137
|
const parsed = parseClass(token);
|
|
@@ -2136,31 +2141,44 @@ function resolveStyleJsWithWarnings(classString, theme, colorScheme, pressed, wi
|
|
|
2136
2141
|
if (!allModifiersHold) continue;
|
|
2137
2142
|
const decls = resolveUtilityNative(parsed, theme);
|
|
2138
2143
|
if (decls === null) continue;
|
|
2144
|
+
const spec = parsed.modifiers.length;
|
|
2139
2145
|
for (const d of decls) {
|
|
2140
2146
|
if (d.property.startsWith("__")) {
|
|
2141
2147
|
continue;
|
|
2142
2148
|
}
|
|
2143
2149
|
if (d.property === "shadow-offset-x" || d.property === "shadow-offset-y") {
|
|
2150
|
+
if (spec < (keySpecificity.get("shadowOffset") ?? 0)) continue;
|
|
2144
2151
|
const n = Number(d.value);
|
|
2145
2152
|
if (!Number.isFinite(n)) continue;
|
|
2146
2153
|
if (shadowOffset === null) shadowOffset = {};
|
|
2147
2154
|
shadowOffset[d.property === "shadow-offset-x" ? "width" : "height"] = n;
|
|
2155
|
+
keySpecificity.set("shadowOffset", spec);
|
|
2148
2156
|
continue;
|
|
2149
2157
|
}
|
|
2150
2158
|
if (d.property === "transform-op-none") {
|
|
2151
2159
|
transformOps.clear();
|
|
2160
|
+
transformSpecificity.clear();
|
|
2152
2161
|
continue;
|
|
2153
2162
|
}
|
|
2154
2163
|
const opKey = TRANSFORM_OP_KEYS.get(d.property);
|
|
2155
2164
|
if (opKey !== void 0) {
|
|
2165
|
+
if (spec < (transformSpecificity.get(opKey) ?? 0)) continue;
|
|
2156
2166
|
const { value: value2, warning: warning2 } = rnStyleValue(d.property, d.value);
|
|
2157
2167
|
if (warning2 !== null) warnings.push(warning2);
|
|
2158
|
-
if (value2 !== null)
|
|
2168
|
+
if (value2 !== null) {
|
|
2169
|
+
transformOps.set(opKey, value2);
|
|
2170
|
+
transformSpecificity.set(opKey, spec);
|
|
2171
|
+
}
|
|
2159
2172
|
continue;
|
|
2160
2173
|
}
|
|
2174
|
+
const key = kebabToCamel(d.property);
|
|
2175
|
+
if (spec < (keySpecificity.get(key) ?? 0)) continue;
|
|
2161
2176
|
const { value, warning } = rnStyleValue(d.property, d.value);
|
|
2162
2177
|
if (warning !== null) warnings.push(warning);
|
|
2163
|
-
if (value !== null)
|
|
2178
|
+
if (value !== null) {
|
|
2179
|
+
style[key] = value;
|
|
2180
|
+
keySpecificity.set(key, spec);
|
|
2181
|
+
}
|
|
2164
2182
|
}
|
|
2165
2183
|
}
|
|
2166
2184
|
if (shadowOffset !== null) {
|
package/dist/jsx-runtime.js
CHANGED
|
@@ -726,9 +726,10 @@ function propBasedModifierState(name, states, hostRest) {
|
|
|
726
726
|
if (ariaInner !== null) return evalAttrCondition(hostRest, "aria-", ariaInner);
|
|
727
727
|
return null;
|
|
728
728
|
}
|
|
729
|
-
|
|
729
|
+
var STATE_HOLD_MARKER = "_kbon";
|
|
730
|
+
function markSatisfiedStateModifiers(parts, namesToReplace) {
|
|
730
731
|
const utility = parts[parts.length - 1] ?? "";
|
|
731
|
-
const modifiers = parts.slice(0, -1).
|
|
732
|
+
const modifiers = parts.slice(0, -1).map((m) => namesToReplace.has(m) ? STATE_HOLD_MARKER : m);
|
|
732
733
|
return [...modifiers, utility].join(":");
|
|
733
734
|
}
|
|
734
735
|
function substituteStateModifiers(classStrRaw, states, hostRest) {
|
|
@@ -746,7 +747,7 @@ function substituteStateModifiers(classStrRaw, states, hostRest) {
|
|
|
746
747
|
}
|
|
747
748
|
if (required.every(([, v]) => v === true)) {
|
|
748
749
|
const requiredNames = new Set(required.map(([m]) => m));
|
|
749
|
-
kept.push(
|
|
750
|
+
kept.push(markSatisfiedStateModifiers(parts, requiredNames));
|
|
750
751
|
}
|
|
751
752
|
}
|
|
752
753
|
return kept.join(" ");
|
|
@@ -1979,7 +1980,9 @@ function resolveUtilityNative(parsed, theme) {
|
|
|
1979
1980
|
|
|
1980
1981
|
// src/jsEngine/resolveStyle.ts
|
|
1981
1982
|
var RESPONSIVE_BREAKPOINTS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
|
|
1983
|
+
var STATE_HOLD_MARKER2 = "_kbon";
|
|
1982
1984
|
function nativeModifierState(modifier, theme, colorScheme, pressed, width) {
|
|
1985
|
+
if (modifier === STATE_HOLD_MARKER2) return true;
|
|
1983
1986
|
if (modifier === "dark") return colorScheme === "dark";
|
|
1984
1987
|
if (modifier === "active") return pressed;
|
|
1985
1988
|
if (RESPONSIVE_BREAKPOINTS.has(modifier)) {
|
|
@@ -2118,6 +2121,8 @@ function resolveStyleJsWithWarnings(classString, theme, colorScheme, pressed, wi
|
|
|
2118
2121
|
const warnings = [];
|
|
2119
2122
|
let shadowOffset = null;
|
|
2120
2123
|
const transformOps = /* @__PURE__ */ new Map();
|
|
2124
|
+
const keySpecificity = /* @__PURE__ */ new Map();
|
|
2125
|
+
const transformSpecificity = /* @__PURE__ */ new Map();
|
|
2121
2126
|
for (const rawToken of classString.split(/\s+/).filter(Boolean)) {
|
|
2122
2127
|
const token = substituteModeAwareColorToken(rawToken, theme, colorScheme);
|
|
2123
2128
|
const parsed = parseClass(token);
|
|
@@ -2127,31 +2132,44 @@ function resolveStyleJsWithWarnings(classString, theme, colorScheme, pressed, wi
|
|
|
2127
2132
|
if (!allModifiersHold) continue;
|
|
2128
2133
|
const decls = resolveUtilityNative(parsed, theme);
|
|
2129
2134
|
if (decls === null) continue;
|
|
2135
|
+
const spec = parsed.modifiers.length;
|
|
2130
2136
|
for (const d of decls) {
|
|
2131
2137
|
if (d.property.startsWith("__")) {
|
|
2132
2138
|
continue;
|
|
2133
2139
|
}
|
|
2134
2140
|
if (d.property === "shadow-offset-x" || d.property === "shadow-offset-y") {
|
|
2141
|
+
if (spec < (keySpecificity.get("shadowOffset") ?? 0)) continue;
|
|
2135
2142
|
const n = Number(d.value);
|
|
2136
2143
|
if (!Number.isFinite(n)) continue;
|
|
2137
2144
|
if (shadowOffset === null) shadowOffset = {};
|
|
2138
2145
|
shadowOffset[d.property === "shadow-offset-x" ? "width" : "height"] = n;
|
|
2146
|
+
keySpecificity.set("shadowOffset", spec);
|
|
2139
2147
|
continue;
|
|
2140
2148
|
}
|
|
2141
2149
|
if (d.property === "transform-op-none") {
|
|
2142
2150
|
transformOps.clear();
|
|
2151
|
+
transformSpecificity.clear();
|
|
2143
2152
|
continue;
|
|
2144
2153
|
}
|
|
2145
2154
|
const opKey = TRANSFORM_OP_KEYS.get(d.property);
|
|
2146
2155
|
if (opKey !== void 0) {
|
|
2156
|
+
if (spec < (transformSpecificity.get(opKey) ?? 0)) continue;
|
|
2147
2157
|
const { value: value2, warning: warning2 } = rnStyleValue(d.property, d.value);
|
|
2148
2158
|
if (warning2 !== null) warnings.push(warning2);
|
|
2149
|
-
if (value2 !== null)
|
|
2159
|
+
if (value2 !== null) {
|
|
2160
|
+
transformOps.set(opKey, value2);
|
|
2161
|
+
transformSpecificity.set(opKey, spec);
|
|
2162
|
+
}
|
|
2150
2163
|
continue;
|
|
2151
2164
|
}
|
|
2165
|
+
const key = kebabToCamel(d.property);
|
|
2166
|
+
if (spec < (keySpecificity.get(key) ?? 0)) continue;
|
|
2152
2167
|
const { value, warning } = rnStyleValue(d.property, d.value);
|
|
2153
2168
|
if (warning !== null) warnings.push(warning);
|
|
2154
|
-
if (value !== null)
|
|
2169
|
+
if (value !== null) {
|
|
2170
|
+
style[key] = value;
|
|
2171
|
+
keySpecificity.set(key, spec);
|
|
2172
|
+
}
|
|
2155
2173
|
}
|
|
2156
2174
|
}
|
|
2157
2175
|
if (shadowOffset !== null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kbach/react-native",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.37",
|
|
4
4
|
"description": "Kbach's utility-class styling engine for React Native — the same class names as @kbach/react, resolved to a StyleSheet-ready style object via a Kotlin/JNI TurboModule (native), the same WASM engine @kbach/react uses (Expo Web / react-native-web), or a pure-JS fallback engine (Expo Go). Ships its own native Android module — one npm install, no separate native package. Beta. Native is Android-only (no iOS bridge yet); works with the React Native CLI, an Expo dev client, AND Expo Go (a reduced-coverage pure-JS fallback, since Expo Go can't load any custom native module).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|