@kbach/react 0.2.2 → 0.2.4
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/dist/index.d.mts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +32 -38
- package/dist/index.mjs +32 -38
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -142,14 +142,29 @@ declare function useTheme(): ThemeContextValue;
|
|
|
142
142
|
|
|
143
143
|
interface ThemeProviderProps {
|
|
144
144
|
children: ReactNode;
|
|
145
|
-
/**
|
|
145
|
+
/** Initial mode. Falls back to persisted value, then 'system'. */
|
|
146
146
|
defaultMode?: ThemeMode;
|
|
147
|
+
/**
|
|
148
|
+
* Explicit color scheme override for native with `defaultMode="system"`.
|
|
149
|
+
*
|
|
150
|
+
* On some Android devices the system scheme is not detected on startup
|
|
151
|
+
* (the `appearanceChanged` event only fires on *changes*, not on launch when
|
|
152
|
+
* the device was already dark). Pass `useColorScheme()` from `react-native`
|
|
153
|
+
* here to guarantee correct detection:
|
|
154
|
+
*
|
|
155
|
+
* ```tsx
|
|
156
|
+
* import { useColorScheme } from 'react-native';
|
|
157
|
+
* const scheme = useColorScheme();
|
|
158
|
+
* <ThemeProvider defaultMode="system" colorScheme={scheme}>…</ThemeProvider>
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
colorScheme?: 'light' | 'dark' | null;
|
|
147
162
|
/** Override the config (useful for per-tree config). Defaults to global getConfig(). */
|
|
148
163
|
config?: FrameworkConfig;
|
|
149
|
-
/** Disable persistence to localStorage
|
|
164
|
+
/** Disable persistence to localStorage */
|
|
150
165
|
disablePersistence?: boolean;
|
|
151
166
|
}
|
|
152
|
-
declare function ThemeProvider({ children, defaultMode, config: configOverride, disablePersistence, }: ThemeProviderProps): React__default.JSX.Element;
|
|
167
|
+
declare function ThemeProvider({ children, defaultMode, colorScheme: colorSchemeProp, config: configOverride, disablePersistence, }: ThemeProviderProps): React__default.JSX.Element;
|
|
153
168
|
|
|
154
169
|
type ToggleVariant = 'button' | 'switch' | 'icon-button';
|
|
155
170
|
interface ThemeToggleProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -142,14 +142,29 @@ declare function useTheme(): ThemeContextValue;
|
|
|
142
142
|
|
|
143
143
|
interface ThemeProviderProps {
|
|
144
144
|
children: ReactNode;
|
|
145
|
-
/**
|
|
145
|
+
/** Initial mode. Falls back to persisted value, then 'system'. */
|
|
146
146
|
defaultMode?: ThemeMode;
|
|
147
|
+
/**
|
|
148
|
+
* Explicit color scheme override for native with `defaultMode="system"`.
|
|
149
|
+
*
|
|
150
|
+
* On some Android devices the system scheme is not detected on startup
|
|
151
|
+
* (the `appearanceChanged` event only fires on *changes*, not on launch when
|
|
152
|
+
* the device was already dark). Pass `useColorScheme()` from `react-native`
|
|
153
|
+
* here to guarantee correct detection:
|
|
154
|
+
*
|
|
155
|
+
* ```tsx
|
|
156
|
+
* import { useColorScheme } from 'react-native';
|
|
157
|
+
* const scheme = useColorScheme();
|
|
158
|
+
* <ThemeProvider defaultMode="system" colorScheme={scheme}>…</ThemeProvider>
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
colorScheme?: 'light' | 'dark' | null;
|
|
147
162
|
/** Override the config (useful for per-tree config). Defaults to global getConfig(). */
|
|
148
163
|
config?: FrameworkConfig;
|
|
149
|
-
/** Disable persistence to localStorage
|
|
164
|
+
/** Disable persistence to localStorage */
|
|
150
165
|
disablePersistence?: boolean;
|
|
151
166
|
}
|
|
152
|
-
declare function ThemeProvider({ children, defaultMode, config: configOverride, disablePersistence, }: ThemeProviderProps): React__default.JSX.Element;
|
|
167
|
+
declare function ThemeProvider({ children, defaultMode, colorScheme: colorSchemeProp, config: configOverride, disablePersistence, }: ThemeProviderProps): React__default.JSX.Element;
|
|
153
168
|
|
|
154
169
|
type ToggleVariant = 'button' | 'switch' | 'icon-button';
|
|
155
170
|
interface ThemeToggleProps {
|
package/dist/index.js
CHANGED
|
@@ -2065,17 +2065,15 @@ function subscribeGlobalDarkMode(callback) {
|
|
|
2065
2065
|
|
|
2066
2066
|
// src/ThemeProvider.tsx
|
|
2067
2067
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
2068
|
-
var
|
|
2068
|
+
var _useColorScheme;
|
|
2069
2069
|
try {
|
|
2070
|
-
({
|
|
2070
|
+
({ useColorScheme: _useColorScheme } = require("react-native"));
|
|
2071
2071
|
} catch {
|
|
2072
2072
|
}
|
|
2073
2073
|
var STORAGE_KEY = "kbach-theme";
|
|
2074
2074
|
function loadPersistedMode() {
|
|
2075
2075
|
try {
|
|
2076
|
-
if (isWeb)
|
|
2077
|
-
return localStorage.getItem(STORAGE_KEY);
|
|
2078
|
-
}
|
|
2076
|
+
if (isWeb) return localStorage.getItem(STORAGE_KEY);
|
|
2079
2077
|
return null;
|
|
2080
2078
|
} catch {
|
|
2081
2079
|
return null;
|
|
@@ -2100,23 +2098,23 @@ function applyWebTheme(resolvedMode, strategy) {
|
|
|
2100
2098
|
function ThemeProvider({
|
|
2101
2099
|
children,
|
|
2102
2100
|
defaultMode = "system",
|
|
2101
|
+
colorScheme: colorSchemeProp,
|
|
2103
2102
|
config: configOverride,
|
|
2104
2103
|
disablePersistence = false
|
|
2105
2104
|
}) {
|
|
2106
2105
|
const [resolvedConfig, setResolvedConfig] = (0, import_react2.useState)(
|
|
2107
2106
|
() => configOverride ? buildConfig(configOverride) : getConfig()
|
|
2108
2107
|
);
|
|
2109
|
-
const
|
|
2108
|
+
const [nativeSchemeFallback, setNativeSchemeFallback] = (0, import_react2.useState)(null);
|
|
2109
|
+
const hookScheme = _useColorScheme?.();
|
|
2110
|
+
const nativeScheme = colorSchemeProp !== void 0 ? colorSchemeProp ?? null : hookScheme ?? nativeSchemeFallback;
|
|
2111
|
+
const [webScheme, setWebScheme] = (0, import_react2.useState)(() => {
|
|
2110
2112
|
if (isWeb && typeof window !== "undefined") {
|
|
2111
2113
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
2112
2114
|
}
|
|
2113
|
-
if (Appearance) {
|
|
2114
|
-
const scheme = Appearance.getColorScheme();
|
|
2115
|
-
return scheme === "dark" ? "dark" : "light";
|
|
2116
|
-
}
|
|
2117
2115
|
return "light";
|
|
2118
|
-
}
|
|
2119
|
-
const
|
|
2116
|
+
});
|
|
2117
|
+
const systemScheme = isWeb ? webScheme : nativeScheme === "dark" ? "dark" : "light";
|
|
2120
2118
|
const [mode, _setMode] = (0, import_react2.useState)(() => {
|
|
2121
2119
|
if (!disablePersistence) {
|
|
2122
2120
|
const persisted = loadPersistedMode();
|
|
@@ -2135,36 +2133,32 @@ function ThemeProvider({
|
|
|
2135
2133
|
const isDark = resolvedMode === "dark";
|
|
2136
2134
|
syncGlobalDarkMode(isDark);
|
|
2137
2135
|
(0, import_react2.useEffect)(() => {
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
const scheme = Appearance.getColorScheme();
|
|
2146
|
-
if (scheme != null) {
|
|
2147
|
-
setSystemSchemeRef.current(scheme === "dark" ? "dark" : "light");
|
|
2136
|
+
if (isWeb) return;
|
|
2137
|
+
try {
|
|
2138
|
+
const { TurboModuleRegistry } = require("react-native");
|
|
2139
|
+
const native = TurboModuleRegistry?.get?.("Appearance");
|
|
2140
|
+
const scheme = native?.getColorScheme?.();
|
|
2141
|
+
if (scheme === "dark" || scheme === "light") {
|
|
2142
|
+
setNativeSchemeFallback(scheme);
|
|
2148
2143
|
}
|
|
2144
|
+
} catch {
|
|
2149
2145
|
}
|
|
2150
2146
|
}, []);
|
|
2151
2147
|
(0, import_react2.useEffect)(() => {
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
}
|
|
2167
|
-
return void 0;
|
|
2148
|
+
applyWebTheme(resolvedMode, resolvedConfig.darkMode);
|
|
2149
|
+
setGlobalDarkMode(isDark);
|
|
2150
|
+
}, [isDark, resolvedMode, resolvedConfig.darkMode]);
|
|
2151
|
+
const setWebSchemeRef = (0, import_react2.useRef)(setWebScheme);
|
|
2152
|
+
setWebSchemeRef.current = setWebScheme;
|
|
2153
|
+
(0, import_react2.useEffect)(() => {
|
|
2154
|
+
if (!isWeb || typeof window === "undefined") return;
|
|
2155
|
+
const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
2156
|
+
if (!mq) return;
|
|
2157
|
+
const handler = (e) => {
|
|
2158
|
+
setWebSchemeRef.current(e.matches ? "dark" : "light");
|
|
2159
|
+
};
|
|
2160
|
+
mq.addEventListener("change", handler);
|
|
2161
|
+
return () => mq.removeEventListener("change", handler);
|
|
2168
2162
|
}, []);
|
|
2169
2163
|
(0, import_react2.useEffect)(() => {
|
|
2170
2164
|
if (configOverride) return;
|
package/dist/index.mjs
CHANGED
|
@@ -39,17 +39,15 @@ import {
|
|
|
39
39
|
useState
|
|
40
40
|
} from "react";
|
|
41
41
|
import { jsx } from "react/jsx-runtime";
|
|
42
|
-
var
|
|
42
|
+
var _useColorScheme;
|
|
43
43
|
try {
|
|
44
|
-
({
|
|
44
|
+
({ useColorScheme: _useColorScheme } = __require("react-native"));
|
|
45
45
|
} catch {
|
|
46
46
|
}
|
|
47
47
|
var STORAGE_KEY = "kbach-theme";
|
|
48
48
|
function loadPersistedMode() {
|
|
49
49
|
try {
|
|
50
|
-
if (isWeb)
|
|
51
|
-
return localStorage.getItem(STORAGE_KEY);
|
|
52
|
-
}
|
|
50
|
+
if (isWeb) return localStorage.getItem(STORAGE_KEY);
|
|
53
51
|
return null;
|
|
54
52
|
} catch {
|
|
55
53
|
return null;
|
|
@@ -74,23 +72,23 @@ function applyWebTheme(resolvedMode, strategy) {
|
|
|
74
72
|
function ThemeProvider({
|
|
75
73
|
children,
|
|
76
74
|
defaultMode = "system",
|
|
75
|
+
colorScheme: colorSchemeProp,
|
|
77
76
|
config: configOverride,
|
|
78
77
|
disablePersistence = false
|
|
79
78
|
}) {
|
|
80
79
|
const [resolvedConfig, setResolvedConfig] = useState(
|
|
81
80
|
() => configOverride ? buildConfig(configOverride) : getConfig()
|
|
82
81
|
);
|
|
83
|
-
const
|
|
82
|
+
const [nativeSchemeFallback, setNativeSchemeFallback] = useState(null);
|
|
83
|
+
const hookScheme = _useColorScheme?.();
|
|
84
|
+
const nativeScheme = colorSchemeProp !== void 0 ? colorSchemeProp ?? null : hookScheme ?? nativeSchemeFallback;
|
|
85
|
+
const [webScheme, setWebScheme] = useState(() => {
|
|
84
86
|
if (isWeb && typeof window !== "undefined") {
|
|
85
87
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
86
88
|
}
|
|
87
|
-
if (Appearance) {
|
|
88
|
-
const scheme = Appearance.getColorScheme();
|
|
89
|
-
return scheme === "dark" ? "dark" : "light";
|
|
90
|
-
}
|
|
91
89
|
return "light";
|
|
92
|
-
}
|
|
93
|
-
const
|
|
90
|
+
});
|
|
91
|
+
const systemScheme = isWeb ? webScheme : nativeScheme === "dark" ? "dark" : "light";
|
|
94
92
|
const [mode, _setMode] = useState(() => {
|
|
95
93
|
if (!disablePersistence) {
|
|
96
94
|
const persisted = loadPersistedMode();
|
|
@@ -109,36 +107,32 @@ function ThemeProvider({
|
|
|
109
107
|
const isDark = resolvedMode === "dark";
|
|
110
108
|
syncGlobalDarkMode(isDark);
|
|
111
109
|
useEffect(() => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const scheme = Appearance.getColorScheme();
|
|
120
|
-
if (scheme != null) {
|
|
121
|
-
setSystemSchemeRef.current(scheme === "dark" ? "dark" : "light");
|
|
110
|
+
if (isWeb) return;
|
|
111
|
+
try {
|
|
112
|
+
const { TurboModuleRegistry } = __require("react-native");
|
|
113
|
+
const native = TurboModuleRegistry?.get?.("Appearance");
|
|
114
|
+
const scheme = native?.getColorScheme?.();
|
|
115
|
+
if (scheme === "dark" || scheme === "light") {
|
|
116
|
+
setNativeSchemeFallback(scheme);
|
|
122
117
|
}
|
|
118
|
+
} catch {
|
|
123
119
|
}
|
|
124
120
|
}, []);
|
|
125
121
|
useEffect(() => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
return void 0;
|
|
122
|
+
applyWebTheme(resolvedMode, resolvedConfig.darkMode);
|
|
123
|
+
setGlobalDarkMode(isDark);
|
|
124
|
+
}, [isDark, resolvedMode, resolvedConfig.darkMode]);
|
|
125
|
+
const setWebSchemeRef = useRef(setWebScheme);
|
|
126
|
+
setWebSchemeRef.current = setWebScheme;
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (!isWeb || typeof window === "undefined") return;
|
|
129
|
+
const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
130
|
+
if (!mq) return;
|
|
131
|
+
const handler = (e) => {
|
|
132
|
+
setWebSchemeRef.current(e.matches ? "dark" : "light");
|
|
133
|
+
};
|
|
134
|
+
mq.addEventListener("change", handler);
|
|
135
|
+
return () => mq.removeEventListener("change", handler);
|
|
142
136
|
}, []);
|
|
143
137
|
useEffect(() => {
|
|
144
138
|
if (configOverride) return;
|