@mrmeg/expo-ui 0.2.0 → 0.3.0

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.
@@ -11,3 +11,4 @@ export declare function resolveThemePreference(userTheme: ThemePreference, syste
11
11
  export declare const useThemeStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ThemeStore>>;
12
12
  export declare function syncSystemTheme(): void;
13
13
  export declare function startSystemThemeListener(): () => void;
14
+ export declare function syncThemeFromEnvironment(): () => void;
@@ -13,7 +13,9 @@ function getSystemTheme() {
13
13
  }
14
14
  export const useThemeStore = create((set) => ({
15
15
  userTheme: "system",
16
- systemTheme: getSystemTheme(),
16
+ // Always start with "light" so SSR and the first client render agree.
17
+ // Real values are populated by `syncThemeFromEnvironment()` after mount.
18
+ systemTheme: "light",
17
19
  setTheme: (theme) => {
18
20
  set({
19
21
  userTheme: theme,
@@ -89,6 +91,18 @@ export function startSystemThemeListener() {
89
91
  };
90
92
  return stopSystemThemeListener;
91
93
  }
92
- // Load saved theme on store creation
93
- useThemeStore.getState().loadTheme();
94
- startSystemThemeListener();
94
+ // Single entry point for host apps to populate the store from the
95
+ // environment (persisted preference + OS color scheme listener). Safe to
96
+ // call multiple times — `startSystemThemeListener` is idempotent — and
97
+ // returns the unsubscribe so it can be used directly inside `useEffect`.
98
+ export function syncThemeFromEnvironment() {
99
+ useThemeStore.getState().loadTheme();
100
+ return startSystemThemeListener();
101
+ }
102
+ // Native has no SSR mismatch concern, so keep the historical auto-init
103
+ // behavior there. On web the host app must call `syncThemeFromEnvironment()`
104
+ // from a top-level `useEffect` to avoid hydration mismatches.
105
+ if (Platform.OS !== "web") {
106
+ useThemeStore.getState().loadTheme();
107
+ startSystemThemeListener();
108
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrmeg/expo-ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "description": "Reusable Expo and React Native UI primitives for MrMeg projects.",
6
6
  "keywords": [