@kbach/ui 0.1.0-beta.0 → 0.1.0-beta.1
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/KBACH.md +4 -5
- package/README.md +35 -303
- package/dist/{chunk-UE54W6ZG.mjs → chunk-KHTZ244V.mjs} +1 -1
- package/dist/{chunk-BPCFICND.mjs → chunk-VBK6ORYJ.mjs} +41 -9
- package/dist/core/index.d.ts +55 -16
- package/dist/core/index.js +35 -9
- package/dist/index.d.ts +5 -11
- package/dist/index.js +103 -94
- package/dist/index.mjs +14 -4
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.mjs +2 -2
- package/dist/native.js +0 -21
- package/dist/native.mjs +49 -0
- package/dist/vite-plugin.js +28 -4
- package/dist/vite-plugin.mjs +28 -4
- package/kbach-ui.md +2 -2
- package/package.json +3 -2
- package/scripts/postinstall.js +17 -0
- package/dist/native.d.ts +0 -314
package/dist/core/index.d.ts
CHANGED
|
@@ -188,6 +188,43 @@ interface ResolvedConfig {
|
|
|
188
188
|
plugins: Array<(api: PluginAPI) => void>;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* Returns a value that's the SAME object across every physical copy of core/
|
|
193
|
+
* a bundler might produce for a single running process — not just across
|
|
194
|
+
* dist/index.js / dist/jsx-runtime.js / dist/jsx-dev-runtime.js (the CJS
|
|
195
|
+
* build, which already shares one real dist/core/index.js via
|
|
196
|
+
* externalization — see tsup.config.ts's CORE_EXTERNAL), but ALSO across
|
|
197
|
+
* that CJS build and the separate ESM build (dist/index.mjs etc., which
|
|
198
|
+
* inlines its own copy of core/ — a deliberate, accepted trade-off for
|
|
199
|
+
* Rollup/Vite compatibility, see context.tsx's ThemeContext comment for the
|
|
200
|
+
* full story).
|
|
201
|
+
*
|
|
202
|
+
* Confirmed as a real, live bug (not just theoretical), back when ThemeProvider
|
|
203
|
+
* still had a separate native-specific wrapper at the now-removed
|
|
204
|
+
* '@kbach/ui/native' subpath (see native/index.ts): a React Native app that
|
|
205
|
+
* reached @kbach/ui through more than one physical dist file — e.g.
|
|
206
|
+
* `import { ThemeProvider } from '@kbach/ui/native'` in one file and
|
|
207
|
+
* `import { useIsDark } from '@kbach/ui'` in another, which Metro can resolve
|
|
208
|
+
* to DIFFERENT dist files per call site — got dark:/light: classes silently
|
|
209
|
+
* inert from one instance while useIsDark() read a different,
|
|
210
|
+
* correctly-updating instance (or vice versa), depending on which module
|
|
211
|
+
* each half of the app happened to load through. ThemeProvider now auto-
|
|
212
|
+
* detects native itself (no separate wrapper/import path to diverge on), but
|
|
213
|
+
* the underlying dual-build split (ESM for Rollup/Vite, CJS for Metro) is
|
|
214
|
+
* still real, so darkModeStore/responsiveStore/config/etc. still need this —
|
|
215
|
+
* jsx-runtime.tsx, for instance, still reaches core/ as its own call site.
|
|
216
|
+
* See RULES.md rule 3: this is exactly the "globalThis-singleton hack" it
|
|
217
|
+
* allows when a real fix (one guaranteed physical module) isn't available —
|
|
218
|
+
* which it isn't here, short of giving up either Rollup or Metro compatibility
|
|
219
|
+
* entirely.
|
|
220
|
+
*
|
|
221
|
+
* Keyed on Symbol.for() (the well-known global symbol registry, shared
|
|
222
|
+
* across realms/module copies by spec) rather than a plain string property,
|
|
223
|
+
* so this can never collide with anything else that happens to touch
|
|
224
|
+
* globalThis.
|
|
225
|
+
*/
|
|
226
|
+
declare function getGlobalSingleton<T>(key: string, create: () => T): T;
|
|
227
|
+
|
|
191
228
|
/**
|
|
192
229
|
* True for a mode-aware color pair (`{ light, dark }`), as opposed to a plain
|
|
193
230
|
* hex/rgb/alias string. Shared by config.ts (alias-chain resolution),
|
|
@@ -1271,14 +1308,17 @@ declare function initConfig(userConfig: FrameworkConfig): void;
|
|
|
1271
1308
|
* synchronously during render without needing context. ThemeProvider writes to it;
|
|
1272
1309
|
* DarkWrapper / InteractiveWrapper subscribe via useSyncExternalStore.
|
|
1273
1310
|
*
|
|
1274
|
-
*
|
|
1275
|
-
*
|
|
1276
|
-
*
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1281
|
-
*
|
|
1311
|
+
* Backed by getGlobalSingleton() (globalThis-keyed), not a plain module-level
|
|
1312
|
+
* variable — core/ being built as its own shared dist/core/ entry (see
|
|
1313
|
+
* tsup.config.ts's CORE_EXTERNAL) only guarantees one instance across the CJS
|
|
1314
|
+
* build (dist/index.js, dist/jsx-runtime.js, dist/jsx-dev-runtime.js). The
|
|
1315
|
+
* separate ESM build (dist/index.mjs etc., required for Rollup/Vite — see
|
|
1316
|
+
* context.tsx's ThemeContext comment) inlines its own copy, and Metro can
|
|
1317
|
+
* route different call sites in the same app through either one. Confirmed
|
|
1318
|
+
* as a real bug this way: dark:/light: classes went completely inert (while
|
|
1319
|
+
* useIsDark() kept reading correctly) in an app mixing
|
|
1320
|
+
* `import ... from '@kbach/ui/native'` and `import ... from '@kbach/ui'`
|
|
1321
|
+
* — the two ended up on different physical copies of this store.
|
|
1282
1322
|
*/
|
|
1283
1323
|
/**
|
|
1284
1324
|
* Silently update isDark without notifying subscribers.
|
|
@@ -1308,13 +1348,12 @@ declare function subscribeGlobalDarkMode(callback: () => void): () => void;
|
|
|
1308
1348
|
/**
|
|
1309
1349
|
* Global responsive width store.
|
|
1310
1350
|
*
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1317
|
-
* this module to begin with — a plain module-level object is enough.
|
|
1351
|
+
* Backed by getGlobalSingleton() (globalThis-keyed) — see
|
|
1352
|
+
* darkModeStore.ts's header comment for why a plain module-level object
|
|
1353
|
+
* isn't enough: core/ being its own shared dist/core/ entry only covers the
|
|
1354
|
+
* CJS build (dist/index.js, dist/jsx-runtime.js, dist/jsx-dev-runtime.js);
|
|
1355
|
+
* the separate ESM build inlines its own copy, and Metro can route
|
|
1356
|
+
* different call sites in the same app through either one.
|
|
1318
1357
|
*/
|
|
1319
1358
|
type WidthListener = () => void;
|
|
1320
1359
|
/** Synchronous write for use in the render phase. */
|
|
@@ -1343,4 +1382,4 @@ declare function subscribeGlobalWidth(listener: WidthListener): () => void;
|
|
|
1343
1382
|
*/
|
|
1344
1383
|
declare function getActiveBreakpoints(width?: number, screens?: Record<string, number>): Set<string>;
|
|
1345
1384
|
|
|
1346
|
-
export { BASE_RESET, type ColorShades, type ColorValue, type DarkMode, type DefaultColorName, type DefaultSpacingKey, type FrameworkConfig, LRUCache, type ParsedClass, type Platform, type PluginAPI, RESET_STYLE_ID, type ResolvedConfig, type ResolvedStyle, type StyleValue, type ThemeColors, type ThemeConfig, type ThemeMode, type ThemeSpacing, buildConfig, clearCache, clearPluginModifiers, defaultColors, defaultTheme, disableRuntimeCSS, escapeCSSSelector, expandModeAwareColorClasses, flatten, generateClassCSS, generateKbachTypesDts, getActiveBreakpoints, getAllModifierNames, getBuiltinStandaloneNames, getBuiltinUtilityPrefixes, getConfig, getDefaultFontFamily, getEffectiveIsWeb, getGlobalDarkMode, getGlobalScreens, getGlobalWidth, getInteractiveModifiers, getModeModifiers, getModifier, getResponsiveModifiers, initConfig, isKnownModifier, isKnownUtility, isModeAwareColor, isNative, isRuntimeCSSDisabled, isWeb, kbachWarn, matchModifier, normalizeClassString, onConfigChange, parseClass, parseClasses, parseHexRgb, registerModifier, resetConfig, resolve, resolveColor, resolveSizing, resolveSpacing, resolveUtility, setDefaultFontFamily, setGlobalDarkMode, setGlobalWidth, setResolveTarget, splitClassTokens, subscribeGlobalDarkMode, subscribeGlobalWidth, syncGlobalDarkMode, syncGlobalScreens, syncGlobalWidth, toNativeValue, updateConfig };
|
|
1385
|
+
export { BASE_RESET, type ColorShades, type ColorValue, type DarkMode, type DefaultColorName, type DefaultSpacingKey, type FrameworkConfig, LRUCache, type ParsedClass, type Platform, type PluginAPI, RESET_STYLE_ID, type ResolvedConfig, type ResolvedStyle, type StyleValue, type ThemeColors, type ThemeConfig, type ThemeMode, type ThemeSpacing, buildConfig, clearCache, clearPluginModifiers, defaultColors, defaultTheme, disableRuntimeCSS, escapeCSSSelector, expandModeAwareColorClasses, flatten, generateClassCSS, generateKbachTypesDts, getActiveBreakpoints, getAllModifierNames, getBuiltinStandaloneNames, getBuiltinUtilityPrefixes, getConfig, getDefaultFontFamily, getEffectiveIsWeb, getGlobalDarkMode, getGlobalScreens, getGlobalSingleton, getGlobalWidth, getInteractiveModifiers, getModeModifiers, getModifier, getResponsiveModifiers, initConfig, isKnownModifier, isKnownUtility, isModeAwareColor, isNative, isRuntimeCSSDisabled, isWeb, kbachWarn, matchModifier, normalizeClassString, onConfigChange, parseClass, parseClasses, parseHexRgb, registerModifier, resetConfig, resolve, resolveColor, resolveSizing, resolveSpacing, resolveUtility, setDefaultFontFamily, setGlobalDarkMode, setGlobalWidth, setResolveTarget, splitClassTokens, subscribeGlobalDarkMode, subscribeGlobalWidth, syncGlobalDarkMode, syncGlobalScreens, syncGlobalWidth, toNativeValue, updateConfig };
|
package/dist/core/index.js
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
getEffectiveIsWeb: () => getEffectiveIsWeb,
|
|
44
44
|
getGlobalDarkMode: () => getGlobalDarkMode,
|
|
45
45
|
getGlobalScreens: () => getGlobalScreens,
|
|
46
|
+
getGlobalSingleton: () => getGlobalSingleton,
|
|
46
47
|
getGlobalWidth: () => getGlobalWidth,
|
|
47
48
|
getInteractiveModifiers: () => getInteractiveModifiers,
|
|
48
49
|
getModeModifiers: () => getModeModifiers,
|
|
@@ -84,6 +85,18 @@ __export(index_exports, {
|
|
|
84
85
|
});
|
|
85
86
|
module.exports = __toCommonJS(index_exports);
|
|
86
87
|
|
|
88
|
+
// src/core/globalSingleton.ts
|
|
89
|
+
function getGlobalSingleton(key, create) {
|
|
90
|
+
const symbolKey = /* @__PURE__ */ Symbol.for(`__kbach_${key}__`);
|
|
91
|
+
const g = globalThis;
|
|
92
|
+
let value = g[symbolKey];
|
|
93
|
+
if (value === void 0) {
|
|
94
|
+
value = create();
|
|
95
|
+
g[symbolKey] = value;
|
|
96
|
+
}
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
|
|
87
100
|
// src/core/colorValue.ts
|
|
88
101
|
function isModeAwareColor(v) {
|
|
89
102
|
return typeof v === "object" && v !== null && "light" in v && "dark" in v;
|
|
@@ -2989,7 +3002,12 @@ var BASE_RESET = [
|
|
|
2989
3002
|
].join("\n");
|
|
2990
3003
|
|
|
2991
3004
|
// src/core/responsiveStore.ts
|
|
2992
|
-
var store =
|
|
3005
|
+
var store = getGlobalSingleton("responsiveStore", () => ({
|
|
3006
|
+
width: 0,
|
|
3007
|
+
notifiedWidth: 0,
|
|
3008
|
+
screens: {},
|
|
3009
|
+
listeners: /* @__PURE__ */ new Set()
|
|
3010
|
+
}));
|
|
2993
3011
|
function syncGlobalWidth(width) {
|
|
2994
3012
|
store.width = width;
|
|
2995
3013
|
}
|
|
@@ -3047,12 +3065,12 @@ function getSortedEntries(resolved) {
|
|
|
3047
3065
|
}
|
|
3048
3066
|
return sorted;
|
|
3049
3067
|
}
|
|
3050
|
-
var
|
|
3068
|
+
var _fontFamilyHolder = getGlobalSingleton("defaultFontFamily", () => ({ value: void 0 }));
|
|
3051
3069
|
function setDefaultFontFamily(font) {
|
|
3052
|
-
|
|
3070
|
+
_fontFamilyHolder.value = font;
|
|
3053
3071
|
}
|
|
3054
3072
|
function getDefaultFontFamily() {
|
|
3055
|
-
return
|
|
3073
|
+
return _fontFamilyHolder.value;
|
|
3056
3074
|
}
|
|
3057
3075
|
var _styleEl = null;
|
|
3058
3076
|
var _ruleIndexByKey = /* @__PURE__ */ new Map();
|
|
@@ -3085,12 +3103,12 @@ function evictInjectedRule(rule) {
|
|
|
3085
3103
|
}
|
|
3086
3104
|
}
|
|
3087
3105
|
var _injectedRules = new LRUCache(5e4, evictInjectedRule);
|
|
3088
|
-
var
|
|
3106
|
+
var _runtimeCSSHolder = getGlobalSingleton("runtimeCSSDisabled", () => ({ value: false }));
|
|
3089
3107
|
function disableRuntimeCSS() {
|
|
3090
|
-
|
|
3108
|
+
_runtimeCSSHolder.value = true;
|
|
3091
3109
|
}
|
|
3092
3110
|
function isRuntimeCSSDisabled() {
|
|
3093
|
-
return
|
|
3111
|
+
return _runtimeCSSHolder.value;
|
|
3094
3112
|
}
|
|
3095
3113
|
function getStyleEl() {
|
|
3096
3114
|
if (_styleEl) return _styleEl;
|
|
@@ -3460,7 +3478,10 @@ function deepMerge(base, override) {
|
|
|
3460
3478
|
}
|
|
3461
3479
|
return result;
|
|
3462
3480
|
}
|
|
3463
|
-
var configStore =
|
|
3481
|
+
var configStore = getGlobalSingleton("configStore", () => ({
|
|
3482
|
+
resolved: null,
|
|
3483
|
+
listeners: /* @__PURE__ */ new Set()
|
|
3484
|
+
}));
|
|
3464
3485
|
function getConfig() {
|
|
3465
3486
|
if (configStore.resolved) return configStore.resolved;
|
|
3466
3487
|
configStore.resolved = buildConfig({});
|
|
@@ -3629,7 +3650,11 @@ function initConfig(userConfig) {
|
|
|
3629
3650
|
}
|
|
3630
3651
|
|
|
3631
3652
|
// src/core/darkModeStore.ts
|
|
3632
|
-
var store2 =
|
|
3653
|
+
var store2 = getGlobalSingleton("darkModeStore", () => ({
|
|
3654
|
+
isDark: false,
|
|
3655
|
+
notifiedIsDark: false,
|
|
3656
|
+
subscribers: /* @__PURE__ */ new Set()
|
|
3657
|
+
}));
|
|
3633
3658
|
function syncGlobalDarkMode(isDark) {
|
|
3634
3659
|
store2.isDark = isDark;
|
|
3635
3660
|
}
|
|
@@ -3671,6 +3696,7 @@ function subscribeGlobalDarkMode(callback) {
|
|
|
3671
3696
|
getEffectiveIsWeb,
|
|
3672
3697
|
getGlobalDarkMode,
|
|
3673
3698
|
getGlobalScreens,
|
|
3699
|
+
getGlobalSingleton,
|
|
3674
3700
|
getGlobalWidth,
|
|
3675
3701
|
getInteractiveModifiers,
|
|
3676
3702
|
getModeModifiers,
|
package/dist/index.d.ts
CHANGED
|
@@ -19,9 +19,6 @@ interface ThemeContextValue {
|
|
|
19
19
|
/** The fully resolved framework config (theme values, darkMode strategy, etc.) */
|
|
20
20
|
config: ResolvedConfig;
|
|
21
21
|
}
|
|
22
|
-
declare global {
|
|
23
|
-
var __kbachThemeContext: Context<ThemeContextValue | null> | undefined;
|
|
24
|
-
}
|
|
25
22
|
declare const ThemeContext: Context<ThemeContextValue | null>;
|
|
26
23
|
declare function useTheme(): ThemeContextValue;
|
|
27
24
|
declare function useIsDark(): boolean;
|
|
@@ -136,22 +133,19 @@ interface ThemeProviderProps {
|
|
|
136
133
|
/**
|
|
137
134
|
* System color scheme for native `defaultMode="system"`.
|
|
138
135
|
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
136
|
+
* On React Native this is detected automatically via `useColorScheme()` —
|
|
137
|
+
* pass this prop only to override that (e.g. in tests, or Storybook).
|
|
141
138
|
*
|
|
142
139
|
* @example
|
|
143
140
|
* ```tsx
|
|
144
|
-
*
|
|
145
|
-
* const colorScheme = useColorScheme();
|
|
146
|
-
* <ThemeProvider defaultMode="system" colorScheme={colorScheme}>…</ThemeProvider>
|
|
141
|
+
* <ThemeProvider defaultMode="system" colorScheme="dark">…</ThemeProvider>
|
|
147
142
|
* ```
|
|
148
143
|
*/
|
|
149
144
|
colorScheme?: 'light' | 'dark' | null;
|
|
150
145
|
/**
|
|
151
146
|
* Current window/screen width in pixels for responsive breakpoints.
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* automatically from `useWindowDimensions()`.
|
|
147
|
+
* Detected automatically on both web (`window.innerWidth`) and React
|
|
148
|
+
* Native (`useWindowDimensions()`) — pass this prop only to override that.
|
|
155
149
|
*/
|
|
156
150
|
windowWidth?: number;
|
|
157
151
|
/** Override the config (useful for per-tree config). Defaults to global getConfig(). */
|