@oxyhq/bloom 0.25.0 → 0.25.2
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/bottom-sheet/index.js +89 -38
- package/lib/commonjs/bottom-sheet/index.js.map +1 -1
- package/lib/commonjs/theme/color-scope/index.js +21 -10
- package/lib/commonjs/theme/color-scope/index.js.map +1 -1
- package/lib/commonjs/theme/color-scope/index.web.js +21 -10
- package/lib/commonjs/theme/color-scope/index.web.js.map +1 -1
- package/lib/module/bottom-sheet/index.js +90 -39
- package/lib/module/bottom-sheet/index.js.map +1 -1
- package/lib/module/theme/color-scope/index.js +21 -10
- package/lib/module/theme/color-scope/index.js.map +1 -1
- package/lib/module/theme/color-scope/index.web.js +21 -10
- package/lib/module/theme/color-scope/index.web.js.map +1 -1
- package/lib/typescript/commonjs/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-scope/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/module/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-scope/index.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-scope/index.web.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/BloomColorScope.test.tsx +66 -0
- package/src/__tests__/BottomSheet.test.tsx +27 -1
- package/src/bottom-sheet/index.tsx +90 -38
- package/src/theme/color-scope/index.tsx +26 -15
- package/src/theme/color-scope/index.web.tsx +25 -15
|
@@ -32,16 +32,16 @@ export function BloomColorScope({
|
|
|
32
32
|
style,
|
|
33
33
|
children,
|
|
34
34
|
}: BloomColorScopeProps) {
|
|
35
|
+
// All hooks are called UNCONDITIONALLY, in the same order on every render —
|
|
36
|
+
// never gate a hook behind an early return (rules of hooks). The conditional
|
|
37
|
+
// no-op/throw behavior is applied AFTER every hook has run, using the values
|
|
38
|
+
// the hooks produced. `resolvedMode` falls back harmlessly when the provider
|
|
39
|
+
// is absent (that render path throws below anyway).
|
|
35
40
|
const parent = useContext(BloomThemeContext);
|
|
36
|
-
|
|
37
|
-
throw new Error('BloomColorScope must be used within a <BloomThemeProvider>');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!colorPreset) return <>{children}</>;
|
|
41
|
+
const resolvedMode = parent?.theme.mode ?? 'light';
|
|
41
42
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const contextValue = useMemo<BloomThemeContextValue>(() => {
|
|
43
|
+
const contextValue = useMemo<BloomThemeContextValue | null>(() => {
|
|
44
|
+
if (!parent || !colorPreset) return null;
|
|
45
45
|
const theme = buildTheme(colorPreset, resolvedMode);
|
|
46
46
|
return { ...parent, theme, colorPreset };
|
|
47
47
|
}, [colorPreset, resolvedMode, parent]);
|
|
@@ -50,10 +50,19 @@ export function BloomColorScope({
|
|
|
50
50
|
// VariableContext (`VariableContextProvider`), NOT via an inline `vars()`
|
|
51
51
|
// style — under react-native-css@3 inline vars applied to a plain `<View>`
|
|
52
52
|
// (no matched className rules) are dropped silently. See `style-builder.ts`.
|
|
53
|
-
const nativeVars = useMemo(
|
|
54
|
-
() => buildScopeVars(colorPreset, resolvedMode),
|
|
53
|
+
const nativeVars = useMemo<Record<string, string> | null>(
|
|
54
|
+
() => (colorPreset ? buildScopeVars(colorPreset, resolvedMode) : null),
|
|
55
55
|
[colorPreset, resolvedMode],
|
|
56
56
|
);
|
|
57
|
+
|
|
58
|
+
if (!parent) {
|
|
59
|
+
throw new Error('BloomColorScope must be used within a <BloomThemeProvider>');
|
|
60
|
+
}
|
|
61
|
+
// `colorPreset` undefined => the scope is a no-op; children inherit the
|
|
62
|
+
// parent scope. With `parent` present, `contextValue`/`nativeVars` are null
|
|
63
|
+
// iff `colorPreset` is absent, so this guard also narrows them to non-null.
|
|
64
|
+
if (!contextValue || !nativeVars) return <>{children}</>;
|
|
65
|
+
|
|
57
66
|
const VariableProvider = getVariableContextProvider();
|
|
58
67
|
|
|
59
68
|
let content: React.ReactNode;
|
|
@@ -97,13 +106,15 @@ export function BloomColorScope({
|
|
|
97
106
|
* `<BloomColorScope>`, which wraps children in `VariableContextProvider`.
|
|
98
107
|
*/
|
|
99
108
|
export function useColorScopeStyle(colorPreset: AppColorName): StyleProp<ViewStyle> {
|
|
109
|
+
// Hooks first, unconditionally; throw only after they have all run.
|
|
100
110
|
const parent = useContext(BloomThemeContext);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
const resolvedMode = parent.theme.mode;
|
|
105
|
-
return useMemo(
|
|
111
|
+
const resolvedMode = parent?.theme.mode ?? 'light';
|
|
112
|
+
const scopeStyle = useMemo(
|
|
106
113
|
() => buildNativePresetStyle(colorPreset, resolvedMode),
|
|
107
114
|
[colorPreset, resolvedMode],
|
|
108
115
|
);
|
|
116
|
+
if (!parent) {
|
|
117
|
+
throw new Error('useColorScopeStyle must be used within a <BloomThemeProvider>');
|
|
118
|
+
}
|
|
119
|
+
return scopeStyle;
|
|
109
120
|
}
|
|
@@ -61,25 +61,33 @@ export function BloomColorScope({
|
|
|
61
61
|
style,
|
|
62
62
|
children,
|
|
63
63
|
}: BloomColorScopeProps) {
|
|
64
|
+
// All hooks are called UNCONDITIONALLY, in the same order on every render —
|
|
65
|
+
// never gate a hook behind an early return (rules of hooks). The conditional
|
|
66
|
+
// no-op/throw behavior is applied AFTER every hook has run, using the values
|
|
67
|
+
// the hooks produced. `resolvedMode` falls back harmlessly when the provider
|
|
68
|
+
// is absent (that render path throws below anyway).
|
|
64
69
|
const parent = useContext(BloomThemeContext);
|
|
65
|
-
|
|
66
|
-
throw new Error('BloomColorScope must be used within a <BloomThemeProvider>');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!colorPreset) return <>{children}</>;
|
|
70
|
+
const resolvedMode = parent?.theme.mode ?? 'light';
|
|
70
71
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
const contextValue = useMemo<BloomThemeContextValue>(() => {
|
|
72
|
+
const contextValue = useMemo<BloomThemeContextValue | null>(() => {
|
|
73
|
+
if (!parent || !colorPreset) return null;
|
|
74
74
|
const theme = buildTheme(colorPreset, resolvedMode);
|
|
75
75
|
return { ...parent, theme, colorPreset };
|
|
76
76
|
}, [colorPreset, resolvedMode, parent]);
|
|
77
77
|
|
|
78
|
-
const varsStyle = useMemo(
|
|
79
|
-
() => buildWebScopeVars(colorPreset, resolvedMode),
|
|
78
|
+
const varsStyle = useMemo<React.CSSProperties | null>(
|
|
79
|
+
() => (colorPreset ? buildWebScopeVars(colorPreset, resolvedMode) : null),
|
|
80
80
|
[colorPreset, resolvedMode],
|
|
81
81
|
);
|
|
82
82
|
|
|
83
|
+
if (!parent) {
|
|
84
|
+
throw new Error('BloomColorScope must be used within a <BloomThemeProvider>');
|
|
85
|
+
}
|
|
86
|
+
// `colorPreset` undefined => the scope is a no-op; children inherit the
|
|
87
|
+
// parent scope. With `parent` present, `contextValue`/`varsStyle` are null
|
|
88
|
+
// iff `colorPreset` is absent, so this guard also narrows them to non-null.
|
|
89
|
+
if (!contextValue || !varsStyle) return <>{children}</>;
|
|
90
|
+
|
|
83
91
|
let content: React.ReactNode;
|
|
84
92
|
if (asChild) {
|
|
85
93
|
const child = Children.only(children);
|
|
@@ -111,13 +119,15 @@ export function BloomColorScope({
|
|
|
111
119
|
* caller. Returns a stable React style object carrying the preset's CSS vars.
|
|
112
120
|
*/
|
|
113
121
|
export function useColorScopeStyle(colorPreset: AppColorName): React.CSSProperties {
|
|
122
|
+
// Hooks first, unconditionally; throw only after they have all run.
|
|
114
123
|
const parent = useContext(BloomThemeContext);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
const resolvedMode = parent.theme.mode;
|
|
119
|
-
return useMemo(
|
|
124
|
+
const resolvedMode = parent?.theme.mode ?? 'light';
|
|
125
|
+
const scopeStyle = useMemo(
|
|
120
126
|
() => buildWebScopeVars(colorPreset, resolvedMode),
|
|
121
127
|
[colorPreset, resolvedMode],
|
|
122
128
|
);
|
|
129
|
+
if (!parent) {
|
|
130
|
+
throw new Error('useColorScopeStyle must be used within a <BloomThemeProvider>');
|
|
131
|
+
}
|
|
132
|
+
return scopeStyle;
|
|
123
133
|
}
|