@oxyhq/bloom 0.6.13 → 0.6.14
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/lib/commonjs/hooks/useControllableState.js +35 -0
- package/lib/commonjs/hooks/useControllableState.js.map +1 -0
- package/lib/commonjs/theme/BloomThemeProvider.js +134 -112
- package/lib/commonjs/theme/BloomThemeProvider.js.map +1 -1
- package/lib/commonjs/theme/build-theme.js +110 -0
- package/lib/commonjs/theme/build-theme.js.map +1 -0
- package/lib/commonjs/theme/color-presets.js +15 -0
- package/lib/commonjs/theme/color-presets.js.map +1 -1
- package/lib/commonjs/theme/index.js +15 -1
- package/lib/commonjs/theme/index.js.map +1 -1
- package/lib/commonjs/theme/persistence.js +127 -0
- package/lib/commonjs/theme/persistence.js.map +1 -0
- package/lib/commonjs/theme/use-isomorphic-layout-effect.js +15 -0
- package/lib/commonjs/theme/use-isomorphic-layout-effect.js.map +1 -0
- package/lib/module/hooks/useControllableState.js +31 -0
- package/lib/module/hooks/useControllableState.js.map +1 -0
- package/lib/module/theme/BloomThemeProvider.js +135 -112
- package/lib/module/theme/BloomThemeProvider.js.map +1 -1
- package/lib/module/theme/build-theme.js +105 -0
- package/lib/module/theme/build-theme.js.map +1 -0
- package/lib/module/theme/color-presets.js +15 -0
- package/lib/module/theme/color-presets.js.map +1 -1
- package/lib/module/theme/index.js +3 -1
- package/lib/module/theme/index.js.map +1 -1
- package/lib/module/theme/persistence.js +120 -0
- package/lib/module/theme/persistence.js.map +1 -0
- package/lib/module/theme/use-isomorphic-layout-effect.js +12 -0
- package/lib/module/theme/use-isomorphic-layout-effect.js.map +1 -0
- package/lib/typescript/commonjs/hooks/useControllableState.d.ts +19 -0
- package/lib/typescript/commonjs/hooks/useControllableState.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/BloomThemeProvider.d.ts +29 -12
- package/lib/typescript/commonjs/theme/BloomThemeProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/build-theme.d.ts +20 -0
- package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-presets.d.ts +18 -3
- package/lib/typescript/commonjs/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/index.d.ts +7 -4
- package/lib/typescript/commonjs/theme/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/persistence.d.ts +48 -0
- package/lib/typescript/commonjs/theme/persistence.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/use-isomorphic-layout-effect.d.ts +8 -0
- package/lib/typescript/commonjs/theme/use-isomorphic-layout-effect.d.ts.map +1 -0
- package/lib/typescript/module/hooks/useControllableState.d.ts +19 -0
- package/lib/typescript/module/hooks/useControllableState.d.ts.map +1 -0
- package/lib/typescript/module/theme/BloomThemeProvider.d.ts +29 -12
- package/lib/typescript/module/theme/BloomThemeProvider.d.ts.map +1 -1
- package/lib/typescript/module/theme/build-theme.d.ts +20 -0
- package/lib/typescript/module/theme/build-theme.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-presets.d.ts +18 -3
- package/lib/typescript/module/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/module/theme/index.d.ts +7 -4
- package/lib/typescript/module/theme/index.d.ts.map +1 -1
- package/lib/typescript/module/theme/persistence.d.ts +48 -0
- package/lib/typescript/module/theme/persistence.d.ts.map +1 -0
- package/lib/typescript/module/theme/use-isomorphic-layout-effect.d.ts +8 -0
- package/lib/typescript/module/theme/use-isomorphic-layout-effect.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/BloomThemeProvider.modes.test.tsx +159 -0
- package/src/__tests__/BloomThemeProvider.persistence.test.tsx +217 -0
- package/src/__tests__/persistence.test.ts +155 -0
- package/src/__tests__/theme.test.ts +1 -1
- package/src/hooks/useControllableState.ts +44 -0
- package/src/theme/BloomThemeProvider.tsx +219 -157
- package/src/theme/build-theme.ts +128 -0
- package/src/theme/color-presets.ts +19 -3
- package/src/theme/index.ts +16 -4
- package/src/theme/persistence.ts +149 -0
- package/src/theme/use-isomorphic-layout-effect.ts +10 -0
|
@@ -33,6 +33,12 @@ Object.defineProperty(exports, "HEX_TO_APP_COLOR", {
|
|
|
33
33
|
return _colorPresets.HEX_TO_APP_COLOR;
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
+
Object.defineProperty(exports, "STATUS_COLORS", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _buildTheme.STATUS_COLORS;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
36
42
|
Object.defineProperty(exports, "applyDarkClass", {
|
|
37
43
|
enumerable: true,
|
|
38
44
|
get: function () {
|
|
@@ -42,7 +48,7 @@ Object.defineProperty(exports, "applyDarkClass", {
|
|
|
42
48
|
Object.defineProperty(exports, "buildTheme", {
|
|
43
49
|
enumerable: true,
|
|
44
50
|
get: function () {
|
|
45
|
-
return
|
|
51
|
+
return _buildTheme.buildTheme;
|
|
46
52
|
}
|
|
47
53
|
});
|
|
48
54
|
Object.defineProperty(exports, "hexToAppColorName", {
|
|
@@ -81,10 +87,18 @@ Object.defineProperty(exports, "useThemeColor", {
|
|
|
81
87
|
return _useTheme.useThemeColor;
|
|
82
88
|
}
|
|
83
89
|
});
|
|
90
|
+
Object.defineProperty(exports, "webLocalStorage", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _persistence.webLocalStorage;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
84
96
|
var _BloomThemeProvider = require("./BloomThemeProvider.js");
|
|
97
|
+
var _buildTheme = require("./build-theme.js");
|
|
85
98
|
var _useTheme = require("./use-theme.js");
|
|
86
99
|
var _colorPresets = require("./color-presets.js");
|
|
87
100
|
var _applyDarkClass = require("./apply-dark-class.js");
|
|
88
101
|
var _setColorSchemeSafe = require("./set-color-scheme-safe.js");
|
|
89
102
|
var _initCssInterop = require("./init-css-interop.js");
|
|
103
|
+
var _persistence = require("./persistence.js");
|
|
90
104
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_BloomThemeProvider","require","_useTheme","_colorPresets","_applyDarkClass","_setColorSchemeSafe","_initCssInterop"],"sourceRoot":"../../../src","sources":["theme/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_BloomThemeProvider","require","_buildTheme","_useTheme","_colorPresets","_applyDarkClass","_setColorSchemeSafe","_initCssInterop","_persistence"],"sourceRoot":"../../../src","sources":["theme/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,mBAAA,GAAAC,OAAA;AAMA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,SAAA,GAAAF,OAAA;AAGA,IAAAG,aAAA,GAAAH,OAAA;AAMA,IAAAI,eAAA,GAAAJ,OAAA;AACA,IAAAK,mBAAA,GAAAL,OAAA;AACA,IAAAM,eAAA,GAAAN,OAAA;AAEA,IAAAO,YAAA,GAAAP,OAAA","ignoreList":[]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.readPersistedTheme = readPersistedTheme;
|
|
7
|
+
exports.readPersistedThemeSync = readPersistedThemeSync;
|
|
8
|
+
exports.webLocalStorage = void 0;
|
|
9
|
+
exports.writePersistedTheme = writePersistedTheme;
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
var _colorPresets = require("./color-presets.js");
|
|
12
|
+
const VALID_PRESETS = new Set(_colorPresets.APP_COLOR_NAMES);
|
|
13
|
+
const VALID_MODES = new Set(['light', 'dark', 'system', 'adaptive']);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Storage adapter for persisting Bloom theme state.
|
|
17
|
+
*
|
|
18
|
+
* Methods may be synchronous or asynchronous. The provider awaits both, so
|
|
19
|
+
* `AsyncStorage`-compatible adapters on native and `localStorage`-backed
|
|
20
|
+
* adapters on web both work without consumer-side branching.
|
|
21
|
+
*
|
|
22
|
+
* On web, a synchronous adapter lets Bloom hydrate before the first paint —
|
|
23
|
+
* preventing a flash of the default palette. On native, the provider can
|
|
24
|
+
* gate `children` rendering until hydration completes (see
|
|
25
|
+
* `awaitHydration` on `BloomThemeProvider`).
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const isValidMode = value => typeof value === 'string' && VALID_MODES.has(value);
|
|
29
|
+
const isValidPreset = value => typeof value === 'string' && VALID_PRESETS.has(value);
|
|
30
|
+
function parsePersistedTheme(raw) {
|
|
31
|
+
if (typeof raw !== 'string') return null;
|
|
32
|
+
let parsed;
|
|
33
|
+
try {
|
|
34
|
+
parsed = JSON.parse(raw);
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
if (!parsed || typeof parsed !== 'object') return null;
|
|
39
|
+
const obj = parsed;
|
|
40
|
+
const mode = isValidMode(obj.mode) ? obj.mode : undefined;
|
|
41
|
+
const colorPreset = isValidPreset(obj.colorPreset) ? obj.colorPreset : undefined;
|
|
42
|
+
if (!mode && !colorPreset) return null;
|
|
43
|
+
return {
|
|
44
|
+
mode,
|
|
45
|
+
colorPreset
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const isThenable = value => !!value && typeof value.then === 'function';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Read persisted state during the first render. Returns a discriminated union
|
|
52
|
+
* so the provider can tell apart:
|
|
53
|
+
* - `none`: persistence not configured.
|
|
54
|
+
* - `sync`: adapter returned a value synchronously (web `localStorage`).
|
|
55
|
+
* Provider can render immediately with the resolved state.
|
|
56
|
+
* - `async`: adapter returned a Promise (native `AsyncStorage`). Provider
|
|
57
|
+
* must await `readPersistedTheme` before painting if gating is enabled.
|
|
58
|
+
*/
|
|
59
|
+
function readPersistedThemeSync(persistKey, storage) {
|
|
60
|
+
if (!persistKey || !storage) return {
|
|
61
|
+
kind: 'none'
|
|
62
|
+
};
|
|
63
|
+
let raw;
|
|
64
|
+
try {
|
|
65
|
+
raw = storage.getItem(persistKey);
|
|
66
|
+
} catch {
|
|
67
|
+
return {
|
|
68
|
+
kind: 'sync',
|
|
69
|
+
state: null
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (isThenable(raw)) return {
|
|
73
|
+
kind: 'async'
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
kind: 'sync',
|
|
77
|
+
state: parsePersistedTheme(raw)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async function readPersistedTheme(persistKey, storage) {
|
|
81
|
+
if (!persistKey || !storage) return null;
|
|
82
|
+
try {
|
|
83
|
+
const raw = await storage.getItem(persistKey);
|
|
84
|
+
return parsePersistedTheme(raw);
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function writePersistedTheme(persistKey, storage, state) {
|
|
90
|
+
if (!persistKey || !storage) return;
|
|
91
|
+
const payload = {};
|
|
92
|
+
if (state.mode !== undefined) payload.mode = state.mode;
|
|
93
|
+
if (state.colorPreset !== undefined) payload.colorPreset = state.colorPreset;
|
|
94
|
+
try {
|
|
95
|
+
await storage.setItem(persistKey, JSON.stringify(payload));
|
|
96
|
+
} catch {
|
|
97
|
+
// Persistence is best-effort: ignore quota and privacy-mode errors.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* `localStorage`-backed storage adapter. Only defined on web; on native the
|
|
103
|
+
* export is `undefined` so consumers pass an `AsyncStorage` adapter explicitly.
|
|
104
|
+
*/
|
|
105
|
+
const webLocalStorage = exports.webLocalStorage = (() => {
|
|
106
|
+
if (_reactNative.Platform.OS !== 'web') return undefined;
|
|
107
|
+
if (typeof globalThis === 'undefined') return undefined;
|
|
108
|
+
if (!('localStorage' in globalThis)) return undefined;
|
|
109
|
+
const ls = globalThis.localStorage;
|
|
110
|
+
return {
|
|
111
|
+
getItem: key => {
|
|
112
|
+
try {
|
|
113
|
+
return ls.getItem(key);
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
setItem: (key, value) => {
|
|
119
|
+
try {
|
|
120
|
+
ls.setItem(key, value);
|
|
121
|
+
} catch {
|
|
122
|
+
// Swallow quota / privacy-mode errors.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
})();
|
|
127
|
+
//# sourceMappingURL=persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_colorPresets","VALID_PRESETS","Set","APP_COLOR_NAMES","VALID_MODES","isValidMode","value","has","isValidPreset","parsePersistedTheme","raw","parsed","JSON","parse","obj","mode","undefined","colorPreset","isThenable","then","readPersistedThemeSync","persistKey","storage","kind","getItem","state","readPersistedTheme","writePersistedTheme","payload","setItem","stringify","webLocalStorage","exports","Platform","OS","globalThis","ls","localStorage","key"],"sourceRoot":"../../../src","sources":["theme/persistence.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useIsomorphicLayoutEffect = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
/**
|
|
10
|
+
* `useLayoutEffect` on web (and native — react-native polyfills it) but falls
|
|
11
|
+
* back to `useEffect` during SSR to avoid the React warning. Bloom apps are
|
|
12
|
+
* primarily Expo (no SSR), but Next.js consumers of the web bundle need this.
|
|
13
|
+
*/
|
|
14
|
+
const useIsomorphicLayoutEffect = exports.useIsomorphicLayoutEffect = _reactNative.Platform.OS === 'web' && typeof document === 'undefined' ? _react.useEffect : _react.useLayoutEffect;
|
|
15
|
+
//# sourceMappingURL=use-isomorphic-layout-effect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","useIsomorphicLayoutEffect","exports","Platform","OS","document","useEffect","useLayoutEffect"],"sourceRoot":"../../../src","sources":["theme/use-isomorphic-layout-effect.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA;AACA;AACA;AACA;AACA;AACO,MAAME,yBAAyB,GAAAC,OAAA,CAAAD,yBAAA,GACpCE,qBAAQ,CAACC,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,GAAGC,gBAAS,GAAGC,sBAAe","ignoreList":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useRef, useState } from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Canonical Radix/shadcn-style controllable state hook. Returns a tuple of the
|
|
6
|
+
* current value and a setter that:
|
|
7
|
+
* - updates internal state when uncontrolled, and
|
|
8
|
+
* - always calls `onChange` (so controlled parents stay in sync).
|
|
9
|
+
*
|
|
10
|
+
* Switching between controlled and uncontrolled at runtime is supported but
|
|
11
|
+
* discouraged; the hook keeps the latest `value` for reads either way.
|
|
12
|
+
*/
|
|
13
|
+
export function useControllableState({
|
|
14
|
+
value,
|
|
15
|
+
defaultValue,
|
|
16
|
+
onChange
|
|
17
|
+
}) {
|
|
18
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
19
|
+
const isControlled = value !== undefined;
|
|
20
|
+
const current = isControlled ? value : internal;
|
|
21
|
+
const onChangeRef = useRef(onChange);
|
|
22
|
+
onChangeRef.current = onChange;
|
|
23
|
+
const setValue = useCallback(next => {
|
|
24
|
+
if (!isControlled) {
|
|
25
|
+
setInternal(next);
|
|
26
|
+
}
|
|
27
|
+
onChangeRef.current?.(next);
|
|
28
|
+
}, [isControlled]);
|
|
29
|
+
return [current, setValue];
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=useControllableState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useRef","useState","useControllableState","value","defaultValue","onChange","internal","setInternal","isControlled","undefined","current","onChangeRef","setValue","next"],"sourceRoot":"../../../src","sources":["hooks/useControllableState.ts"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAWrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAAI;EACtCC,KAAK;EACLC,YAAY;EACZC;AAC8B,CAAC,EAA0B;EACzD,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGN,QAAQ,CAAIG,YAAY,CAAC;EACzD,MAAMI,YAAY,GAAGL,KAAK,KAAKM,SAAS;EACxC,MAAMC,OAAO,GAAGF,YAAY,GAAIL,KAAK,GAASG,QAAQ;EAEtD,MAAMK,WAAW,GAAGX,MAAM,CAACK,QAAQ,CAAC;EACpCM,WAAW,CAACD,OAAO,GAAGL,QAAQ;EAE9B,MAAMO,QAAQ,GAAGb,WAAW,CACzBc,IAAO,IAAK;IACX,IAAI,CAACL,YAAY,EAAE;MACjBD,WAAW,CAACM,IAAI,CAAC;IACnB;IACAF,WAAW,CAACD,OAAO,GAAGG,IAAI,CAAC;EAC7B,CAAC,EACD,CAACL,YAAY,CACf,CAAC;EAED,OAAO,CAACE,OAAO,EAAEE,QAAQ,CAAC;AAC5B","ignoreList":[]}
|
|
@@ -5,153 +5,176 @@
|
|
|
5
5
|
// throw "Cannot manually set color scheme, as dark mode is type 'media'" the
|
|
6
6
|
// first time Bloom toggles the dark class on <html>. See ./init-css-interop.
|
|
7
7
|
import "./init-css-interop.js";
|
|
8
|
-
import React, { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';
|
|
9
|
-
import { useColorScheme as useRNColorScheme
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
8
|
+
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
9
|
+
import { useColorScheme as useRNColorScheme } from 'react-native';
|
|
10
|
+
import { useControllableState } from "../hooks/useControllableState.js";
|
|
11
|
+
import { FontLoader } from '../fonts/FontLoader';
|
|
12
12
|
import { applyDarkClass, applyColorPresetVars } from "./apply-dark-class.js";
|
|
13
|
+
import { buildTheme } from "./build-theme.js";
|
|
14
|
+
import { readPersistedTheme, readPersistedThemeSync, writePersistedTheme } from "./persistence.js";
|
|
13
15
|
import { setColorSchemeSafe } from "./set-color-scheme-safe.js";
|
|
14
|
-
import {
|
|
16
|
+
import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect.js";
|
|
15
17
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
const DEFAULT_PRESET = 'oxy';
|
|
19
|
+
const DEFAULT_MODE = 'system';
|
|
20
|
+
export const BloomThemeContext = /*#__PURE__*/createContext(null);
|
|
21
|
+
function useThemeState({
|
|
22
|
+
controlledMode,
|
|
23
|
+
controlledPreset,
|
|
24
|
+
defaultMode,
|
|
25
|
+
defaultPreset,
|
|
26
|
+
persistKey,
|
|
27
|
+
storage,
|
|
28
|
+
onModeChange,
|
|
29
|
+
onColorPresetChange
|
|
30
|
+
}) {
|
|
31
|
+
// Synchronous read happens once on first render. Succeeds on web with
|
|
32
|
+
// localStorage-backed adapters; async adapters rehydrate via the effect
|
|
33
|
+
// below. Lazy-initialized via `useState` so it runs exactly once per mount.
|
|
34
|
+
const [syncResult] = useState(() => readPersistedThemeSync(persistKey, storage));
|
|
35
|
+
const syncState = syncResult.kind === 'sync' ? syncResult.state : null;
|
|
36
|
+
const initialMode = syncState?.mode ?? defaultMode;
|
|
37
|
+
const initialPreset = syncState?.colorPreset ?? defaultPreset;
|
|
38
|
+
|
|
39
|
+
// Hydrated immediately when persistence is off or the adapter resolved
|
|
40
|
+
// synchronously (including a null hit — that's a valid "no value" answer).
|
|
41
|
+
const [hydrated, setHydrated] = useState(syncResult.kind !== 'async');
|
|
42
|
+
const [mode, setModeInternal] = useControllableState({
|
|
43
|
+
value: controlledMode,
|
|
44
|
+
defaultValue: initialMode
|
|
45
|
+
});
|
|
46
|
+
const [colorPreset, setPresetInternal] = useControllableState({
|
|
47
|
+
value: controlledPreset,
|
|
48
|
+
defaultValue: initialPreset
|
|
49
|
+
});
|
|
30
50
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
// Refs let setMode/setColorPreset stay referentially stable. Callbacks
|
|
52
|
+
// memoized only by setters and storage identity won't churn the context
|
|
53
|
+
// value on every theme change.
|
|
54
|
+
const modeRef = useRef(mode);
|
|
55
|
+
modeRef.current = mode;
|
|
56
|
+
const presetRef = useRef(colorPreset);
|
|
57
|
+
presetRef.current = colorPreset;
|
|
58
|
+
|
|
59
|
+
// Async hydration for adapters that can't be read synchronously
|
|
60
|
+
// (AsyncStorage, MMKV via JSI fallback, etc).
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (hydrated) return;
|
|
63
|
+
if (!persistKey || !storage) {
|
|
64
|
+
setHydrated(true);
|
|
65
|
+
return;
|
|
39
66
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
text: hslVarToCSS(vars['--foreground'] ?? '0 0% 100%'),
|
|
56
|
-
textSecondary: mutedForeground,
|
|
57
|
-
textTertiary: mutedForeground,
|
|
58
|
-
border: hslVarToCSS(vars['--border'] ?? '0 0% 20%'),
|
|
59
|
-
borderLight: hslVarToCSS(vars['--input'] ?? '0 0% 20%'),
|
|
60
|
-
primary: primaryColor,
|
|
61
|
-
primaryForeground,
|
|
62
|
-
primaryLight: surface,
|
|
63
|
-
primaryDark: background,
|
|
64
|
-
secondary: primaryColor,
|
|
65
|
-
tint: primaryColor,
|
|
66
|
-
icon: mutedForeground,
|
|
67
|
-
iconActive: primaryColor,
|
|
68
|
-
success: '#10B981',
|
|
69
|
-
error: '#EF4444',
|
|
70
|
-
warning: '#F59E0B',
|
|
71
|
-
info: '#3B82F6',
|
|
72
|
-
primarySubtle: isDark ? hsl(primaryHue, 50, 10) : hsl(primaryHue, 70, 93),
|
|
73
|
-
primarySubtleForeground: isDark ? hsl(primaryHue, 70, 65) : hsl(primaryHue, 90, 25),
|
|
74
|
-
negative: hsl(destructiveHue, 84, 45),
|
|
75
|
-
negativeForeground: '#FFFFFF',
|
|
76
|
-
negativeSubtle: isDark ? hsl(destructiveHue, 50, 10) : hsl(destructiveHue, 90, 95),
|
|
77
|
-
negativeSubtleForeground: isDark ? hsl(destructiveHue, 70, 65) : hsl(destructiveHue, 80, 40),
|
|
78
|
-
contrast50: isDark ? hsl(primaryHue, 15, 12) : hsl(primaryHue, 10, 93),
|
|
79
|
-
card: surface,
|
|
80
|
-
shadow: isDark ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.1)',
|
|
81
|
-
overlay: 'rgba(0, 0, 0, 0.5)'
|
|
67
|
+
let cancelled = false;
|
|
68
|
+
readPersistedTheme(persistKey, storage).then(state => {
|
|
69
|
+
if (cancelled) return;
|
|
70
|
+
if (state?.mode && controlledMode === undefined) {
|
|
71
|
+
setModeInternal(state.mode);
|
|
72
|
+
onModeChange?.(state.mode);
|
|
73
|
+
}
|
|
74
|
+
if (state?.colorPreset && controlledPreset === undefined) {
|
|
75
|
+
setPresetInternal(state.colorPreset);
|
|
76
|
+
onColorPresetChange?.(state.colorPreset);
|
|
77
|
+
}
|
|
78
|
+
setHydrated(true);
|
|
79
|
+
});
|
|
80
|
+
return () => {
|
|
81
|
+
cancelled = true;
|
|
82
82
|
};
|
|
83
|
-
|
|
83
|
+
// Hydration runs once per storage instance. controlledMode/Preset are
|
|
84
|
+
// captured by closure intentionally — switching controlled-ness mid-flight
|
|
85
|
+
// is unsupported and would invalidate the in-flight hydration anyway.
|
|
86
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
87
|
+
}, [persistKey, storage]);
|
|
88
|
+
const setMode = useCallback(next => {
|
|
89
|
+
setModeInternal(next);
|
|
90
|
+
onModeChange?.(next);
|
|
91
|
+
void writePersistedTheme(persistKey, storage, {
|
|
92
|
+
mode: next,
|
|
93
|
+
colorPreset: presetRef.current
|
|
94
|
+
});
|
|
95
|
+
}, [setModeInternal, onModeChange, persistKey, storage]);
|
|
96
|
+
const setColorPreset = useCallback(next => {
|
|
97
|
+
setPresetInternal(next);
|
|
98
|
+
onColorPresetChange?.(next);
|
|
99
|
+
void writePersistedTheme(persistKey, storage, {
|
|
100
|
+
mode: modeRef.current,
|
|
101
|
+
colorPreset: next
|
|
102
|
+
});
|
|
103
|
+
}, [setPresetInternal, onColorPresetChange, persistKey, storage]);
|
|
84
104
|
return {
|
|
85
|
-
mode
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
105
|
+
mode,
|
|
106
|
+
colorPreset,
|
|
107
|
+
setMode,
|
|
108
|
+
setColorPreset,
|
|
109
|
+
hydrated
|
|
89
110
|
};
|
|
90
111
|
}
|
|
91
|
-
export const BloomThemeContext = /*#__PURE__*/createContext(null);
|
|
92
112
|
export function BloomThemeProvider({
|
|
93
113
|
mode: controlledMode,
|
|
94
114
|
colorPreset: controlledPreset,
|
|
115
|
+
defaultMode = DEFAULT_MODE,
|
|
116
|
+
defaultColorPreset = DEFAULT_PRESET,
|
|
95
117
|
onModeChange,
|
|
96
118
|
onColorPresetChange,
|
|
119
|
+
persistKey,
|
|
120
|
+
storage,
|
|
121
|
+
awaitHydration,
|
|
122
|
+
onHydrating,
|
|
97
123
|
fonts = true,
|
|
98
124
|
onFontsLoading,
|
|
99
125
|
children
|
|
100
126
|
}) {
|
|
101
127
|
const rnScheme = useRNColorScheme();
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
128
|
+
const {
|
|
129
|
+
mode,
|
|
130
|
+
colorPreset,
|
|
131
|
+
setMode,
|
|
132
|
+
setColorPreset,
|
|
133
|
+
hydrated
|
|
134
|
+
} = useThemeState({
|
|
135
|
+
controlledMode,
|
|
136
|
+
controlledPreset,
|
|
137
|
+
defaultMode,
|
|
138
|
+
defaultPreset: defaultColorPreset,
|
|
139
|
+
persistKey,
|
|
140
|
+
storage,
|
|
141
|
+
onModeChange,
|
|
142
|
+
onColorPresetChange
|
|
143
|
+
});
|
|
108
144
|
const isAdaptive = mode === 'adaptive';
|
|
109
145
|
const effectiveMode = isAdaptive ? 'system' : mode;
|
|
110
146
|
const resolved = effectiveMode === 'system' ? rnScheme === 'dark' ? 'dark' : 'light' : effectiveMode;
|
|
111
147
|
|
|
112
|
-
// Apply native color scheme and CSS vars
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
const lastApplied = useRef('');
|
|
117
|
-
const applyKey = `${resolved}:${appColor}`;
|
|
118
|
-
if (lastApplied.current !== applyKey) {
|
|
119
|
-
lastApplied.current = applyKey;
|
|
148
|
+
// Apply native color scheme, dark class, and CSS vars whenever the resolved
|
|
149
|
+
// mode or preset changes. `useIsomorphicLayoutEffect` runs before paint on
|
|
150
|
+
// both native and web, eliminating the previous render-time side effect.
|
|
151
|
+
useIsomorphicLayoutEffect(() => {
|
|
120
152
|
setColorSchemeSafe(effectiveMode);
|
|
121
153
|
applyDarkClass(resolved);
|
|
122
|
-
applyColorPresetVars(
|
|
123
|
-
}
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
const theme = buildTheme(appColor, resolved, isAdaptive);
|
|
134
|
-
return {
|
|
135
|
-
theme,
|
|
136
|
-
mode,
|
|
137
|
-
colorPreset: appColor,
|
|
138
|
-
setMode,
|
|
139
|
-
setColorPreset
|
|
140
|
-
};
|
|
141
|
-
}, [resolved, appColor, isAdaptive, mode, setMode, setColorPreset]);
|
|
154
|
+
applyColorPresetVars(colorPreset, resolved);
|
|
155
|
+
}, [effectiveMode, resolved, colorPreset]);
|
|
156
|
+
const contextValue = useMemo(() => ({
|
|
157
|
+
theme: buildTheme(colorPreset, resolved, isAdaptive),
|
|
158
|
+
mode,
|
|
159
|
+
colorPreset,
|
|
160
|
+
setMode,
|
|
161
|
+
setColorPreset
|
|
162
|
+
}), [colorPreset, resolved, isAdaptive, mode, setMode, setColorPreset]);
|
|
163
|
+
const shouldAwait = awaitHydration ?? Boolean(persistKey && storage);
|
|
164
|
+
const isGated = shouldAwait && !hydrated;
|
|
142
165
|
return /*#__PURE__*/_jsx(BloomThemeContext.Provider, {
|
|
143
166
|
value: contextValue,
|
|
144
167
|
children: /*#__PURE__*/_jsx(FontLoader, {
|
|
145
168
|
enabled: fonts,
|
|
146
169
|
fallback: onFontsLoading,
|
|
147
|
-
children: children
|
|
170
|
+
children: isGated ? onHydrating ?? null : children
|
|
148
171
|
})
|
|
149
172
|
});
|
|
150
173
|
}
|
|
151
174
|
|
|
152
175
|
/**
|
|
153
|
-
* Scoped color override for a subtree.
|
|
154
|
-
*
|
|
176
|
+
* Scoped color override for a subtree. Inherits the resolved mode from the
|
|
177
|
+
* parent `BloomThemeProvider` but renders descendants with a different preset.
|
|
155
178
|
*/
|
|
156
179
|
|
|
157
180
|
export function BloomColorScope({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","createContext","useCallback","useContext","useMemo","useRef","useState","useColorScheme","useRNColorScheme","
|
|
1
|
+
{"version":3,"names":["React","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","useColorScheme","useRNColorScheme","useControllableState","FontLoader","applyDarkClass","applyColorPresetVars","buildTheme","readPersistedTheme","readPersistedThemeSync","writePersistedTheme","setColorSchemeSafe","useIsomorphicLayoutEffect","jsx","_jsx","DEFAULT_PRESET","DEFAULT_MODE","BloomThemeContext","useThemeState","controlledMode","controlledPreset","defaultMode","defaultPreset","persistKey","storage","onModeChange","onColorPresetChange","syncResult","syncState","kind","state","initialMode","mode","initialPreset","colorPreset","hydrated","setHydrated","setModeInternal","value","defaultValue","setPresetInternal","modeRef","current","presetRef","cancelled","then","undefined","setMode","next","setColorPreset","BloomThemeProvider","defaultColorPreset","awaitHydration","onHydrating","fonts","onFontsLoading","children","rnScheme","isAdaptive","effectiveMode","resolved","contextValue","theme","shouldAwait","Boolean","isGated","Provider","enabled","fallback","BloomColorScope","parent","Error"],"sourceRoot":"../../../src","sources":["theme/BloomThemeProvider.tsx"],"mappings":"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","ignoreList":[]}
|