@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,210 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deleteDynamicToken,
|
|
3
|
+
getDynamicToken,
|
|
4
|
+
getGlobalDarkMode,
|
|
5
|
+
getGlobalThemeMode,
|
|
6
|
+
seedDefaultMode,
|
|
7
|
+
setDynamicToken,
|
|
8
|
+
setGlobalThemeMode,
|
|
9
|
+
subscribeDynamicTokens,
|
|
10
|
+
subscribeGlobalDarkMode,
|
|
11
|
+
toggleGlobalDarkMode
|
|
12
|
+
} from "./chunk-TS2EEVOE.mjs";
|
|
13
|
+
import {
|
|
14
|
+
defaultTheme,
|
|
15
|
+
getTheme,
|
|
16
|
+
resolveClassName,
|
|
17
|
+
setTheme
|
|
18
|
+
} from "./chunk-AG7ZQ2K4.mjs";
|
|
19
|
+
|
|
20
|
+
// src/config.ts
|
|
21
|
+
function parseHexRgb(hex) {
|
|
22
|
+
const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
23
|
+
if (!m) return null;
|
|
24
|
+
let h = m[1];
|
|
25
|
+
if (h.length === 3) h = h.split("").map((c) => c + c).join("");
|
|
26
|
+
const n = parseInt(h, 16);
|
|
27
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
28
|
+
}
|
|
29
|
+
function applyOpacityToHex(hex, opacityText) {
|
|
30
|
+
const rgb = parseHexRgb(hex);
|
|
31
|
+
if (!rgb) return hex;
|
|
32
|
+
const a = Number(opacityText) / 100;
|
|
33
|
+
const clamped = Number.isFinite(a) ? Math.min(1, Math.max(0, a)) : 1;
|
|
34
|
+
return `rgba(${rgb.join(",")},${clamped})`;
|
|
35
|
+
}
|
|
36
|
+
function resolveColorEntry(value, lookup) {
|
|
37
|
+
const slash = value.indexOf("/");
|
|
38
|
+
const name = slash === -1 ? value : value.slice(0, slash);
|
|
39
|
+
const opacity = slash === -1 ? void 0 : value.slice(slash + 1);
|
|
40
|
+
const base = lookup(name);
|
|
41
|
+
if (base === void 0) return value;
|
|
42
|
+
return opacity === void 0 ? base : applyOpacityToHex(base, opacity);
|
|
43
|
+
}
|
|
44
|
+
function resolveColors(extend, existing) {
|
|
45
|
+
const resolved = {};
|
|
46
|
+
const lookup = (name) => {
|
|
47
|
+
const found = resolved[name] ?? existing[name];
|
|
48
|
+
return typeof found === "string" ? found : void 0;
|
|
49
|
+
};
|
|
50
|
+
for (const [name, value] of Object.entries(extend)) {
|
|
51
|
+
resolved[name] = resolveColorEntry(value, lookup);
|
|
52
|
+
}
|
|
53
|
+
return resolved;
|
|
54
|
+
}
|
|
55
|
+
function resolveKbachConfig(config) {
|
|
56
|
+
let theme = { ...defaultTheme, ...config.theme };
|
|
57
|
+
if (config.extend?.colors) {
|
|
58
|
+
theme = { ...theme, colors: { ...theme.colors, ...resolveColors(config.extend.colors, theme.colors) } };
|
|
59
|
+
}
|
|
60
|
+
if (config.extend?.spacing) {
|
|
61
|
+
theme = { ...theme, spacing: { ...theme.spacing, ...config.extend.spacing } };
|
|
62
|
+
}
|
|
63
|
+
if (config.extend?.screens) {
|
|
64
|
+
theme = { ...theme, screens: { ...theme.screens, ...config.extend.screens } };
|
|
65
|
+
}
|
|
66
|
+
if (config.extend?.fontFamily) {
|
|
67
|
+
theme = { ...theme, fontFamily: { ...theme.fontFamily, ...config.extend.fontFamily } };
|
|
68
|
+
}
|
|
69
|
+
if (config.extend?.container) {
|
|
70
|
+
theme = { ...theme, container: { ...theme.container, ...config.extend.container } };
|
|
71
|
+
}
|
|
72
|
+
if (config.darkMode) {
|
|
73
|
+
theme = { ...theme, darkMode: config.darkMode };
|
|
74
|
+
}
|
|
75
|
+
return theme;
|
|
76
|
+
}
|
|
77
|
+
function applyKbachConfig(config) {
|
|
78
|
+
const theme = resolveKbachConfig(config);
|
|
79
|
+
setTheme(theme);
|
|
80
|
+
return theme;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/useTheme.ts
|
|
84
|
+
import { useMemo, useSyncExternalStore } from "react";
|
|
85
|
+
function useTheme() {
|
|
86
|
+
const isDark = useSyncExternalStore(subscribeGlobalDarkMode, getGlobalDarkMode);
|
|
87
|
+
const mode = useSyncExternalStore(subscribeGlobalDarkMode, getGlobalThemeMode);
|
|
88
|
+
return useMemo(
|
|
89
|
+
() => ({ mode, isDark, setMode: setGlobalThemeMode, toggle: toggleGlobalDarkMode }),
|
|
90
|
+
[mode, isDark]
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/ThemeProvider.tsx
|
|
95
|
+
import { useEffect, useRef } from "react";
|
|
96
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
97
|
+
var mountedProviderCount = 0;
|
|
98
|
+
var warnedMultipleProviders = false;
|
|
99
|
+
function ThemeProvider({ children, defaultMode = "system" }) {
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
mountedProviderCount++;
|
|
102
|
+
if (mountedProviderCount > 1 && !warnedMultipleProviders) {
|
|
103
|
+
warnedMultipleProviders = true;
|
|
104
|
+
console.warn(
|
|
105
|
+
"[kbach] Multiple <ThemeProvider> instances are mounted at once. Dark-mode state is one global store useTheme() reads everywhere, not scoped per-provider, so their defaultMode seeds will fight over the same state."
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
return () => {
|
|
109
|
+
mountedProviderCount--;
|
|
110
|
+
};
|
|
111
|
+
}, []);
|
|
112
|
+
const seeded = useRef(false);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (seeded.current) return;
|
|
115
|
+
seeded.current = true;
|
|
116
|
+
seedDefaultMode(defaultMode);
|
|
117
|
+
}, []);
|
|
118
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/useColors.ts
|
|
122
|
+
function parseHexRgb2(hex) {
|
|
123
|
+
const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
124
|
+
if (!m) return null;
|
|
125
|
+
let h = m[1];
|
|
126
|
+
if (h.length === 3) h = h.split("").map((c) => c + c).join("");
|
|
127
|
+
const n = parseInt(h, 16);
|
|
128
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
129
|
+
}
|
|
130
|
+
function applyOpacity(color, opacity) {
|
|
131
|
+
const a = Math.max(0, Math.min(1, opacity / 100));
|
|
132
|
+
if (color.startsWith("#")) {
|
|
133
|
+
const rgb = parseHexRgb2(color);
|
|
134
|
+
return rgb ? `rgba(${rgb.join(",")},${a})` : color;
|
|
135
|
+
}
|
|
136
|
+
if (color.startsWith("rgb(")) return color.replace("rgb(", "rgba(").replace(")", `,${a})`);
|
|
137
|
+
if (color.startsWith("rgba(")) return color.replace(/,\s*[\d.]+\)$/, `,${a})`);
|
|
138
|
+
return color;
|
|
139
|
+
}
|
|
140
|
+
function resolveEntry(entry, isDark) {
|
|
141
|
+
return typeof entry === "string" ? entry : isDark ? entry.dark : entry.light;
|
|
142
|
+
}
|
|
143
|
+
function makeColorsProxy(theme, isDark) {
|
|
144
|
+
const alpha = (color, opacity) => opacity === void 0 ? color : applyOpacity(color, opacity);
|
|
145
|
+
const cache = /* @__PURE__ */ new Map();
|
|
146
|
+
function resolveNamed(key) {
|
|
147
|
+
let name = key;
|
|
148
|
+
let opacity;
|
|
149
|
+
if (key.includes("/")) {
|
|
150
|
+
const slash = key.indexOf("/");
|
|
151
|
+
name = key.slice(0, slash);
|
|
152
|
+
opacity = Number(key.slice(slash + 1));
|
|
153
|
+
}
|
|
154
|
+
const entry = theme.colors[name];
|
|
155
|
+
if (entry === void 0) return void 0;
|
|
156
|
+
const value = resolveEntry(entry, isDark);
|
|
157
|
+
return opacity === void 0 ? value : applyOpacity(value, opacity);
|
|
158
|
+
}
|
|
159
|
+
function makeFamilyProxy(family) {
|
|
160
|
+
return new Proxy({}, {
|
|
161
|
+
get(_, prop) {
|
|
162
|
+
const key = String(prop);
|
|
163
|
+
if (key === "then") return void 0;
|
|
164
|
+
return resolveNamed(`${family}-${key}`);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return new Proxy({ alpha }, {
|
|
169
|
+
get(_, prop) {
|
|
170
|
+
const key = String(prop);
|
|
171
|
+
if (key === "then") return void 0;
|
|
172
|
+
if (key === "alpha") return alpha;
|
|
173
|
+
const direct = resolveNamed(key);
|
|
174
|
+
if (direct !== void 0) return direct;
|
|
175
|
+
if (!cache.has(key)) cache.set(key, makeFamilyProxy(key));
|
|
176
|
+
return cache.get(key);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function useColors() {
|
|
181
|
+
const { isDark } = useTheme();
|
|
182
|
+
return makeColorsProxy(getTheme(), isDark);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/useDynamicToken.ts
|
|
186
|
+
import { useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
187
|
+
function useDynamicToken(name) {
|
|
188
|
+
return useSyncExternalStore2(subscribeDynamicTokens, () => getDynamicToken(name));
|
|
189
|
+
}
|
|
190
|
+
export {
|
|
191
|
+
ThemeProvider,
|
|
192
|
+
applyKbachConfig,
|
|
193
|
+
defaultTheme,
|
|
194
|
+
deleteDynamicToken,
|
|
195
|
+
getDynamicToken,
|
|
196
|
+
getGlobalDarkMode,
|
|
197
|
+
getGlobalThemeMode,
|
|
198
|
+
getTheme,
|
|
199
|
+
resolveClassName,
|
|
200
|
+
resolveKbachConfig,
|
|
201
|
+
setDynamicToken,
|
|
202
|
+
setGlobalThemeMode,
|
|
203
|
+
setTheme,
|
|
204
|
+
subscribeDynamicTokens,
|
|
205
|
+
subscribeGlobalDarkMode,
|
|
206
|
+
toggleGlobalDarkMode,
|
|
207
|
+
useColors,
|
|
208
|
+
useDynamicToken,
|
|
209
|
+
useTheme
|
|
210
|
+
};
|
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
export { Fragment } from 'react';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
* @kbach/react-native/jsx-dev-runtime
|
|
6
|
-
*
|
|
7
|
-
* Development variant — Metro calls jsxDEV instead of jsx/jsxs in dev
|
|
8
|
-
* builds. Same pattern as @kbach/react/jsx-dev-runtime (Phase 3): reuses
|
|
9
|
-
* jsx/jsxs for the actual interception, then patches _source/_self onto
|
|
10
|
-
* the result so React DevTools shows the original file/line.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
declare function jsxDEV(type: unknown, props: Record<string, unknown> | null, key?: string, isStaticChildren?: boolean, source?: {
|
|
4
|
+
declare const jsxDEV: (type: unknown, props: Record<string, unknown> | null, key?: string, isStaticChildren?: boolean, source?: {
|
|
14
5
|
fileName: string;
|
|
15
6
|
lineNumber: number;
|
|
16
7
|
columnNumber: number;
|
|
17
|
-
}, self?: unknown)
|
|
8
|
+
}, self?: unknown) => react.ReactElement;
|
|
18
9
|
|
|
19
10
|
export { jsxDEV };
|