@kbach/react-native 1.0.0-beta.33 → 1.0.0-beta.34

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.
@@ -5,17 +5,20 @@ import { ReactNode } from 'react';
5
5
 
6
6
  /**
7
7
  * A `kbach.config.js`-style theme customization — same shape as
8
- * @kbach/react's `KbachConfig`, minus mode-aware `{ light, dark }` color
9
- * entries in `extend.colors` specifically: aliasing/opacity math here only
10
- * ever operates on plain hex (`brand: 'blue-6'`, `brandSoft: 'brand/30'`),
11
- * matching `jsEngine/resolvers/color.ts`'s `lookupHex`'s own Plain-only
12
- * convention — a reference to an EXISTING color that happens to be
13
- * mode-aware (`theme.colors` can hold those now, for `useColors()`; see
14
- * `theme.ts`'s own `ColorEntry` doc comment) just doesn't resolve as an
15
- * alias, falling through to "literal CSS value" the same way an unknown
16
- * name would. A config object goes in, a resolved `ThemeConfig` comes out,
17
- * via one PURE function (`resolveKbachConfig`) — no plugins, no
18
- * live-update store, nothing to keep "in sync."
8
+ * @kbach/react's `KbachConfig`, minus @kbach/react's own PER-COLOR
9
+ * `{ light, dark }` object form in `extend.colors` specifically (real
10
+ * mode-aware colors here are written via the grouped `dark` key instead —
11
+ * see `KbachConfig.extend.colors`'s own doc comment below): aliasing/
12
+ * opacity math on an individual color value here only ever operates on
13
+ * plain hex (`brand: 'blue-6'`, `brandSoft: 'brand/30'`), matching
14
+ * `jsEngine/resolvers/color.ts`'s `lookupHex`'s own Plain-only convention
15
+ * — a reference to an EXISTING color that happens to be mode-aware
16
+ * (`theme.colors` can hold those, for `useColors()`; see `theme.ts`'s own
17
+ * `ColorEntry` doc comment) just doesn't resolve as an alias, falling
18
+ * through to "literal CSS value" the same way an unknown name would. A
19
+ * config object goes in, a resolved `ThemeConfig` comes out, via one PURE
20
+ * function (`resolveKbachConfig`) — no plugins, no live-update store,
21
+ * nothing to keep "in sync."
19
22
  */
