@kbach/react-native 1.0.0-beta.2 → 1.0.0-beta.21
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 +253 -87
- package/android/build.gradle +36 -0
- package/android/src/main/AndroidManifest.xml +14 -0
- package/android/src/main/java/com/kbachnative/KbachModule.kt +83 -0
- package/android/src/main/java/com/kbachnative/KbachPackage.kt +54 -0
- package/android/src/main/jniLibs/arm64-v8a/libkbach_core_engine.so +0 -0
- package/android/src/main/jniLibs/x86_64/libkbach_core_engine.so +0 -0
- package/dist/chunk-AG7ZQ2K4.mjs +552 -0
- package/dist/chunk-OS7EPBH5.mjs +40 -0
- package/dist/chunk-TS2EEVOE.mjs +107 -0
- package/dist/darkModeStore.d.ts +58 -0
- package/dist/darkModeStore.js +112 -0
- package/dist/dynamicTokens.d.ts +36 -0
- package/dist/dynamicTokens.js +75 -0
- package/dist/index.d.ts +53 -102
- package/dist/index.js +1721 -385
- package/dist/index.web.d.ts +18 -0
- package/dist/index.web.js +436 -0
- package/dist/index.web.mjs +210 -0
- package/dist/jsx-dev-runtime.d.ts +3 -12
- package/dist/jsx-dev-runtime.js +1738 -343
- package/dist/jsx-dev-runtime.web.d.ts +10 -0
- package/dist/jsx-dev-runtime.web.js +270 -0
- package/dist/jsx-dev-runtime.web.mjs +29 -0
- package/dist/jsx-runtime.d.ts +3 -23
- package/dist/jsx-runtime.js +1729 -335
- package/dist/jsx-runtime.web.d.ts +7 -0
- package/dist/jsx-runtime.web.js +252 -0
- package/dist/{jsx-runtime.mjs → jsx-runtime.web.mjs} +2 -2
- package/dist/theme.d.ts +54 -0
- package/dist/{chunk-YHF3QLRL.mjs → theme.js} +94 -72
- package/dist/useDynamicToken-Dr15c88t.d.ts +160 -0
- package/package.json +62 -14
- package/react-native.config.js +29 -0
- package/specs/NativeKbachModule.ts +31 -0
- package/src/babel-plugin.js +74 -2
- package/dist/chunk-SVMYVXY6.mjs +0 -44
- package/dist/index.d.mts +0 -148
- package/dist/index.mjs +0 -80
- package/dist/jsx-dev-runtime.d.mts +0 -19
- package/dist/jsx-dev-runtime.mjs +0 -20
- package/dist/jsx-runtime.d.mts +0 -27
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveClassName
|
|
3
|
+
} from "./chunk-AG7ZQ2K4.mjs";
|
|
4
|
+
|
|
5
|
+
// src/jsxRuntimeCoreWeb.ts
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { Fragment } from "react";
|
|
8
|
+
function makeElement(isStaticChildren, type, props, key) {
|
|
9
|
+
return (isStaticChildren ? _jsxs : _jsx)(type, props, key);
|
|
10
|
+
}
|
|
11
|
+
function processElement(resolveClassName2, type, rawProps, key, isStaticChildren) {
|
|
12
|
+
if (type === null || typeof type === "symbol" || !rawProps) {
|
|
13
|
+
return makeElement(isStaticChildren, type, rawProps ?? {}, key);
|
|
14
|
+
}
|
|
15
|
+
const { className: classStrRaw, dataSet: userDataSet, ...rest } = rawProps;
|
|
16
|
+
if (typeof classStrRaw !== "string") {
|
|
17
|
+
return makeElement(isStaticChildren, type, rawProps, key);
|
|
18
|
+
}
|
|
19
|
+
const resolved = resolveClassName2(classStrRaw);
|
|
20
|
+
const dataSet = { ...userDataSet, kb: resolved };
|
|
21
|
+
return makeElement(isStaticChildren, type, { ...rest, dataSet }, key);
|
|
22
|
+
}
|
|
23
|
+
function createJsxFunctionsWeb(resolveClassName2) {
|
|
24
|
+
function jsx2(type, props, key) {
|
|
25
|
+
return processElement(resolveClassName2, type, props, key, false);
|
|
26
|
+
}
|
|
27
|
+
function jsxs2(type, props, key) {
|
|
28
|
+
return processElement(resolveClassName2, type, props, key, true);
|
|
29
|
+
}
|
|
30
|
+
return { jsx: jsx2, jsxs: jsxs2 };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/jsx-runtime.web.tsx
|
|
34
|
+
var { jsx, jsxs } = createJsxFunctionsWeb(resolveClassName);
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
Fragment,
|
|
38
|
+
jsx,
|
|
39
|
+
jsxs
|
|
40
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getTheme
|
|
3
|
+
} from "./chunk-AG7ZQ2K4.mjs";
|
|
4
|
+
|
|
5
|
+
// src/darkModeStore.ts
|
|
6
|
+
import { Appearance } from "react-native";
|
|
7
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
8
|
+
function systemPrefersDark() {
|
|
9
|
+
return Appearance.getColorScheme() === "dark";
|
|
10
|
+
}
|
|
11
|
+
function resolveIsDark(m) {
|
|
12
|
+
return m === "system" ? systemPrefersDark() : m === "dark";
|
|
13
|
+
}
|
|
14
|
+
function applyToDom(dark) {
|
|
15
|
+
if (typeof document === "undefined") return;
|
|
16
|
+
const root = document.documentElement;
|
|
17
|
+
const strategy = getTheme().darkMode;
|
|
18
|
+
if (strategy === "class") {
|
|
19
|
+
root.classList.toggle("dark", dark);
|
|
20
|
+
root.classList.toggle("light", !dark);
|
|
21
|
+
} else if (strategy === "attribute") {
|
|
22
|
+
root.setAttribute("data-theme", dark ? "dark" : "light");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
var mode = "system";
|
|
26
|
+
var isDark = resolveIsDark(mode);
|
|
27
|
+
applyToDom(isDark);
|
|
28
|
+
var hasExplicitChoice = false;
|
|
29
|
+
var subscription = Appearance.addChangeListener(({ colorScheme }) => {
|
|
30
|
+
if (mode !== "system") return;
|
|
31
|
+
isDark = colorScheme === "dark";
|
|
32
|
+
applyToDom(isDark);
|
|
33
|
+
notify();
|
|
34
|
+
});
|
|
35
|
+
function notify() {
|
|
36
|
+
for (const listener of listeners) listener();
|
|
37
|
+
}
|
|
38
|
+
function getGlobalDarkMode() {
|
|
39
|
+
return isDark;
|
|
40
|
+
}
|
|
41
|
+
function getGlobalThemeMode() {
|
|
42
|
+
return mode;
|
|
43
|
+
}
|
|
44
|
+
function setGlobalThemeMode(nextMode) {
|
|
45
|
+
mode = nextMode;
|
|
46
|
+
isDark = resolveIsDark(nextMode);
|
|
47
|
+
hasExplicitChoice = true;
|
|
48
|
+
applyToDom(isDark);
|
|
49
|
+
notify();
|
|
50
|
+
}
|
|
51
|
+
function toggleGlobalDarkMode() {
|
|
52
|
+
setGlobalThemeMode(isDark ? "light" : "dark");
|
|
53
|
+
}
|
|
54
|
+
function subscribeGlobalDarkMode(listener) {
|
|
55
|
+
listeners.add(listener);
|
|
56
|
+
return () => listeners.delete(listener);
|
|
57
|
+
}
|
|
58
|
+
function seedDefaultMode(fallback) {
|
|
59
|
+
if (hasExplicitChoice || mode === fallback) return;
|
|
60
|
+
mode = fallback;
|
|
61
|
+
isDark = resolveIsDark(fallback);
|
|
62
|
+
applyToDom(isDark);
|
|
63
|
+
notify();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/dynamicTokens.ts
|
|
67
|
+
var tokens = /* @__PURE__ */ new Map();
|
|
68
|
+
var listeners2 = /* @__PURE__ */ new Set();
|
|
69
|
+
var version = 0;
|
|
70
|
+
function applyToDom2(name, value) {
|
|
71
|
+
if (typeof document === "undefined") return;
|
|
72
|
+
document.documentElement.style.setProperty(`--${name}`, value);
|
|
73
|
+
}
|
|
74
|
+
function notify2() {
|
|
75
|
+
version++;
|
|
76
|
+
for (const listener of listeners2) listener();
|
|
77
|
+
}
|
|
78
|
+
function setDynamicToken(name, value) {
|
|
79
|
+
tokens.set(name, value);
|
|
80
|
+
applyToDom2(name, value);
|
|
81
|
+
notify2();
|
|
82
|
+
}
|
|
83
|
+
function getDynamicToken(name) {
|
|
84
|
+
return tokens.get(name);
|
|
85
|
+
}
|
|
86
|
+
function deleteDynamicToken(name) {
|
|
87
|
+
if (!tokens.delete(name)) return;
|
|
88
|
+
if (typeof document !== "undefined") document.documentElement.style.removeProperty(`--${name}`);
|
|
89
|
+
notify2();
|
|
90
|
+
}
|
|
91
|
+
function subscribeDynamicTokens(listener) {
|
|
92
|
+
listeners2.add(listener);
|
|
93
|
+
return () => listeners2.delete(listener);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
getGlobalDarkMode,
|
|
98
|
+
getGlobalThemeMode,
|
|
99
|
+
setGlobalThemeMode,
|
|
100
|
+
toggleGlobalDarkMode,
|
|
101
|
+
subscribeGlobalDarkMode,
|
|
102
|
+
seedDefaultMode,
|
|
103
|
+
setDynamicToken,
|
|
104
|
+
getDynamicToken,
|
|
105
|
+
deleteDynamicToken,
|
|
106
|
+
subscribeDynamicTokens
|
|
107
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native port of @kbach/react's darkModeStore.ts — same architecture (a
|
|
3
|
+
* single module-level store is the real source of truth;
|
|
4
|
+
* ThemeProvider/useTheme are a thin, OPTIONAL wrapper around it; every
|
|
5
|
+
* function here works standalone with no provider mounted anywhere), with
|
|
6
|
+
* two real platform differences from the web version:
|
|
7
|
+
*
|
|
8
|
+
* 1. No persistence. There's no React-Native-builtin equivalent of
|
|
9
|
+
* localStorage — adding one would mean forcing a real native dependency
|
|
10
|
+
* (e.g. @react-native-async-storage/async-storage) on every consumer,
|
|
11
|
+
* even ones that don't want it. The mode always starts at 'system' on a
|
|
12
|
+
* fresh app launch. If you want persistence, read your own storage at
|
|
13
|
+
* startup (before your first render) and call setGlobalThemeMode() with
|
|
14
|
+
* the result — same "seed once, no built-in write-back" shape as
|
|
15
|
+
* seedDefaultMode() below, just driven by your own storage instead of
|
|
16
|
+
* one this package picks for you.
|
|
17
|
+
* 2. `applyToDom` below IS needed here, unlike what an earlier version of
|
|
18
|
+
* this file's own comment claimed ("no DOM to apply the resolved mode
|
|
19
|
+
* to") — that reasoning only holds for real native (Android/iOS), where
|
|
20
|
+
* nativeBridge.ts's resolveStyle() reads getGlobalDarkMode() directly on
|
|
21
|
+
* every call, no DOM involved at all. This file is ALSO used by Expo
|
|
22
|
+
* Web, though (no `.web.ts` sibling — Metro has nothing to swap in), and
|
|
23
|
+
* Expo Web resolves `dark:` classes to REAL CSS with `[data-theme=
|
|
24
|
+
* "dark"]`-style selectors (see nativeBridge.web.ts) that only ever
|
|
25
|
+
* match if something writes that attribute to the DOM — nothing did,
|
|
26
|
+
* which is exactly why toggling the mode changed `useTheme()`'s own
|
|
27
|
+
* state (a consumer reading `mode`/`isDark` directly, e.g. for a label,
|
|
28
|
+
* updated correctly) while every `dark:`-prefixed style silently never
|
|
29
|
+
* applied. `typeof document === 'undefined'` is what makes one function
|
|
30
|
+
* safe on both platforms: real native's Hermes has no `document` global
|
|
31
|
+
* at all (not even `undefined` as a defined-but-empty value — genuinely
|
|
32
|
+
* unset, which `typeof` can check without throwing), so this always
|
|
33
|
+
* no-ops there, while Expo Web's react-native-web renders into a real
|
|
34
|
+
* browser DOM where it's needed.
|
|
35
|
+
*/
|
|
36
|
+
type ThemeMode = 'light' | 'dark' | 'system';
|
|
37
|
+
declare function getGlobalDarkMode(): boolean;
|
|
38
|
+
declare function getGlobalThemeMode(): ThemeMode;
|
|
39
|
+
/** Explicit user choice — takes priority over any later `<ThemeProvider defaultMode>` seed (see `seedDefaultMode` below). Not persisted; see this module's own doc comment. */
|
|
40
|
+
declare function setGlobalThemeMode(nextMode: ThemeMode): void;
|
|
41
|
+
declare function toggleGlobalDarkMode(): void;
|
|
42
|
+
declare function subscribeGlobalDarkMode(listener: () => void): () => void;
|
|
43
|
+
/**
|
|
44
|
+
* Applies `fallback` as the initial mode, but ONLY if nothing has made an
|
|
45
|
+
* explicit choice yet — called once by `<ThemeProvider defaultMode>` on
|
|
46
|
+
* mount, never exported for direct use elsewhere. Unlike the web store,
|
|
47
|
+
* there's no persisted-value check here (nothing to check); the only
|
|
48
|
+
* thing that can beat a seed is a `setGlobalThemeMode()` call that
|
|
49
|
+
* happened first (e.g. your own storage-restore logic run before the
|
|
50
|
+
* provider mounts).
|
|
51
|
+
*/
|
|
52
|
+
declare function seedDefaultMode(fallback: ThemeMode): void;
|
|
53
|
+
/** Exported for tests only — resets every module-level field back to its as-if-just-imported state. */
|
|
54
|
+
declare function _resetForTests(): void;
|
|
55
|
+
/** Exported for tests only — removes the Appearance change subscription so a test's mock doesn't leak into the next one. */
|
|
56
|
+
declare function _unsubscribeForTests(): void;
|
|
57
|
+
|
|
58
|
+
export { type ThemeMode, _resetForTests, _unsubscribeForTests, getGlobalDarkMode, getGlobalThemeMode, seedDefaultMode, setGlobalThemeMode, subscribeGlobalDarkMode, toggleGlobalDarkMode };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/darkModeStore.ts
|
|
21
|
+
var darkModeStore_exports = {};
|
|
22
|
+
__export(darkModeStore_exports, {
|
|
23
|
+
_resetForTests: () => _resetForTests,
|
|
24
|
+
_unsubscribeForTests: () => _unsubscribeForTests,
|
|
25
|
+
getGlobalDarkMode: () => getGlobalDarkMode,
|
|
26
|
+
getGlobalThemeMode: () => getGlobalThemeMode,
|
|
27
|
+
seedDefaultMode: () => seedDefaultMode,
|
|
28
|
+
setGlobalThemeMode: () => setGlobalThemeMode,
|
|
29
|
+
subscribeGlobalDarkMode: () => subscribeGlobalDarkMode,
|
|
30
|
+
toggleGlobalDarkMode: () => toggleGlobalDarkMode
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(darkModeStore_exports);
|
|
33
|
+
var import_react_native = require("react-native");
|
|
34
|
+
var import_theme = require("./theme");
|
|
35
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
36
|
+
function systemPrefersDark() {
|
|
37
|
+
return import_react_native.Appearance.getColorScheme() === "dark";
|
|
38
|
+
}
|
|
39
|
+
function resolveIsDark(m) {
|
|
40
|
+
return m === "system" ? systemPrefersDark() : m === "dark";
|
|
41
|
+
}
|
|
42
|
+
function applyToDom(dark) {
|
|
43
|
+
if (typeof document === "undefined") return;
|
|
44
|
+
const root = document.documentElement;
|
|
45
|
+
const strategy = (0, import_theme.getTheme)().darkMode;
|
|
46
|
+
if (strategy === "class") {
|
|
47
|
+
root.classList.toggle("dark", dark);
|
|
48
|
+
root.classList.toggle("light", !dark);
|
|
49
|
+
} else if (strategy === "attribute") {
|
|
50
|
+
root.setAttribute("data-theme", dark ? "dark" : "light");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
var mode = "system";
|
|
54
|
+
var isDark = resolveIsDark(mode);
|
|
55
|
+
applyToDom(isDark);
|
|
56
|
+
var hasExplicitChoice = false;
|
|
57
|
+
var subscription = import_react_native.Appearance.addChangeListener(({ colorScheme }) => {
|
|
58
|
+
if (mode !== "system") return;
|
|
59
|
+
isDark = colorScheme === "dark";
|
|
60
|
+
applyToDom(isDark);
|
|
61
|
+
notify();
|
|
62
|
+
});
|
|
63
|
+
function notify() {
|
|
64
|
+
for (const listener of listeners) listener();
|
|
65
|
+
}
|
|
66
|
+
function getGlobalDarkMode() {
|
|
67
|
+
return isDark;
|
|
68
|
+
}
|
|
69
|
+
function getGlobalThemeMode() {
|
|
70
|
+
return mode;
|
|
71
|
+
}
|
|
72
|
+
function setGlobalThemeMode(nextMode) {
|
|
73
|
+
mode = nextMode;
|
|
74
|
+
isDark = resolveIsDark(nextMode);
|
|
75
|
+
hasExplicitChoice = true;
|
|
76
|
+
applyToDom(isDark);
|
|
77
|
+
notify();
|
|
78
|
+
}
|
|
79
|
+
function toggleGlobalDarkMode() {
|
|
80
|
+
setGlobalThemeMode(isDark ? "light" : "dark");
|
|
81
|
+
}
|
|
82
|
+
function subscribeGlobalDarkMode(listener) {
|
|
83
|
+
listeners.add(listener);
|
|
84
|
+
return () => listeners.delete(listener);
|
|
85
|
+
}
|
|
86
|
+
function seedDefaultMode(fallback) {
|
|
87
|
+
if (hasExplicitChoice || mode === fallback) return;
|
|
88
|
+
mode = fallback;
|
|
89
|
+
isDark = resolveIsDark(fallback);
|
|
90
|
+
applyToDom(isDark);
|
|
91
|
+
notify();
|
|
92
|
+
}
|
|
93
|
+
function _resetForTests() {
|
|
94
|
+
mode = "system";
|
|
95
|
+
isDark = resolveIsDark(mode);
|
|
96
|
+
hasExplicitChoice = false;
|
|
97
|
+
listeners.clear();
|
|
98
|
+
}
|
|
99
|
+
function _unsubscribeForTests() {
|
|
100
|
+
subscription.remove();
|
|
101
|
+
}
|
|
102
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
103
|
+
0 && (module.exports = {
|
|
104
|
+
_resetForTests,
|
|
105
|
+
_unsubscribeForTests,
|
|
106
|
+
getGlobalDarkMode,
|
|
107
|
+
getGlobalThemeMode,
|
|
108
|
+
seedDefaultMode,
|
|
109
|
+
setGlobalThemeMode,
|
|
110
|
+
subscribeGlobalDarkMode,
|
|
111
|
+
toggleGlobalDarkMode
|
|
112
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform runtime-settable style values — the native counterpart to
|
|
3
|
+
* a real CSS custom property. Real `var(--sidebar-width)` already works on
|
|
4
|
+
* Expo Web today with ZERO code here (raw CSS text, resolved by the
|
|
5
|
+
* browser's own engine — see `jsxRuntimeCoreWeb.ts`, which does no
|
|
6
|
+
* className rewriting at all). Native has no such thing: RN's style system
|
|
7
|
+
* needs an actual JS-computed value at render time, so this module exists
|
|
8
|
+
* to give `var(--x)` an equivalent that works there too — same
|
|
9
|
+
* "module-level store is the real source of truth, no Context required"
|
|
10
|
+
* architecture as `darkModeStore.ts`, and `setDynamicToken` ALSO writes the
|
|
11
|
+
* real CSS custom property to the DOM when one exists (mirroring that
|
|
12
|
+
* file's own `applyToDom`), so a single call updates both platforms
|
|
13
|
+
* identically: instantly via native CSS reactivity on web, via this
|
|
14
|
+
* store's subscribers (see `jsxRuntimeCore.ts`'s `ReactiveElement`, which
|
|
15
|
+
* substitutes a registered token's current value into the className
|
|
16
|
+
* string before every resolve) on native.
|
|
17
|
+
*
|
|
18
|
+
* Deliberately ONE listener set shared by every token, not per-token
|
|
19
|
+
* subscriptions — same trade-off `darkModeStore.ts` already makes for
|
|
20
|
+
* "any relevant change re-renders every subscribed element" simplicity.
|
|
21
|
+
* An unrelated token's change still re-renders every subscribed element
|
|
22
|
+
* (there's no per-token filtering), but `substituteDynamicTokens` in
|
|
23
|
+
* `jsxRuntimeCore.ts` re-reads each token's CURRENT value fresh on every
|
|
24
|
+
* one of those re-renders, so the resolved style stays correct regardless
|
|
25
|
+
* — the redundant re-render is a cheap, accepted trade-off, not a bug.
|
|
26
|
+
*/
|
|
27
|
+
/** `name` is the bare token name, WITHOUT the leading `--` (matching how `getDynamicToken`/`var(--name)` substitution both address it). */
|
|
28
|
+
declare function setDynamicToken(name: string, value: string): void;
|
|
29
|
+
declare function getDynamicToken(name: string): string | undefined;
|
|
30
|
+
declare function deleteDynamicToken(name: string): void;
|
|
31
|
+
declare function subscribeDynamicTokens(listener: () => void): () => void;
|
|
32
|
+
declare function getDynamicTokensVersion(): number;
|
|
33
|
+
/** Exported for tests only — resets every module-level field back to its as-if-just-imported state. */
|
|
34
|
+
declare function _resetForTests(): void;
|
|
35
|
+
|
|
36
|
+
export { _resetForTests, deleteDynamicToken, getDynamicToken, getDynamicTokensVersion, setDynamicToken, subscribeDynamicTokens };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/dynamicTokens.ts
|
|
21
|
+
var dynamicTokens_exports = {};
|
|
22
|
+
__export(dynamicTokens_exports, {
|
|
23
|
+
_resetForTests: () => _resetForTests,
|
|
24
|
+
deleteDynamicToken: () => deleteDynamicToken,
|
|
25
|
+
getDynamicToken: () => getDynamicToken,
|
|
26
|
+
getDynamicTokensVersion: () => getDynamicTokensVersion,
|
|
27
|
+
setDynamicToken: () => setDynamicToken,
|
|
28
|
+
subscribeDynamicTokens: () => subscribeDynamicTokens
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(dynamicTokens_exports);
|
|
31
|
+
var tokens = /* @__PURE__ */ new Map();
|
|
32
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
33
|
+
var version = 0;
|
|
34
|
+
function applyToDom(name, value) {
|
|
35
|
+
if (typeof document === "undefined") return;
|
|
36
|
+
document.documentElement.style.setProperty(`--${name}`, value);
|
|
37
|
+
}
|
|
38
|
+
function notify() {
|
|
39
|
+
version++;
|
|
40
|
+
for (const listener of listeners) listener();
|
|
41
|
+
}
|
|
42
|
+
function setDynamicToken(name, value) {
|
|
43
|
+
tokens.set(name, value);
|
|
44
|
+
applyToDom(name, value);
|
|
45
|
+
notify();
|
|
46
|
+
}
|
|
47
|
+
function getDynamicToken(name) {
|
|
48
|
+
return tokens.get(name);
|
|
49
|
+
}
|
|
50
|
+
function deleteDynamicToken(name) {
|
|
51
|
+
if (!tokens.delete(name)) return;
|
|
52
|
+
if (typeof document !== "undefined") document.documentElement.style.removeProperty(`--${name}`);
|
|
53
|
+
notify();
|
|
54
|
+
}
|
|
55
|
+
function subscribeDynamicTokens(listener) {
|
|
56
|
+
listeners.add(listener);
|
|
57
|
+
return () => listeners.delete(listener);
|
|
58
|
+
}
|
|
59
|
+
function getDynamicTokensVersion() {
|
|
60
|
+
return version;
|
|
61
|
+
}
|
|
62
|
+
function _resetForTests() {
|
|
63
|
+
tokens.clear();
|
|
64
|
+
listeners.clear();
|
|
65
|
+
version = 0;
|
|
66
|
+
}
|
|
67
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
68
|
+
0 && (module.exports = {
|
|
69
|
+
_resetForTests,
|
|
70
|
+
deleteDynamicToken,
|
|
71
|
+
getDynamicToken,
|
|
72
|
+
getDynamicTokensVersion,
|
|
73
|
+
setDynamicToken,
|
|
74
|
+
subscribeDynamicTokens
|
|
75
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
colors: Record<string, string>;
|
|
7
|
-
spacing: Record<string, number>;
|
|
8
|
-
screens: Record<string, number>;
|
|
9
|
-
darkMode: 'attribute' | 'class' | 'media';
|
|
10
|
-
}
|
|
11
|
-
declare const defaultTheme: ThemeConfig;
|
|
12
|
-
declare function setTheme(theme: ThemeConfig): void;
|
|
13
|
-
declare function getTheme(): ThemeConfig;
|
|
1
|
+
export { ColorEntry, ContainerConfig, ThemeConfig, defaultTheme, getTheme, setTheme } from './theme';
|
|
2
|
+
export { C as ColorScale, a as ColorsAPI, K as KbachConfig, T as ThemeProvider, b as ThemeProviderProps, c as ThemeState, d as applyKbachConfig, r as resolveKbachConfig, u as useColors, e as useDynamicToken, f as useTheme } from './useDynamicToken-Dr15c88t.js';
|
|
3
|
+
export { ThemeMode, getGlobalDarkMode, getGlobalThemeMode, setGlobalThemeMode, subscribeGlobalDarkMode, toggleGlobalDarkMode } from './darkModeStore';
|
|
4
|
+
export { deleteDynamicToken, getDynamicToken, setDynamicToken, subscribeDynamicTokens } from './dynamicTokens';
|
|
5
|
+
import 'react';
|
|
14
6
|
|
|
7
|
+
type StyleValue = string | number | {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
};
|
|
15
11
|
interface StyleObject {
|
|
16
|
-
[key: string]:
|
|
12
|
+
[key: string]: StyleValue;
|
|
17
13
|
}
|
|
18
14
|
/**
|
|
19
15
|
* Calls the Rust engine via the KbachModule TurboModule (see
|
|
@@ -32,10 +28,9 @@ interface StyleObject {
|
|
|
32
28
|
* whenever the mode is `'system'` (its own default), so nothing regresses
|
|
33
29
|
* for apps that never touch the override API at all. This function itself
|
|
34
30
|
* has no subscription of its own, so nothing re-renders just because the
|
|
35
|
-
* store's value changed — call `
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* and would miss an explicit override entirely.
|
|
31
|
+
* store's value changed — call `useTheme()` (its `isDark`) somewhere in
|
|
32
|
+
* the tree for that, NOT React Native's own `useColorScheme()`, which only
|
|
33
|
+
* reflects the raw OS setting and would miss an explicit override entirely.
|
|
39
34
|
*
|
|
40
35
|
* Phase 11 originally shipped with live in-place theme switching unverified
|
|
41
36
|
* (a `uiMode` toggle triggered a re-render but `Appearance.getColorScheme()`
|
|
@@ -59,90 +54,46 @@ interface StyleObject {
|
|
|
59
54
|
* `Pressable` ever knows this, so it's passed in directly by the caller
|
|
60
55
|
* (jsx-runtime, from Pressable's own style-function callback) rather than
|
|
61
56
|
* queried here. Defaults to `false` for every other element type.
|
|
62
|
-
*/
|
|
63
|
-
declare function resolveStyle(classString: string, pressed?: boolean): StyleObject;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Native port of @kbach/react's darkModeStore.ts — same architecture (a
|
|
67
|
-
* single module-level store is the real source of truth;
|
|
68
|
-
* ThemeProvider/useTheme are a thin, OPTIONAL wrapper around it; every
|
|
69
|
-
* function here works standalone with no provider mounted anywhere), with
|
|
70
|
-
* two real platform differences from the web version:
|
|
71
57
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* `
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Applied once, on this provider's first mount, but ONLY if nothing has
|
|
112
|
-
* made an explicit mode choice yet (see
|
|
113
|
-
* `darkModeStore.ts::seedDefaultMode`) — an explicit prior choice always
|
|
114
|
-
* wins over a component's own default. Unlike @kbach/react's web
|
|
115
|
-
* version, there's no persisted value to check here — see
|
|
116
|
-
* darkModeStore.ts's own doc comment on why this package doesn't persist
|
|
117
|
-
* the mode across app launches.
|
|
118
|
-
*/
|
|
119
|
-
defaultMode?: ThemeMode;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Native port of @kbach/react's `ThemeProvider` — a thin, OPTIONAL React
|
|
123
|
-
* Context wrapper around `darkModeStore.ts`'s single global store, not the
|
|
124
|
-
* source of truth itself. Because the store is global, MULTIPLE mounted
|
|
125
|
-
* providers share the exact same `mode`/`isDark` state rather than each
|
|
126
|
-
* getting their own scoped value — mounting more than one is very likely a
|
|
127
|
-
* mistake (each fighting over the same state via a different
|
|
128
|
-
* `defaultMode`), so this warns once in dev, matching the web version's
|
|
129
|
-
* identical guard.
|
|
130
|
-
*/
|
|
131
|
-
declare function ThemeProvider({ children, defaultMode }: ThemeProviderProps): react.JSX.Element;
|
|
132
|
-
|
|
133
|
-
interface ThemeContextValue {
|
|
134
|
-
mode: ThemeMode;
|
|
135
|
-
isDark: boolean;
|
|
136
|
-
setMode: (mode: ThemeMode) => void;
|
|
137
|
-
toggle: () => void;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Requires a `<ThemeProvider>` ancestor — throws otherwise, since a
|
|
141
|
-
* component that destructures `{ mode, setMode }` genuinely needs Context
|
|
142
|
-
* (unlike a component that just wants the dark/light boolean, which should
|
|
143
|
-
* reach for `useGlobalDarkMode()` instead and never needs a provider at
|
|
144
|
-
* all).
|
|
58
|
+
* `width` gates `sm:`/`md:`/`lg:`/`xl:`/`2xl:` against the active theme's
|
|
59
|
+
* `screens` scale (resolve_style.rs's `native_modifier_state`) — read fresh
|
|
60
|
+
* from `Dimensions.get('window').width` on every call, the same "no
|
|
61
|
+
* caching, no store" choice `colorScheme`/`pressed` already make, and for
|
|
62
|
+
* the same reason: unlike dark mode there's no explicit-override concept to
|
|
63
|
+
* preserve here (nobody manually overrides their screen width), so a plain
|
|
64
|
+
* synchronous read is enough — no need for the subscribable store
|
|
65
|
+
* darkModeStore.ts is for. As with `colorScheme`, this function has no
|
|
66
|
+
* subscription of its own, so rotating/resizing the window doesn't
|
|
67
|
+
* re-render anything by itself — call RN's own `useWindowDimensions()`
|
|
68
|
+
* somewhere in the tree for that (same role `useColorScheme()` plays for
|
|
69
|
+
* `dark:` in apps/native-sandbox/App.tsx).
|
|
70
|
+
*
|
|
71
|
+
* Falls back to `./jsEngine` (a pure-JS, no-WASM/no-native reimplementation
|
|
72
|
+
* of this same resolution logic — see that directory's own doc comments)
|
|
73
|
+
* when `KbachModule` isn't registered at all — Expo Go, which can never
|
|
74
|
+
* load ANY custom native module (not even Expo's own Modules API), so the
|
|
75
|
+
* TurboModule this file otherwise depends on simply doesn't exist there.
|
|
76
|
+
* `TurboModuleRegistry.get` (not `.getEnforcing`, which throws) is what
|
|
77
|
+
* makes this detectable at all — `get` returns `null`/`undefined` instead.
|
|
78
|
+
* A real dev-client/CLI build always has the module registered, so this
|
|
79
|
+
* fallback only ever activates in Expo Go itself; everywhere else behaves
|
|
80
|
+
* exactly as before. The JS engine covers a strict subset of what the
|
|
81
|
+
* native/WASM engines resolve (see jsEngine/resolveUtilityNative.ts) — an
|
|
82
|
+
* intentional, documented parity gap, not a bug.
|
|
83
|
+
*
|
|
84
|
+
* An arbitrary value that couldn't be resolved to something RN's style
|
|
85
|
+
* system can actually use (an unreduced percentage/viewport-relative
|
|
86
|
+
* `calc()`, a raw `var(...)`, ...) is dropped from the returned style —
|
|
87
|
+
* never passed through as an invalid string — and surfaced via
|
|
88
|
+
* `console.warn` here (dev builds only, mirroring RN's own convention for
|
|
89
|
+
* this kind of non-fatal correctness warning) rather than failing
|
|
90
|
+
* silently. The native/JNI path embeds these under a `"__kbachWarnings"`
|
|
91
|
+
* key in the same JSON `resolve_style_json` already returns (see that
|
|
92
|
+
* function's own doc comment for why — reusing the one JSON round-trip
|
|
93
|
+
* rather than adding a second FFI call); the jsEngine fallback returns
|
|
94
|
+
* them directly via `resolveStyleJsWithWarnings`. Both paths converge here
|
|
95
|
+
* so call sites never need to know which engine actually resolved anything.
|
|
145
96
|
*/
|
|
146
|
-
declare function
|
|
97
|
+
declare function resolveStyle(classString: string, pressed?: boolean): StyleObject;
|
|
147
98
|
|
|
148
|
-
export { type StyleObject,
|
|
99
|
+
export { type StyleObject, resolveStyle };
|