@kbach/react-native 1.0.0-beta.14 → 1.0.0-beta.16

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveClassName
3
- } from "./chunk-ZB2UU6EO.mjs";
3
+ } from "./chunk-3ED4FIO2.mjs";
4
4
 
5
5
  // src/jsxRuntimeCoreWeb.ts
6
6
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getTheme
3
- } from "./chunk-HK6PDJJK.mjs";
3
+ } from "./chunk-3ED4FIO2.mjs";
4
4
 
5
5
  // src/darkModeStore.ts
6
6
  import { Appearance } from "react-native";
@@ -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
+ });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export { C as ColorEntry, a as ColorScale, b as ColorsAPI, c as ContainerConfig, K as KbachConfig, T as ThemeConfig, d as ThemeMode, e as ThemeProvider, f as ThemeProviderProps, g as ThemeState, h as applyKbachConfig, i as defaultTheme, j as getGlobalDarkMode, k as getGlobalThemeMode, l as getTheme, r as resolveKbachConfig, s as setGlobalThemeMode, m as setTheme, n as subscribeGlobalDarkMode, t as toggleGlobalDarkMode, u as useColors, o as useTheme } from './useColors-C6jyCLuG.js';
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 useTheme } from './useColors-Br8QhIlE.js';
3
+ export { ThemeMode, getGlobalDarkMode, getGlobalThemeMode, setGlobalThemeMode, subscribeGlobalDarkMode, toggleGlobalDarkMode } from './darkModeStore';
2
4
  import 'react';
3
5
 
4
6
  type StyleValue = string | number | {