@oxyhq/bloom 0.6.12 → 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/apply-dark-class.js +6 -1
- package/lib/commonjs/theme/apply-dark-class.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/apply-dark-class.js +6 -1
- package/lib/module/theme/apply-dark-class.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/apply-dark-class.d.ts +5 -0
- package/lib/typescript/commonjs/theme/apply-dark-class.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/apply-dark-class.d.ts +5 -0
- package/lib/typescript/module/theme/apply-dark-class.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/apply-dark-class.ts +6 -1
- 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
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useControllableState = useControllableState;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
/**
|
|
9
|
+
* Canonical Radix/shadcn-style controllable state hook. Returns a tuple of the
|
|
10
|
+
* current value and a setter that:
|
|
11
|
+
* - updates internal state when uncontrolled, and
|
|
12
|
+
* - always calls `onChange` (so controlled parents stay in sync).
|
|
13
|
+
*
|
|
14
|
+
* Switching between controlled and uncontrolled at runtime is supported but
|
|
15
|
+
* discouraged; the hook keeps the latest `value` for reads either way.
|
|
16
|
+
*/
|
|
17
|
+
function useControllableState({
|
|
18
|
+
value,
|
|
19
|
+
defaultValue,
|
|
20
|
+
onChange
|
|
21
|
+
}) {
|
|
22
|
+
const [internal, setInternal] = (0, _react.useState)(defaultValue);
|
|
23
|
+
const isControlled = value !== undefined;
|
|
24
|
+
const current = isControlled ? value : internal;
|
|
25
|
+
const onChangeRef = (0, _react.useRef)(onChange);
|
|
26
|
+
onChangeRef.current = onChange;
|
|
27
|
+
const setValue = (0, _react.useCallback)(next => {
|
|
28
|
+
if (!isControlled) {
|
|
29
|
+
setInternal(next);
|
|
30
|
+
}
|
|
31
|
+
onChangeRef.current?.(next);
|
|
32
|
+
}, [isControlled]);
|
|
33
|
+
return [current, setValue];
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=useControllableState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","useControllableState","value","defaultValue","onChange","internal","setInternal","useState","isControlled","undefined","current","onChangeRef","useRef","setValue","useCallback","next"],"sourceRoot":"../../../src","sources":["hooks/useControllableState.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,oBAAoBA,CAAI;EACtCC,KAAK;EACLC,YAAY;EACZC;AAC8B,CAAC,EAA0B;EACzD,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAG,IAAAC,eAAQ,EAAIJ,YAAY,CAAC;EACzD,MAAMK,YAAY,GAAGN,KAAK,KAAKO,SAAS;EACxC,MAAMC,OAAO,GAAGF,YAAY,GAAIN,KAAK,GAASG,QAAQ;EAEtD,MAAMM,WAAW,GAAG,IAAAC,aAAM,EAACR,QAAQ,CAAC;EACpCO,WAAW,CAACD,OAAO,GAAGN,QAAQ;EAE9B,MAAMS,QAAQ,GAAG,IAAAC,kBAAW,EACzBC,IAAO,IAAK;IACX,IAAI,CAACP,YAAY,EAAE;MACjBF,WAAW,CAACS,IAAI,CAAC;IACnB;IACAJ,WAAW,CAACD,OAAO,GAAGK,IAAI,CAAC;EAC7B,CAAC,EACD,CAACP,YAAY,CACf,CAAC;EAED,OAAO,CAACE,OAAO,EAAEG,QAAQ,CAAC;AAC5B","ignoreList":[]}
|
|
@@ -6,15 +6,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.BloomColorScope = BloomColorScope;
|
|
7
7
|
exports.BloomThemeContext = void 0;
|
|
8
8
|
exports.BloomThemeProvider = BloomThemeProvider;
|
|
9
|
-
exports.buildTheme = buildTheme;
|
|
10
9
|
require("./init-css-interop.js");
|
|
11
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
12
11
|
var _reactNative = require("react-native");
|
|
13
|
-
var
|
|
14
|
-
var
|
|
12
|
+
var _useControllableState = require("../hooks/useControllableState.js");
|
|
13
|
+
var _FontLoader = require("../fonts/FontLoader");
|
|
15
14
|
var _applyDarkClass = require("./apply-dark-class.js");
|
|
15
|
+
var _buildTheme = require("./build-theme.js");
|
|
16
|
+
var _persistence = require("./persistence.js");
|
|
16
17
|
var _setColorSchemeSafe = require("./set-color-scheme-safe.js");
|
|
17
|
-
var
|
|
18
|
+
var _useIsomorphicLayoutEffect = require("./use-isomorphic-layout-effect.js");
|
|
18
19
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
19
20
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
20
21
|
// Side-effect import — must come first. Initializes react-native-css-interop's
|
|
@@ -22,145 +23,166 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
22
23
|
// throw "Cannot manually set color scheme, as dark mode is type 'media'" the
|
|
23
24
|
// first time Bloom toggles the dark class on <html>. See ./init-css-interop.
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
const DEFAULT_PRESET = 'oxy';
|
|
27
|
+
const DEFAULT_MODE = 'system';
|
|
28
|
+
const BloomThemeContext = exports.BloomThemeContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
29
|
+
function useThemeState({
|
|
30
|
+
controlledMode,
|
|
31
|
+
controlledPreset,
|
|
32
|
+
defaultMode,
|
|
33
|
+
defaultPreset,
|
|
34
|
+
persistKey,
|
|
35
|
+
storage,
|
|
36
|
+
onModeChange,
|
|
37
|
+
onColorPresetChange
|
|
38
|
+
}) {
|
|
39
|
+
// Synchronous read happens once on first render. Succeeds on web with
|
|
40
|
+
// localStorage-backed adapters; async adapters rehydrate via the effect
|
|
41
|
+
// below. Lazy-initialized via `useState` so it runs exactly once per mount.
|
|
42
|
+
const [syncResult] = (0, _react.useState)(() => (0, _persistence.readPersistedThemeSync)(persistKey, storage));
|
|
43
|
+
const syncState = syncResult.kind === 'sync' ? syncResult.state : null;
|
|
44
|
+
const initialMode = syncState?.mode ?? defaultMode;
|
|
45
|
+
const initialPreset = syncState?.colorPreset ?? defaultPreset;
|
|
46
|
+
|
|
47
|
+
// Hydrated immediately when persistence is off or the adapter resolved
|
|
48
|
+
// synchronously (including a null hit — that's a valid "no value" answer).
|
|
49
|
+
const [hydrated, setHydrated] = (0, _react.useState)(syncResult.kind !== 'async');
|
|
50
|
+
const [mode, setModeInternal] = (0, _useControllableState.useControllableState)({
|
|
51
|
+
value: controlledMode,
|
|
52
|
+
defaultValue: initialMode
|
|
53
|
+
});
|
|
54
|
+
const [colorPreset, setPresetInternal] = (0, _useControllableState.useControllableState)({
|
|
55
|
+
value: controlledPreset,
|
|
56
|
+
defaultValue: initialPreset
|
|
57
|
+
});
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
// Refs let setMode/setColorPreset stay referentially stable. Callbacks
|
|
60
|
+
// memoized only by setters and storage identity won't churn the context
|
|
61
|
+
// value on every theme change.
|
|
62
|
+
const modeRef = (0, _react.useRef)(mode);
|
|
63
|
+
modeRef.current = mode;
|
|
64
|
+
const presetRef = (0, _react.useRef)(colorPreset);
|
|
65
|
+
presetRef.current = colorPreset;
|
|
66
|
+
|
|
67
|
+
// Async hydration for adapters that can't be read synchronously
|
|
68
|
+
// (AsyncStorage, MMKV via JSI fallback, etc).
|
|
69
|
+
(0, _react.useEffect)(() => {
|
|
70
|
+
if (hydrated) return;
|
|
71
|
+
if (!persistKey || !storage) {
|
|
72
|
+
setHydrated(true);
|
|
73
|
+
return;
|
|
48
74
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
text: hslVarToCSS(vars['--foreground'] ?? '0 0% 100%'),
|
|
65
|
-
textSecondary: mutedForeground,
|
|
66
|
-
textTertiary: mutedForeground,
|
|
67
|
-
border: hslVarToCSS(vars['--border'] ?? '0 0% 20%'),
|
|
68
|
-
borderLight: hslVarToCSS(vars['--input'] ?? '0 0% 20%'),
|
|
69
|
-
primary: primaryColor,
|
|
70
|
-
primaryForeground,
|
|
71
|
-
primaryLight: surface,
|
|
72
|
-
primaryDark: background,
|
|
73
|
-
secondary: primaryColor,
|
|
74
|
-
tint: primaryColor,
|
|
75
|
-
icon: mutedForeground,
|
|
76
|
-
iconActive: primaryColor,
|
|
77
|
-
success: '#10B981',
|
|
78
|
-
error: '#EF4444',
|
|
79
|
-
warning: '#F59E0B',
|
|
80
|
-
info: '#3B82F6',
|
|
81
|
-
primarySubtle: isDark ? hsl(primaryHue, 50, 10) : hsl(primaryHue, 70, 93),
|
|
82
|
-
primarySubtleForeground: isDark ? hsl(primaryHue, 70, 65) : hsl(primaryHue, 90, 25),
|
|
83
|
-
negative: hsl(destructiveHue, 84, 45),
|
|
84
|
-
negativeForeground: '#FFFFFF',
|
|
85
|
-
negativeSubtle: isDark ? hsl(destructiveHue, 50, 10) : hsl(destructiveHue, 90, 95),
|
|
86
|
-
negativeSubtleForeground: isDark ? hsl(destructiveHue, 70, 65) : hsl(destructiveHue, 80, 40),
|
|
87
|
-
contrast50: isDark ? hsl(primaryHue, 15, 12) : hsl(primaryHue, 10, 93),
|
|
88
|
-
card: surface,
|
|
89
|
-
shadow: isDark ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.1)',
|
|
90
|
-
overlay: 'rgba(0, 0, 0, 0.5)'
|
|
75
|
+
let cancelled = false;
|
|
76
|
+
(0, _persistence.readPersistedTheme)(persistKey, storage).then(state => {
|
|
77
|
+
if (cancelled) return;
|
|
78
|
+
if (state?.mode && controlledMode === undefined) {
|
|
79
|
+
setModeInternal(state.mode);
|
|
80
|
+
onModeChange?.(state.mode);
|
|
81
|
+
}
|
|
82
|
+
if (state?.colorPreset && controlledPreset === undefined) {
|
|
83
|
+
setPresetInternal(state.colorPreset);
|
|
84
|
+
onColorPresetChange?.(state.colorPreset);
|
|
85
|
+
}
|
|
86
|
+
setHydrated(true);
|
|
87
|
+
});
|
|
88
|
+
return () => {
|
|
89
|
+
cancelled = true;
|
|
91
90
|
};
|
|
92
|
-
|
|
91
|
+
// Hydration runs once per storage instance. controlledMode/Preset are
|
|
92
|
+
// captured by closure intentionally — switching controlled-ness mid-flight
|
|
93
|
+
// is unsupported and would invalidate the in-flight hydration anyway.
|
|
94
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
95
|
+
}, [persistKey, storage]);
|
|
96
|
+
const setMode = (0, _react.useCallback)(next => {
|
|
97
|
+
setModeInternal(next);
|
|
98
|
+
onModeChange?.(next);
|
|
99
|
+
void (0, _persistence.writePersistedTheme)(persistKey, storage, {
|
|
100
|
+
mode: next,
|
|
101
|
+
colorPreset: presetRef.current
|
|
102
|
+
});
|
|
103
|
+
}, [setModeInternal, onModeChange, persistKey, storage]);
|
|
104
|
+
const setColorPreset = (0, _react.useCallback)(next => {
|
|
105
|
+
setPresetInternal(next);
|
|
106
|
+
onColorPresetChange?.(next);
|
|
107
|
+
void (0, _persistence.writePersistedTheme)(persistKey, storage, {
|
|
108
|
+
mode: modeRef.current,
|
|
109
|
+
colorPreset: next
|
|
110
|
+
});
|
|
111
|
+
}, [setPresetInternal, onColorPresetChange, persistKey, storage]);
|
|
93
112
|
return {
|
|
94
|
-
mode
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
113
|
+
mode,
|
|
114
|
+
colorPreset,
|
|
115
|
+
setMode,
|
|
116
|
+
setColorPreset,
|
|
117
|
+
hydrated
|
|
98
118
|
};
|
|
99
119
|
}
|
|
100
|
-
const BloomThemeContext = exports.BloomThemeContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
101
120
|
function BloomThemeProvider({
|
|
102
121
|
mode: controlledMode,
|
|
103
122
|
colorPreset: controlledPreset,
|
|
123
|
+
defaultMode = DEFAULT_MODE,
|
|
124
|
+
defaultColorPreset = DEFAULT_PRESET,
|
|
104
125
|
onModeChange,
|
|
105
126
|
onColorPresetChange,
|
|
127
|
+
persistKey,
|
|
128
|
+
storage,
|
|
129
|
+
awaitHydration,
|
|
130
|
+
onHydrating,
|
|
106
131
|
fonts = true,
|
|
107
132
|
onFontsLoading,
|
|
108
133
|
children
|
|
109
134
|
}) {
|
|
110
135
|
const rnScheme = (0, _reactNative.useColorScheme)();
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
const {
|
|
137
|
+
mode,
|
|
138
|
+
colorPreset,
|
|
139
|
+
setMode,
|
|
140
|
+
setColorPreset,
|
|
141
|
+
hydrated
|
|
142
|
+
} = useThemeState({
|
|
143
|
+
controlledMode,
|
|
144
|
+
controlledPreset,
|
|
145
|
+
defaultMode,
|
|
146
|
+
defaultPreset: defaultColorPreset,
|
|
147
|
+
persistKey,
|
|
148
|
+
storage,
|
|
149
|
+
onModeChange,
|
|
150
|
+
onColorPresetChange
|
|
151
|
+
});
|
|
117
152
|
const isAdaptive = mode === 'adaptive';
|
|
118
153
|
const effectiveMode = isAdaptive ? 'system' : mode;
|
|
119
154
|
const resolved = effectiveMode === 'system' ? rnScheme === 'dark' ? 'dark' : 'light' : effectiveMode;
|
|
120
155
|
|
|
121
|
-
// Apply native color scheme and CSS vars
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
const lastApplied = (0, _react.useRef)('');
|
|
126
|
-
const applyKey = `${resolved}:${appColor}`;
|
|
127
|
-
if (lastApplied.current !== applyKey) {
|
|
128
|
-
lastApplied.current = applyKey;
|
|
156
|
+
// Apply native color scheme, dark class, and CSS vars whenever the resolved
|
|
157
|
+
// mode or preset changes. `useIsomorphicLayoutEffect` runs before paint on
|
|
158
|
+
// both native and web, eliminating the previous render-time side effect.
|
|
159
|
+
(0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => {
|
|
129
160
|
(0, _setColorSchemeSafe.setColorSchemeSafe)(effectiveMode);
|
|
130
161
|
(0, _applyDarkClass.applyDarkClass)(resolved);
|
|
131
|
-
(0, _applyDarkClass.applyColorPresetVars)(
|
|
132
|
-
}
|
|
133
|
-
const
|
|
134
|
-
(0,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
const theme = buildTheme(appColor, resolved, isAdaptive);
|
|
143
|
-
return {
|
|
144
|
-
theme,
|
|
145
|
-
mode,
|
|
146
|
-
colorPreset: appColor,
|
|
147
|
-
setMode,
|
|
148
|
-
setColorPreset
|
|
149
|
-
};
|
|
150
|
-
}, [resolved, appColor, isAdaptive, mode, setMode, setColorPreset]);
|
|
162
|
+
(0, _applyDarkClass.applyColorPresetVars)(colorPreset, resolved);
|
|
163
|
+
}, [effectiveMode, resolved, colorPreset]);
|
|
164
|
+
const contextValue = (0, _react.useMemo)(() => ({
|
|
165
|
+
theme: (0, _buildTheme.buildTheme)(colorPreset, resolved, isAdaptive),
|
|
166
|
+
mode,
|
|
167
|
+
colorPreset,
|
|
168
|
+
setMode,
|
|
169
|
+
setColorPreset
|
|
170
|
+
}), [colorPreset, resolved, isAdaptive, mode, setMode, setColorPreset]);
|
|
171
|
+
const shouldAwait = awaitHydration ?? Boolean(persistKey && storage);
|
|
172
|
+
const isGated = shouldAwait && !hydrated;
|
|
151
173
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(BloomThemeContext.Provider, {
|
|
152
174
|
value: contextValue,
|
|
153
175
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FontLoader.FontLoader, {
|
|
154
176
|
enabled: fonts,
|
|
155
177
|
fallback: onFontsLoading,
|
|
156
|
-
children: children
|
|
178
|
+
children: isGated ? onHydrating ?? null : children
|
|
157
179
|
})
|
|
158
180
|
});
|
|
159
181
|
}
|
|
160
182
|
|
|
161
183
|
/**
|
|
162
|
-
* Scoped color override for a subtree.
|
|
163
|
-
*
|
|
184
|
+
* Scoped color override for a subtree. Inherits the resolved mode from the
|
|
185
|
+
* parent `BloomThemeProvider` but renders descendants with a different preset.
|
|
164
186
|
*/
|
|
165
187
|
|
|
166
188
|
function BloomColorScope({
|
|
@@ -172,7 +194,7 @@ function BloomColorScope({
|
|
|
172
194
|
throw new Error('BloomColorScope must be used within a <BloomThemeProvider>');
|
|
173
195
|
}
|
|
174
196
|
const contextValue = (0, _react.useMemo)(() => {
|
|
175
|
-
const theme = buildTheme(colorPreset, parent.theme.mode);
|
|
197
|
+
const theme = (0, _buildTheme.buildTheme)(colorPreset, parent.theme.mode);
|
|
176
198
|
return {
|
|
177
199
|
...parent,
|
|
178
200
|
theme,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["require","_react","_interopRequireWildcard","_reactNative","
|
|
1
|
+
{"version":3,"names":["require","_react","_interopRequireWildcard","_reactNative","_useControllableState","_FontLoader","_applyDarkClass","_buildTheme","_persistence","_setColorSchemeSafe","_useIsomorphicLayoutEffect","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","DEFAULT_PRESET","DEFAULT_MODE","BloomThemeContext","exports","createContext","useThemeState","controlledMode","controlledPreset","defaultMode","defaultPreset","persistKey","storage","onModeChange","onColorPresetChange","syncResult","useState","readPersistedThemeSync","syncState","kind","state","initialMode","mode","initialPreset","colorPreset","hydrated","setHydrated","setModeInternal","useControllableState","value","defaultValue","setPresetInternal","modeRef","useRef","current","presetRef","useEffect","cancelled","readPersistedTheme","then","undefined","setMode","useCallback","next","writePersistedTheme","setColorPreset","BloomThemeProvider","defaultColorPreset","awaitHydration","onHydrating","fonts","onFontsLoading","children","rnScheme","useRNColorScheme","isAdaptive","effectiveMode","resolved","useIsomorphicLayoutEffect","setColorSchemeSafe","applyDarkClass","applyColorPresetVars","contextValue","useMemo","theme","buildTheme","shouldAwait","Boolean","isGated","jsx","Provider","FontLoader","enabled","fallback","BloomColorScope","parent","useContext","Error"],"sourceRoot":"../../../src","sources":["theme/BloomThemeProvider.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -16,6 +16,11 @@ function applyDarkClass(resolved) {
|
|
|
16
16
|
/**
|
|
17
17
|
* Apply a color preset's CSS custom properties to the document root.
|
|
18
18
|
* No-op on native — only affects web.
|
|
19
|
+
*
|
|
20
|
+
* Values are written as raw HSL triples (e.g. `185 100% 20%`), matching the
|
|
21
|
+
* shadcn/Tailwind convention where stylesheets wrap them themselves with
|
|
22
|
+
* `hsl(var(--primary))`. Writing pre-resolved `hsl(...)` values here would
|
|
23
|
+
* produce invalid `hsl(hsl(...))` in consuming stylesheets and break theming.
|
|
19
24
|
*/
|
|
20
25
|
function applyColorPresetVars(preset, resolved) {
|
|
21
26
|
if (_reactNative.Platform.OS !== 'web' || typeof document === 'undefined') return;
|
|
@@ -24,7 +29,7 @@ function applyColorPresetVars(preset, resolved) {
|
|
|
24
29
|
const vars = resolved === 'dark' ? config.dark : config.light;
|
|
25
30
|
const root = document.documentElement.style;
|
|
26
31
|
for (const [key, value] of Object.entries(vars)) {
|
|
27
|
-
root.setProperty(key,
|
|
32
|
+
root.setProperty(key, value);
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
//# sourceMappingURL=apply-dark-class.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_colorPresets","applyDarkClass","resolved","Platform","OS","document","documentElement","classList","toggle","applyColorPresetVars","preset","config","APP_COLOR_PRESETS","vars","dark","light","root","style","key","value","Object","entries","setProperty"],"sourceRoot":"../../../src","sources":["theme/apply-dark-class.ts"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAEO,SAASE,cAAcA,CAACC,QAA0B,EAAE;EACzD,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,EAAE;IAC5DA,QAAQ,CAACC,eAAe,CAACC,SAAS,CAACC,MAAM,CAAC,MAAM,EAAEN,QAAQ,KAAK,MAAM,CAAC;EACxE;AACF;;AAEA;AACA;AACA;AACA;AACO,SAASO,oBAAoBA,CAACC,MAAoB,EAAER,QAA0B,EAAE;EACrF,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,EAAE;EAE9D,MAAMM,MAAM,GAAGC,+BAAiB,CAACF,MAAM,CAAC;EACxC,IAAI,CAACC,MAAM,EAAE;EAEb,MAAME,IAAI,GAAGX,QAAQ,KAAK,MAAM,GAAGS,MAAM,CAACG,IAAI,GAAGH,MAAM,CAACI,KAAK;EAC7D,MAAMC,IAAI,GAAGX,QAAQ,CAACC,eAAe,CAACW,KAAK;EAE3C,KAAK,MAAM,CAACC,GAAG,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACR,IAAI,CAAC,EAAE;IAC/CG,IAAI,CAACM,WAAW,CAACJ,GAAG,
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_colorPresets","applyDarkClass","resolved","Platform","OS","document","documentElement","classList","toggle","applyColorPresetVars","preset","config","APP_COLOR_PRESETS","vars","dark","light","root","style","key","value","Object","entries","setProperty"],"sourceRoot":"../../../src","sources":["theme/apply-dark-class.ts"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAEO,SAASE,cAAcA,CAACC,QAA0B,EAAE;EACzD,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,EAAE;IAC5DA,QAAQ,CAACC,eAAe,CAACC,SAAS,CAACC,MAAM,CAAC,MAAM,EAAEN,QAAQ,KAAK,MAAM,CAAC;EACxE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASO,oBAAoBA,CAACC,MAAoB,EAAER,QAA0B,EAAE;EACrF,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,EAAE;EAE9D,MAAMM,MAAM,GAAGC,+BAAiB,CAACF,MAAM,CAAC;EACxC,IAAI,CAACC,MAAM,EAAE;EAEb,MAAME,IAAI,GAAGX,QAAQ,KAAK,MAAM,GAAGS,MAAM,CAACG,IAAI,GAAGH,MAAM,CAACI,KAAK;EAC7D,MAAMC,IAAI,GAAGX,QAAQ,CAACC,eAAe,CAACW,KAAK;EAE3C,KAAK,MAAM,CAACC,GAAG,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACR,IAAI,CAAC,EAAE;IAC/CG,IAAI,CAACM,WAAW,CAACJ,GAAG,EAAEC,KAAK,CAAC;EAC9B;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.STATUS_COLORS = void 0;
|
|
7
|
+
exports.buildTheme = buildTheme;
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _colorPresets = require("./color-presets.js");
|
|
10
|
+
var _adaptiveColors = require("./adaptive-colors.js");
|
|
11
|
+
/**
|
|
12
|
+
* Status colors used across the design system. Independent of the accent
|
|
13
|
+
* preset so semantic intent stays stable across themes.
|
|
14
|
+
*/
|
|
15
|
+
const STATUS_COLORS = exports.STATUS_COLORS = {
|
|
16
|
+
success: '#10B981',
|
|
17
|
+
error: '#EF4444',
|
|
18
|
+
warning: '#F59E0B',
|
|
19
|
+
info: '#3B82F6'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Convert a shadcn-style HSL CSS variable (`'H S% L%'` or `'H S% L% / A'`)
|
|
24
|
+
* into a fully-resolved `hsl()` / `hsla()` color string consumable by both
|
|
25
|
+
* web `style` and React Native.
|
|
26
|
+
*/
|
|
27
|
+
function hslVarToColor(hslVar) {
|
|
28
|
+
const parts = hslVar.split('/').map(p => p.trim());
|
|
29
|
+
const triple = parts[0] ?? '0 0% 0%';
|
|
30
|
+
const components = triple.replace(/\s+/g, ', ');
|
|
31
|
+
if (parts.length === 2) {
|
|
32
|
+
const alpha = parseFloat(parts[1] ?? '100') / 100;
|
|
33
|
+
return `hsla(${components}, ${alpha})`;
|
|
34
|
+
}
|
|
35
|
+
return `hsl(${components})`;
|
|
36
|
+
}
|
|
37
|
+
function extractHue(hslVar) {
|
|
38
|
+
const first = hslVar.split(/\s+/)[0] ?? '0';
|
|
39
|
+
const hue = parseInt(first, 10);
|
|
40
|
+
return Number.isFinite(hue) ? hue : 0;
|
|
41
|
+
}
|
|
42
|
+
function hsl(h, s, l) {
|
|
43
|
+
return `hsl(${h}, ${s}%, ${l}%)`;
|
|
44
|
+
}
|
|
45
|
+
function readToken(tokens, key, fallback = '0 0% 0%') {
|
|
46
|
+
return hslVarToColor(tokens[key] ?? fallback);
|
|
47
|
+
}
|
|
48
|
+
function buildColorsFromPreset(preset, resolved) {
|
|
49
|
+
const config = _colorPresets.APP_COLOR_PRESETS[preset];
|
|
50
|
+
const tokens = resolved === 'dark' ? config.dark : config.light;
|
|
51
|
+
const isDark = resolved === 'dark';
|
|
52
|
+
const primaryHue = extractHue(tokens['--primary'] ?? '0 0% 50%');
|
|
53
|
+
const destructiveHue = extractHue(tokens['--destructive'] ?? '0 0% 0%');
|
|
54
|
+
const background = readToken(tokens, '--background');
|
|
55
|
+
const surface = readToken(tokens, '--surface');
|
|
56
|
+
const mutedForeground = readToken(tokens, '--muted-foreground', '0 0% 50%');
|
|
57
|
+
const primaryColor = readToken(tokens, '--primary', '0 0% 50%');
|
|
58
|
+
const primaryForeground = readToken(tokens, '--primary-foreground', '0 0% 100%');
|
|
59
|
+
return {
|
|
60
|
+
background,
|
|
61
|
+
backgroundSecondary: surface,
|
|
62
|
+
backgroundTertiary: readToken(tokens, '--muted'),
|
|
63
|
+
text: readToken(tokens, '--foreground', '0 0% 100%'),
|
|
64
|
+
textSecondary: mutedForeground,
|
|
65
|
+
textTertiary: mutedForeground,
|
|
66
|
+
border: readToken(tokens, '--border', '0 0% 20%'),
|
|
67
|
+
borderLight: readToken(tokens, '--input', '0 0% 20%'),
|
|
68
|
+
primary: primaryColor,
|
|
69
|
+
primaryForeground,
|
|
70
|
+
// Legacy aliases retained for backwards compatibility with downstream
|
|
71
|
+
// consumers. `primaryLight` should be a brand tint, not the surface, but
|
|
72
|
+
// changing this is a breaking change handled in a separate major.
|
|
73
|
+
primaryLight: surface,
|
|
74
|
+
primaryDark: background,
|
|
75
|
+
// `secondary` historically mirrored `primary`. Retained for compatibility.
|
|
76
|
+
secondary: primaryColor,
|
|
77
|
+
tint: primaryColor,
|
|
78
|
+
icon: mutedForeground,
|
|
79
|
+
iconActive: primaryColor,
|
|
80
|
+
...STATUS_COLORS,
|
|
81
|
+
primarySubtle: isDark ? hsl(primaryHue, 50, 10) : hsl(primaryHue, 70, 93),
|
|
82
|
+
primarySubtleForeground: isDark ? hsl(primaryHue, 70, 65) : hsl(primaryHue, 90, 25),
|
|
83
|
+
negative: hsl(destructiveHue, 84, 45),
|
|
84
|
+
negativeForeground: '#FFFFFF',
|
|
85
|
+
negativeSubtle: isDark ? hsl(destructiveHue, 50, 10) : hsl(destructiveHue, 90, 95),
|
|
86
|
+
negativeSubtleForeground: isDark ? hsl(destructiveHue, 70, 65) : hsl(destructiveHue, 80, 40),
|
|
87
|
+
contrast50: isDark ? hsl(primaryHue, 15, 12) : hsl(primaryHue, 10, 93),
|
|
88
|
+
card: surface,
|
|
89
|
+
shadow: isDark ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.1)',
|
|
90
|
+
overlay: 'rgba(0, 0, 0, 0.5)'
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Build a `Theme` from a color preset and a resolved light/dark mode.
|
|
96
|
+
*
|
|
97
|
+
* When `isAdaptive` is true and the platform exposes adaptive (Material You /
|
|
98
|
+
* iOS dynamic) colors, those override the preset-derived palette.
|
|
99
|
+
*/
|
|
100
|
+
function buildTheme(preset, resolved, isAdaptive = false) {
|
|
101
|
+
const adaptive = isAdaptive && _reactNative.Platform.OS !== 'web' ? (0, _adaptiveColors.getAdaptiveColors)() : undefined;
|
|
102
|
+
const colors = adaptive ?? buildColorsFromPreset(preset, resolved);
|
|
103
|
+
return {
|
|
104
|
+
mode: resolved,
|
|
105
|
+
colors,
|
|
106
|
+
isDark: resolved === 'dark',
|
|
107
|
+
isLight: resolved === 'light'
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=build-theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_colorPresets","_adaptiveColors","STATUS_COLORS","exports","success","error","warning","info","hslVarToColor","hslVar","parts","split","map","p","trim","triple","components","replace","length","alpha","parseFloat","extractHue","first","hue","parseInt","Number","isFinite","hsl","h","s","l","readToken","tokens","key","fallback","buildColorsFromPreset","preset","resolved","config","APP_COLOR_PRESETS","dark","light","isDark","primaryHue","destructiveHue","background","surface","mutedForeground","primaryColor","primaryForeground","backgroundSecondary","backgroundTertiary","text","textSecondary","textTertiary","border","borderLight","primary","primaryLight","primaryDark","secondary","tint","icon","iconActive","primarySubtle","primarySubtleForeground","negative","negativeForeground","negativeSubtle","negativeSubtleForeground","contrast50","card","shadow","overlay","buildTheme","isAdaptive","adaptive","Platform","OS","getAdaptiveColors","undefined","colors","mode","isLight"],"sourceRoot":"../../../src","sources":["theme/build-theme.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -5,6 +5,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.HEX_TO_APP_COLOR = exports.APP_COLOR_PRESETS = exports.APP_COLOR_NAMES = void 0;
|
|
7
7
|
exports.hexToAppColorName = hexToAppColorName;
|
|
8
|
+
/**
|
|
9
|
+
* Palette tokens for a single mode (light or dark) of a color preset.
|
|
10
|
+
*
|
|
11
|
+
* Keys carry a leading `--` for historical reasons (shadcn-style CSS variable
|
|
12
|
+
* names) — keep in mind the values are platform-agnostic **raw HSL triples**
|
|
13
|
+
* (e.g. `'185 100% 20%'` or `'185 100% 20% / 0.5'`), not CSS-resolved colors.
|
|
14
|
+
* The same map drives both:
|
|
15
|
+
* - the web layer (written verbatim into `document.documentElement.style`
|
|
16
|
+
* so Tailwind's `hsl(var(--primary))` plumbing picks them up), and
|
|
17
|
+
* - the native layer (`buildTheme` resolves them into `hsl(...)` strings
|
|
18
|
+
* consumable by React Native styles).
|
|
19
|
+
*
|
|
20
|
+
* The `--` prefix is an implementation detail we will drop in a future major.
|
|
21
|
+
*/
|
|
22
|
+
|
|
8
23
|
const APP_COLOR_NAMES = exports.APP_COLOR_NAMES = ['teal', 'blue', 'green', 'amber', 'yellow', 'red', 'purple', 'pink', 'sky', 'orange', 'mint', 'oxy', 'faircoin'];
|
|
9
24
|
const HEX_TO_APP_COLOR = exports.HEX_TO_APP_COLOR = {
|
|
10
25
|
'#005c67': 'teal',
|