@kbach/react-native 1.0.0-beta.4 → 1.0.0-beta.41
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 +84 -132
- 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-3AY4XSVY.mjs +40 -0
- package/dist/chunk-A3PV4XGK.mjs +564 -0
- package/dist/chunk-YYCSHELO.mjs +112 -0
- package/dist/clsx-BLLSnqAa.d.ts +277 -0
- package/dist/darkModeStore.d.ts +73 -0
- package/dist/darkModeStore.js +118 -0
- package/dist/dynamicTokens.d.ts +36 -0
- package/dist/dynamicTokens.js +75 -0
- package/dist/index.d.ts +11 -156
- package/dist/index.js +2072 -393
- package/dist/index.web.d.ts +15 -4
- package/dist/index.web.js +438 -401
- package/dist/index.web.mjs +268 -14
- package/dist/jsx-dev-runtime.js +2177 -332
- package/dist/jsx-dev-runtime.web.js +206 -361
- package/dist/jsx-dev-runtime.web.mjs +19 -7
- package/dist/jsx-runtime.js +2177 -332
- package/dist/jsx-runtime.web.js +191 -353
- package/dist/jsx-runtime.web.mjs +3 -6
- package/dist/theme.d.ts +54 -0
- package/dist/{chunk-AEVOM2NB.mjs → theme.js} +86 -61
- package/package.json +43 -14
- package/src/babel-plugin.js +144 -2
- package/dist/chunk-4KCCEMEN.mjs +0 -66
- package/dist/chunk-DLIXI5OW.mjs +0 -53
- package/dist/chunk-FG5E4NLJ.mjs +0 -18
- package/dist/chunk-KSDFO34H.mjs +0 -32
- package/dist/chunk-OJQAJLYT.mjs +0 -14
- package/dist/chunk-ZUE6SCTE.mjs +0 -14
- package/dist/index.d.mts +0 -161
- package/dist/index.mjs +0 -32
- package/dist/index.web.d.mts +0 -7
- package/dist/jsx-dev-runtime.d.mts +0 -10
- package/dist/jsx-dev-runtime.mjs +0 -17
- package/dist/jsx-dev-runtime.web.d.mts +0 -10
- package/dist/jsx-runtime.d.mts +0 -7
- package/dist/jsx-runtime.mjs +0 -14
- package/dist/jsx-runtime.web.d.mts +0 -7
package/dist/index.web.mjs
CHANGED
|
@@ -1,32 +1,286 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
useTheme
|
|
5
|
-
} from "./chunk-4KCCEMEN.mjs";
|
|
6
|
-
import {
|
|
7
|
-
resolveStyle
|
|
8
|
-
} from "./chunk-KSDFO34H.mjs";
|
|
9
|
-
import {
|
|
10
|
-
defaultTheme,
|
|
2
|
+
deleteDynamicToken,
|
|
3
|
+
getDynamicToken,
|
|
11
4
|
getGlobalDarkMode,
|
|
12
5
|
getGlobalThemeMode,
|
|
13
|
-
|
|
6
|
+
resyncDomWithActiveTheme,
|
|
7
|
+
seedDefaultMode,
|
|
8
|
+
setDynamicToken,
|
|
14
9
|
setGlobalThemeMode,
|
|
15
|
-
|
|
10
|
+
subscribeDynamicTokens,
|
|
16
11
|
subscribeGlobalDarkMode,
|
|
17
12
|
toggleGlobalDarkMode
|
|
18
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-YYCSHELO.mjs";
|
|
14
|
+
import {
|
|
15
|
+
defaultTheme,
|
|
16
|
+
getTheme,
|
|
17
|
+
resolveClassName,
|
|
18
|
+
setTheme
|
|
19
|
+
} from "./chunk-A3PV4XGK.mjs";
|
|
20
|
+
|
|
21
|
+
// src/config.ts
|
|
22
|
+
function parseHexRgb(hex) {
|
|
23
|
+
const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
24
|
+
if (!m) return null;
|
|
25
|
+
let h = m[1];
|
|
26
|
+
if (h.length === 3) h = h.split("").map((c) => c + c).join("");
|
|
27
|
+
const n = parseInt(h, 16);
|
|
28
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
29
|
+
}
|
|
30
|
+
function applyOpacityToHex(hex, opacityText) {
|
|
31
|
+
const rgb = parseHexRgb(hex);
|
|
32
|
+
if (!rgb) return hex;
|
|
33
|
+
const a = Number(opacityText) / 100;
|
|
34
|
+
const clamped = Number.isFinite(a) ? Math.min(1, Math.max(0, a)) : 1;
|
|
35
|
+
return `rgba(${rgb.join(",")},${clamped})`;
|
|
36
|
+
}
|
|
37
|
+
function resolveColorEntry(value, lookup) {
|
|
38
|
+
const slash = value.indexOf("/");
|
|
39
|
+
const name = slash === -1 ? value : value.slice(0, slash);
|
|
40
|
+
const opacity = slash === -1 ? void 0 : value.slice(slash + 1);
|
|
41
|
+
const base = lookup(name);
|
|
42
|
+
if (base === void 0) return value;
|
|
43
|
+
return opacity === void 0 ? base : applyOpacityToHex(base, opacity);
|
|
44
|
+
}
|
|
45
|
+
function resolveColors(extend, existing) {
|
|
46
|
+
const { dark: darkExtend, ...lightExtend } = extend;
|
|
47
|
+
const resolvedLight = {};
|
|
48
|
+
const lookupLight = (name) => {
|
|
49
|
+
const found = resolvedLight[name] ?? existing[name];
|
|
50
|
+
return typeof found === "string" ? found : void 0;
|
|
51
|
+
};
|
|
52
|
+
for (const [name, value] of Object.entries(lightExtend)) {
|
|
53
|
+
if (typeof value !== "string") continue;
|
|
54
|
+
resolvedLight[name] = resolveColorEntry(value, lookupLight);
|
|
55
|
+
}
|
|
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;
|
|
73
|
+
}
|
|
74
|
+
function resolveKbachConfig(config) {
|
|
75
|
+
let theme = { ...defaultTheme, ...config.theme };
|
|
76
|
+
if (config.extend?.colors) {
|
|
77
|
+
theme = { ...theme, colors: { ...theme.colors, ...resolveColors(config.extend.colors, theme.colors) } };
|
|
78
|
+
}
|
|
79
|
+
if (config.extend?.spacing) {
|
|
80
|
+
theme = { ...theme, spacing: { ...theme.spacing, ...config.extend.spacing } };
|
|
81
|
+
}
|
|
82
|
+
if (config.extend?.screens) {
|
|
83
|
+
theme = { ...theme, screens: { ...theme.screens, ...config.extend.screens } };
|
|
84
|
+
}
|
|
85
|
+
if (config.extend?.fontFamily) {
|
|
86
|
+
theme = { ...theme, fontFamily: { ...theme.fontFamily, ...config.extend.fontFamily } };
|
|
87
|
+
}
|
|
88
|
+
if (config.extend?.container) {
|
|
89
|
+
theme = { ...theme, container: { ...theme.container, ...config.extend.container } };
|
|
90
|
+
}
|
|
91
|
+
if (config.darkMode) {
|
|
92
|
+
theme = { ...theme, darkMode: config.darkMode };
|
|
93
|
+
}
|
|
94
|
+
return theme;
|
|
95
|
+
}
|
|
96
|
+
function applyKbachConfig(config) {
|
|
97
|
+
const theme = resolveKbachConfig(config);
|
|
98
|
+
setTheme(theme);
|
|
99
|
+
resyncDomWithActiveTheme();
|
|
100
|
+
return theme;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/useTheme.ts
|
|
104
|
+
import { useMemo, useSyncExternalStore } from "react";
|
|
105
|
+
function useTheme() {
|
|
106
|
+
const isDark = useSyncExternalStore(subscribeGlobalDarkMode, getGlobalDarkMode);
|
|
107
|
+
const mode = useSyncExternalStore(subscribeGlobalDarkMode, getGlobalThemeMode);
|
|
108
|
+
return useMemo(
|
|
109
|
+
() => ({ mode, isDark, setMode: setGlobalThemeMode, toggle: toggleGlobalDarkMode }),
|
|
110
|
+
[mode, isDark]
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/ThemeProvider.tsx
|
|
115
|
+
import { useEffect, useRef } from "react";
|
|
116
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
117
|
+
var PERSIST_STORAGE_KEY = "kbach-theme";
|
|
118
|
+
function isThemeMode(value) {
|
|
119
|
+
return value === "light" || value === "dark" || value === "system";
|
|
120
|
+
}
|
|
121
|
+
var mountedProviderCount = 0;
|
|
122
|
+
var warnedMultipleProviders = false;
|
|
123
|
+
function ThemeProvider({ children, defaultMode = "system", persist = false }) {
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
mountedProviderCount++;
|
|
126
|
+
if (mountedProviderCount > 1 && !warnedMultipleProviders) {
|
|
127
|
+
warnedMultipleProviders = true;
|
|
128
|
+
console.warn(
|
|
129
|
+
"[Kbach] Multiple <ThemeProvider> instances are mounted at once.\nDark mode is one global store \u2014 useTheme() reads it everywhere, not scoped per provider \u2014 so their defaultMode/persist seeds will fight over the same state.\nMount exactly one <ThemeProvider>, as high in the tree as convenient."
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
return () => {
|
|
133
|
+
mountedProviderCount--;
|
|
134
|
+
};
|
|
135
|
+
}, []);
|
|
136
|
+
const seeded = useRef(false);
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (seeded.current) return;
|
|
139
|
+
seeded.current = true;
|
|
140
|
+
if (!persist) {
|
|
141
|
+
seedDefaultMode(defaultMode);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
let cancelled = false;
|
|
145
|
+
persist.getItem(PERSIST_STORAGE_KEY).then((stored) => {
|
|
146
|
+
if (cancelled) return;
|
|
147
|
+
if (isThemeMode(stored)) seedDefaultMode(stored);
|
|
148
|
+
else seedDefaultMode(defaultMode);
|
|
149
|
+
}).catch(() => {
|
|
150
|
+
if (!cancelled) seedDefaultMode(defaultMode);
|
|
151
|
+
});
|
|
152
|
+
return () => {
|
|
153
|
+
cancelled = true;
|
|
154
|
+
};
|
|
155
|
+
}, []);
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
if (!persist) return;
|
|
158
|
+
return subscribeGlobalDarkMode(() => {
|
|
159
|
+
persist.setItem(PERSIST_STORAGE_KEY, getGlobalThemeMode()).catch(() => {
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}, [persist]);
|
|
163
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/useColors.ts
|
|
167
|
+
import { useMemo as useMemo2 } from "react";
|
|
168
|
+
function parseHexRgb2(hex) {
|
|
169
|
+
const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
170
|
+
if (!m) return null;
|
|
171
|
+
let h = m[1];
|
|
172
|
+
if (h.length === 3) h = h.split("").map((c) => c + c).join("");
|
|
173
|
+
const n = parseInt(h, 16);
|
|
174
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
175
|
+
}
|
|
176
|
+
function applyOpacity(color, opacity) {
|
|
177
|
+
const a = Math.max(0, Math.min(1, opacity / 100));
|
|
178
|
+
if (color.startsWith("#")) {
|
|
179
|
+
const rgb = parseHexRgb2(color);
|
|
180
|
+
return rgb ? `rgba(${rgb.join(",")},${a})` : color;
|
|
181
|
+
}
|
|
182
|
+
if (color.startsWith("rgb(")) return color.replace("rgb(", "rgba(").replace(")", `,${a})`);
|
|
183
|
+
if (color.startsWith("rgba(")) return color.replace(/,\s*[\d.]+\)$/, `,${a})`);
|
|
184
|
+
return color;
|
|
185
|
+
}
|
|
186
|
+
function resolveEntry(entry, isDark) {
|
|
187
|
+
return typeof entry === "string" ? entry : isDark ? entry.dark : entry.light;
|
|
188
|
+
}
|
|
189
|
+
function makeColorsProxy(theme, isDark) {
|
|
190
|
+
const alpha = (color, opacity) => opacity === void 0 ? color : applyOpacity(color, opacity);
|
|
191
|
+
const cache = /* @__PURE__ */ new Map();
|
|
192
|
+
function resolveNamed(key) {
|
|
193
|
+
let name = key;
|
|
194
|
+
let opacity;
|
|
195
|
+
if (key.includes("/")) {
|
|
196
|
+
const slash = key.indexOf("/");
|
|
197
|
+
name = key.slice(0, slash);
|
|
198
|
+
opacity = Number(key.slice(slash + 1));
|
|
199
|
+
}
|
|
200
|
+
const entry = theme.colors[name];
|
|
201
|
+
if (entry === void 0) return void 0;
|
|
202
|
+
const value = resolveEntry(entry, isDark);
|
|
203
|
+
return opacity === void 0 ? value : applyOpacity(value, opacity);
|
|
204
|
+
}
|
|
205
|
+
function makeFamilyProxy(family) {
|
|
206
|
+
return new Proxy({}, {
|
|
207
|
+
get(_, prop) {
|
|
208
|
+
const key = String(prop);
|
|
209
|
+
if (key === "then") return void 0;
|
|
210
|
+
return resolveNamed(`${family}-${key}`);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
const get = (name) => resolveNamed(name) ?? name;
|
|
215
|
+
return new Proxy({ alpha, get }, {
|
|
216
|
+
get(_, prop) {
|
|
217
|
+
const key = String(prop);
|
|
218
|
+
if (key === "then") return void 0;
|
|
219
|
+
if (key === "alpha") return alpha;
|
|
220
|
+
if (key === "get") return get;
|
|
221
|
+
const direct = resolveNamed(key);
|
|
222
|
+
if (direct !== void 0) return direct;
|
|
223
|
+
if (!cache.has(key)) cache.set(key, makeFamilyProxy(key));
|
|
224
|
+
return cache.get(key);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
function useColors() {
|
|
229
|
+
const { isDark } = useTheme();
|
|
230
|
+
const theme = getTheme();
|
|
231
|
+
return useMemo2(() => makeColorsProxy(theme, isDark), [theme, isDark]);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/useDynamicToken.ts
|
|
235
|
+
import { useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
236
|
+
function useDynamicToken(name) {
|
|
237
|
+
return useSyncExternalStore2(subscribeDynamicTokens, () => getDynamicToken(name));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// src/clsx.ts
|
|
241
|
+
function clsx(...inputs) {
|
|
242
|
+
let out = "";
|
|
243
|
+
for (const input of inputs) {
|
|
244
|
+
const piece = resolveClassValue(input);
|
|
245
|
+
if (piece) out = out ? `${out} ${piece}` : piece;
|
|
246
|
+
}
|
|
247
|
+
return out;
|
|
248
|
+
}
|
|
249
|
+
function resolveClassValue(value) {
|
|
250
|
+
if (!value) return "";
|
|
251
|
+
const type = typeof value;
|
|
252
|
+
if (type === "string" || type === "number" || type === "bigint") return String(value);
|
|
253
|
+
if (Array.isArray(value)) return clsx(...value);
|
|
254
|
+
if (type === "object") {
|
|
255
|
+
let out = "";
|
|
256
|
+
for (const key in value) {
|
|
257
|
+
if (Object.prototype.hasOwnProperty.call(value, key) && value[key]) {
|
|
258
|
+
out = out ? `${out} ${key}` : key;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return out;
|
|
262
|
+
}
|
|
263
|
+
return "";
|
|
264
|
+
}
|
|
19
265
|
export {
|
|
20
266
|
ThemeProvider,
|
|
267
|
+
applyKbachConfig,
|
|
268
|
+
clsx,
|
|
21
269
|
defaultTheme,
|
|
270
|
+
deleteDynamicToken,
|
|
271
|
+
getDynamicToken,
|
|
22
272
|
getGlobalDarkMode,
|
|
23
273
|
getGlobalThemeMode,
|
|
24
274
|
getTheme,
|
|
25
|
-
|
|
275
|
+
resolveClassName,
|
|
276
|
+
resolveKbachConfig,
|
|
277
|
+
setDynamicToken,
|
|
26
278
|
setGlobalThemeMode,
|
|
27
279
|
setTheme,
|
|
280
|
+
subscribeDynamicTokens,
|
|
28
281
|
subscribeGlobalDarkMode,
|
|
29
282
|
toggleGlobalDarkMode,
|
|
30
|
-
|
|
283
|
+
useColors,
|
|
284
|
+
useDynamicToken,
|
|
31
285
|
useTheme
|
|
32
286
|
};
|