20
23
  interface KbachConfig {
21
24
  darkMode?: ThemeConfig['darkMode'];
@@ -37,8 +40,26 @@ interface KbachConfig {
37
40
  * '#ff6b35', brandSoft: 'brand/30' }` — `brandSoft` resolves to
38
41
  * `brand`'s own value at 30% opacity). A string that doesn't match any
39
42
  * known color name is treated as a literal CSS value instead.
43
+ *
44
+ * `dark` is a reserved key, not a color name: a parallel map of
45
+ * dark-mode overrides for any of the OTHER names in this same object —
46
+ * `{ surface: 'gray-2', card: 'white', dark: { surface: 'gray-11',
47
+ * card: 'gray-9' } }` makes `surface`/`card` mode-aware
48
+ * (`{ light, dark }` entries in the resolved theme), while `brand`
49
+ * (never mentioned under `dark`) stays a plain, mode-independent
50
+ * color. A name under `dark` with no matching top-level (light) entry
51
+ * is skipped — mode-aware colors need both sides written out, and
52
+ * inventing a "light" value out of nowhere would be worse than just
53
+ * not creating the entry at all. References inside `dark` resolve
54
+ * against the built-in palette and OTHER entries within `dark` itself
55
+ * (not against the light-side custom colors) — the same
56
+ * "self-contained, ordering-independent-of-the-other-side" resolution
57
+ * the light side already gets, just mirrored.
40
58
  */
41
- colors?: Record<string, string>;
59
+ colors?: {
60
+ [colorName: string]: string | Record<string, string> | undefined;
61
+ dark?: Record<string, string>;
62
+ };
42
63
  spacing?: Record<string, number>;
43
64
  screens?: Record<string, number>;
44
65
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { ColorEntry, ContainerConfig, ThemeConfig, defaultTheme, getTheme, setTheme } from './theme';
2
- export { C as ClassArray, a as ClassDictionary, b as ClassValue, c as ColorScale, d as ColorsAPI, K as KbachConfig, T as ThemeProvider, e as ThemeProviderProps, f as ThemeState, g as ThemeStorageAdapter, h as applyKbachConfig, i as clsx, r as resolveKbachConfig, u as useColors, j as useDynamicToken, k as useTheme } from './clsx-BCXALPGh.js';
2
+ export { C as ClassArray, a as ClassDictionary, b as ClassValue, c as ColorScale, d as ColorsAPI, K as KbachConfig, T as ThemeProvider, e as ThemeProviderProps, f as ThemeState, g as ThemeStorageAdapter, h as applyKbachConfig, i as clsx, r as resolveKbachConfig, u as useColors, j as useDynamicToken, k as useTheme } from './clsx-CxjWSCcU.js';
3
3
  export { ThemeMode, getGlobalDarkMode, getGlobalThemeMode, setGlobalThemeMode, subscribeGlobalDarkMode, toggleGlobalDarkMode } from './darkModeStore';
4
4
  export { deleteDynamicToken, getDynamicToken, setDynamicToken, subscribeDynamicTokens } from './dynamicTokens';
5
5
  import 'react';
package/dist/index.js CHANGED
@@ -1843,15 +1843,33 @@ function resolveColorEntry(value, lookup) {
1843
1843
  return opacity === void 0 ? base : applyOpacityToHex(base, opacity);
1844
1844
  }
1845
1845
  function resolveColors(extend, existing) {
1846
- const resolved = {};
1847
- const lookup = (name) => {
1848
- const found = resolved[name] ?? existing[name];
1846
+ const { dark: darkExtend, ...lightExtend } = extend;
1847
+ const resolvedLight = {};
1848
+ const lookupLight = (name) => {
1849
+ const found = resolvedLight[name] ?? existing[name];
1849
1850
  return typeof found === "string" ? found : void 0;
1850
1851
  };
1851
- for (const [name, value] of Object.entries(extend)) {
1852
- resolved[name] = resolveColorEntry(value, lookup);
1852
+ for (const [name, value] of Object.entries(lightExtend)) {
1853
+ if (typeof value !== "string") continue;
1854
+ resolvedLight[name] = resolveColorEntry(value, lookupLight);
1855
+ }
1856
+ const result = { ...resolvedLight };
1857
+ if (darkExtend) {
1858
+ const resolvedDark = {};
1859
+ const lookupDark = (name) => {
1860
+ const found = resolvedDark[name] ?? existing[name];
1861
+ return typeof found === "string" ? found : void 0;
1862
+ };
1863
+ for (const [name, value] of Object.entries(darkExtend)) {
1864
+ resolvedDark[name] = resolveColorEntry(value, lookupDark);
1865
+ }
1866
+ for (const [name, darkValue] of Object.entries(resolvedDark)) {
1867
+ const lightValue = resolvedLight[name];
1868
+ if (lightValue === void 0) continue;
1869
+ result[name] = { light: lightValue, dark: darkValue };
1870
+ }
1853
1871
  }
1854
- return resolved;
1872
+ return result;
1855
1873
  }
1856
1874
  function resolveKbachConfig(config) {
1857
1875
  let theme = { ...import_theme2.defaultTheme, ...config.theme };
@@ -1,5 +1,5 @@
1
1
  export { ColorEntry, ContainerConfig, ThemeConfig, defaultTheme, getTheme, setTheme } from './theme';
2
- export { C as ClassArray, a as ClassDictionary, b as ClassValue, c as ColorScale, d as ColorsAPI, K as KbachConfig, T as ThemeProvider, e as ThemeProviderProps, f as ThemeState, h as applyKbachConfig, i as clsx, r as resolveKbachConfig, u as useColors, j as useDynamicToken, k as useTheme } from './clsx-BCXALPGh.js';
2
+ export { C as ClassArray, a as ClassDictionary, b as ClassValue, c as ColorScale, d as ColorsAPI, K as KbachConfig, T as ThemeProvider, e as ThemeProviderProps, f as ThemeState, h as applyKbachConfig, i as clsx, r as resolveKbachConfig, u as useColors, j as useDynamicToken, k as useTheme } from './clsx-CxjWSCcU.js';
3
3
  export { ThemeMode, getGlobalDarkMode, getGlobalThemeMode, setGlobalThemeMode, subscribeGlobalDarkMode, toggleGlobalDarkMode } from './darkModeStore';
4
4
  export { deleteDynamicToken, getDynamicToken, setDynamicToken, subscribeDynamicTokens } from './dynamicTokens';
5
5
  import 'react';
package/dist/index.web.js CHANGED
@@ -271,15 +271,33 @@ function resolveColorEntry(value, lookup) {
271
271
  return opacity === void 0 ? base : applyOpacityToHex(base, opacity);
272
272
  }
273
273
  function resolveColors(extend, existing) {
274
- const resolved = {};
275
- const lookup = (name) => {
276
- const found = resolved[name] ?? existing[name];
274
+ const { dark: darkExtend, ...lightExtend } = extend;
275
+ const resolvedLight = {};
276
+ const lookupLight = (name) => {
277
+ const found = resolvedLight[name] ?? existing[name];
277
278
  return typeof found === "string" ? found : void 0;
278
279
  };
279
- for (const [name, value] of Object.entries(extend)) {
280
- resolved[name] = resolveColorEntry(value, lookup);
280
+ for (const [name, value] of Object.entries(lightExtend)) {
281
+ if (typeof value !== "string") continue;
282
+ resolvedLight[name] = resolveColorEntry(value, lookupLight);
281
283
  }
282
- return resolved;
284
+ const result = { ...resolvedLight };
285
+ if (darkExtend) {
286
+ const resolvedDark = {};
287
+ const lookupDark = (name) => {
288
+ const found = resolvedDark[name] ?? existing[name];
289
+ return typeof found === "string" ? found : void 0;
290
+ };
291
+ for (const [name, value] of Object.entries(darkExtend)) {
292
+ resolvedDark[name] = resolveColorEntry(value, lookupDark);
293
+ }
294
+ for (const [name, darkValue] of Object.entries(resolvedDark)) {
295
+ const lightValue = resolvedLight[name];
296
+ if (lightValue === void 0) continue;
297
+ result[name] = { light: lightValue, dark: darkValue };
298
+ }
299
+ }
300
+ return result;
283
301
  }
284
302
  function resolveKbachConfig(config) {
285
303
  let theme = { ...import_theme2.defaultTheme, ...config.theme };
@@ -43,15 +43,33 @@ function resolveColorEntry(value, lookup) {
43
43
  return opacity === void 0 ? base : applyOpacityToHex(base, opacity);
44
44
  }
45
45
  function resolveColors(extend, existing) {
46
- const resolved = {};
47
- const lookup = (name) => {
48
- const found = resolved[name] ?? existing[name];
46
+ const { dark: darkExtend, ...lightExtend } = extend;
47
+ const resolvedLight = {};
48
+ const lookupLight = (name) => {
49
+ const found = resolvedLight[name] ?? existing[name];
49
50
  return typeof found === "string" ? found : void 0;
50
51
  };
51
- for (const [name, value] of Object.entries(extend)) {
52
- resolved[name] = resolveColorEntry(value, lookup);
52
+ for (const [name, value] of Object.entries(lightExtend)) {
53
+ if (typeof value !== "string") continue;
54
+ resolvedLight[name] = resolveColorEntry(value, lookupLight);
53
55
  }
54
- return resolved;
56
+ const result = { ...resolvedLight };
57
+ if (darkExtend) {
58
+ const resolvedDark = {};
59
+ const lookupDark = (name) => {
60
+ const found = resolvedDark[name] ?? existing[name];
61
+ return typeof found === "string" ? found : void 0;
62
+ };
63
+ for (const [name, value] of Object.entries(darkExtend)) {
64
+ resolvedDark[name] = resolveColorEntry(value, lookupDark);
65
+ }
66
+ for (const [name, darkValue] of Object.entries(resolvedDark)) {
67
+ const lightValue = resolvedLight[name];
68
+ if (lightValue === void 0) continue;
69
+ result[name] = { light: lightValue, dark: darkValue };
70
+ }
71
+ }
72
+ return result;
55
73
  }
56
74
  function resolveKbachConfig(config) {
57
75
  let theme = { ...defaultTheme, ...config.theme };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react-native",
3
- "version": "1.0.0-beta.33",
3
+ "version": "1.0.0-beta.34",
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",