@kbach/react-native 1.0.0-beta.24 → 1.0.0-beta.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,19 +3,20 @@ import {
3
3
  getDynamicToken,
4
4
  getGlobalDarkMode,
5
5
  getGlobalThemeMode,
6
+ resyncDomWithActiveTheme,
6
7
  seedDefaultMode,
7
8
  setDynamicToken,
8
9
  setGlobalThemeMode,
9
10
  subscribeDynamicTokens,
10
11
  subscribeGlobalDarkMode,
11
12
  toggleGlobalDarkMode
12
- } from "./chunk-TS2EEVOE.mjs";
13
+ } from "./chunk-LWD6JATB.mjs";
13
14
  import {
14
15
  defaultTheme,
15
16
  getTheme,
16
17
  resolveClassName,
17
18
  setTheme
18
- } from "./chunk-AG7ZQ2K4.mjs";
19
+ } from "./chunk-BEXNFWW6.mjs";
19
20
 
20
21
  // src/config.ts
21
22
  function parseHexRgb(hex) {
@@ -77,6 +78,7 @@ function resolveKbachConfig(config) {
77
78
  function applyKbachConfig(config) {
78
79
  const theme = resolveKbachConfig(config);
79
80
  setTheme(theme);
81
+ resyncDomWithActiveTheme();
80
82
  return theme;
81
83
  }
82
84
 
@@ -144,6 +146,7 @@ function ThemeProvider({ children, defaultMode = "system", persist = false }) {
144
146
  }
145
147
 
146
148
  // src/useColors.ts
149
+ import { useMemo as useMemo2 } from "react";
147
150
  function parseHexRgb2(hex) {
148
151
  const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
149
152
  if (!m) return null;
@@ -204,7 +207,8 @@ function makeColorsProxy(theme, isDark) {
204
207
  }
205
208
  function useColors() {
206
209
  const { isDark } = useTheme();
207
- return makeColorsProxy(getTheme(), isDark);
210
+ const theme = getTheme();
211
+ return useMemo2(() => makeColorsProxy(theme, isDark), [theme, isDark]);
208
212
  }
209
213
 
210
214
  // src/useDynamicToken.ts
@@ -729,6 +729,27 @@ function resolveNegatableLength(theme, parsed) {
729
729
  if (px === 0) return "0px";
730
730
  return `-${px}px`;
731
731
  }
732
+ function fractionPercent(value) {
733
+ const slashIdx = value.indexOf("/");
734
+ if (slashIdx === -1) return null;
735
+ const numStr = value.slice(0, slashIdx);
736
+ const denStr = value.slice(slashIdx + 1);
737
+ const num = Number(numStr);
738
+ const den = Number(denStr);
739
+ if (!Number.isFinite(num) || !Number.isFinite(den) || numStr.trim() === "" || denStr.trim() === "") return null;
740
+ if (den === 0) return null;
741
+ const pct = num / den * 100;
742
+ const formatted = pct.toFixed(6);
743
+ const trimmed = formatted.replace(/0+$/, "").replace(/\.$/, "");
744
+ return `${trimmed}%`;
745
+ }
746
+ function resolveNegatableSize(theme, parsed) {
747
+ if (!parsed.isArbitrary && parsed.value !== null) {
748
+ const pct = fractionPercent(parsed.value);
749
+ if (pct !== null) return parsed.negative ? `-${pct}` : pct;
750
+ }
751
+ return resolveNegatableLength(theme, parsed);
752
+ }
732
753
  function resolvePercent(parsed) {
733
754
  if (parsed.negative) return null;
734
755
  const value = parsed.value;
@@ -882,43 +903,44 @@ function resolve(parsed, theme) {
882
903
  case "shrink":
883
904
  return [decl("flex-shrink", parsed.value ?? "1")];
884
905
  // top/right/bottom/left/inset support real Tailwind's negative-value
885
- // convention ("-top-4") — see resolveNegatableLength's own doc comment.
906
+ // convention ("-top-4") AND its percentage-fraction scale ("top-1/2",
907
+ // "-inset-1/3") — see resolveNegatableSize's own doc comment.
886
908
  case "top": {
887
- const v = resolveNegatableLength(theme, parsed);
909
+ const v = resolveNegatableSize(theme, parsed);
888
910
  return v === null ? null : [decl("top", v)];
889
911
  }
890
912
  case "right": {
891
- const v = resolveNegatableLength(theme, parsed);
913
+ const v = resolveNegatableSize(theme, parsed);
892
914
  return v === null ? null : [decl("right", v)];
893
915
  }
894
916
  case "bottom": {
895
- const v = resolveNegatableLength(theme, parsed);
917
+ const v = resolveNegatableSize(theme, parsed);
896
918
  return v === null ? null : [decl("bottom", v)];
897
919
  }
898
920
  case "left": {
899
- const v = resolveNegatableLength(theme, parsed);
921
+ const v = resolveNegatableSize(theme, parsed);
900
922
  return v === null ? null : [decl("left", v)];
901
923
  }
902
924
  case "inset": {
903
- const v = resolveNegatableLength(theme, parsed);
925
+ const v = resolveNegatableSize(theme, parsed);
904
926
  return v === null ? null : [decl("inset", v)];
905
927
  }
906
928
  case "inset-x": {
907
- const v = resolveNegatableLength(theme, parsed);
929
+ const v = resolveNegatableSize(theme, parsed);
908
930
  return v === null ? null : [decl("left", v), decl("right", v)];
909
931
  }
910
932
  case "inset-y": {
911
- const v = resolveNegatableLength(theme, parsed);
933
+ const v = resolveNegatableSize(theme, parsed);
912
934
  return v === null ? null : [decl("top", v), decl("bottom", v)];
913
935
  }
914
936
  // Logical inset — just a different CSS property name, same reasoning
915
937
  // as Rust's layout.rs (no direction-tracking logic needed here).
916
938
  case "start": {
917
- const v = resolveNegatableLength(theme, parsed);
939
+ const v = resolveNegatableSize(theme, parsed);
918
940
  return v === null ? null : [decl("inset-inline-start", v)];
919
941
  }
920
942
  case "end": {
921
- const v = resolveNegatableLength(theme, parsed);
943
+ const v = resolveNegatableSize(theme, parsed);
922
944
  return v === null ? null : [decl("inset-inline-end", v)];
923
945
  }
924
946
  // "aspect-" is a registered VALUE_PREFIXES entry (parser.ts), so
@@ -1016,20 +1038,6 @@ function namedSize(key) {
1016
1038
  return null;
1017
1039
  }
1018
1040
  }
1019
- function fractionPercent(value) {
1020
- const slashIdx = value.indexOf("/");
1021
- if (slashIdx === -1) return null;
1022
- const numStr = value.slice(0, slashIdx);
1023
- const denStr = value.slice(slashIdx + 1);
1024
- const num = Number(numStr);
1025
- const den = Number(denStr);
1026
- if (!Number.isFinite(num) || !Number.isFinite(den) || numStr.trim() === "" || denStr.trim() === "") return null;
1027
- if (den === 0) return null;
1028
- const pct = num / den * 100;
1029
- const formatted = pct.toFixed(6);
1030
- const trimmed = formatted.replace(/0+$/, "").replace(/\.$/, "");
1031
- return `${trimmed}%`;
1032
- }
1033
1041
  function cssSizeKeyword(key) {
1034
1042
  switch (key) {
1035
1043
  case "min":
@@ -1930,16 +1938,33 @@ function resolveStyleJsWithWarnings(classString, theme, colorScheme, pressed, wi
1930
1938
  }
1931
1939
 
1932
1940
  // src/nativeBridge.ts
1941
+ var RESOLVE_STYLE_CACHE_MAX = 500;
1942
+ var resolveStyleCache = /* @__PURE__ */ new Map();
1943
+ var cachedForThemeJson = null;
1933
1944
  function resolveStyle(classString, pressed = false) {
1934
1945
  const colorScheme = (0, import_darkModeStore2.getGlobalDarkMode)() ? "dark" : "light";
1935
1946
  const width = import_react_native2.Dimensions.get("window").width;
1947
+ const themeJson = (0, import_theme.getThemeJson)();
1948
+ if (themeJson !== cachedForThemeJson) {
1949
+ resolveStyleCache.clear();
1950
+ cachedForThemeJson = themeJson;
1951
+ }
1952
+ const cacheKey = `${classString}\0${pressed}\0${colorScheme}\0${width}`;
1953
+ const cached = resolveStyleCache.get(cacheKey);
1954
+ if (cached !== void 0) return { ...cached };
1955
+ const style = resolveStyleUncached(classString, pressed, colorScheme, width, themeJson);
1956
+ if (resolveStyleCache.size >= RESOLVE_STYLE_CACHE_MAX) resolveStyleCache.clear();
1957
+ resolveStyleCache.set(cacheKey, style);
1958
+ return { ...style };
1959
+ }
1960
+ function resolveStyleUncached(classString, pressed, colorScheme, width, themeJson) {
1936
1961
  const KbachModule = import_react_native2.TurboModuleRegistry.get("KbachModule");
1937
1962
  if (!KbachModule) {
1938
1963
  const { style: style2, warnings: warnings2 } = resolveStyleJsWithWarnings(classString, (0, import_theme.getTheme)(), colorScheme, pressed, width);
1939
1964
  warnIfDev(classString, warnings2);
1940
1965
  return style2;
1941
1966
  }
1942
- const json = KbachModule.resolveStyle(classString, (0, import_theme.getThemeJson)(), colorScheme, pressed, width);
1967
+ const json = KbachModule.resolveStyle(classString, themeJson, colorScheme, pressed, width);
1943
1968
  const style = JSON.parse(json);
1944
1969
  const warnings = style.__kbachWarnings;
1945
1970
  if (warnings !== void 0) {