@oxyhq/bloom 0.59.2 → 0.59.3
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/README.md +1 -1
- package/lib/commonjs/bottom-sheet/BottomSheetBase.js +25 -9
- package/lib/commonjs/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.js +2 -1
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/SheetShell.js +2 -1
- package/lib/commonjs/dialog/SheetShell.js.map +1 -1
- package/lib/commonjs/overlay/index.js +9 -1
- package/lib/commonjs/overlay/index.js.map +1 -1
- package/lib/commonjs/styles/radii.js +9 -0
- package/lib/commonjs/styles/radii.js.map +1 -0
- package/lib/module/bottom-sheet/BottomSheetBase.js +26 -10
- package/lib/module/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/module/dialog/Dialog.js +2 -1
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/SheetShell.js +2 -1
- package/lib/module/dialog/SheetShell.js.map +1 -1
- package/lib/module/overlay/index.js +8 -1
- package/lib/module/overlay/index.js.map +1 -1
- package/lib/module/styles/radii.js +5 -0
- package/lib/module/styles/radii.js.map +1 -0
- package/lib/typescript/commonjs/bottom-sheet/BottomSheetBase.d.ts +4 -5
- package/lib/typescript/commonjs/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/SheetShell.d.ts.map +1 -1
- package/lib/typescript/commonjs/overlay/index.d.ts +3 -0
- package/lib/typescript/commonjs/overlay/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/styles/radii.d.ts +3 -0
- package/lib/typescript/commonjs/styles/radii.d.ts.map +1 -0
- package/lib/typescript/module/bottom-sheet/BottomSheetBase.d.ts +4 -5
- package/lib/typescript/module/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/module/dialog/SheetShell.d.ts.map +1 -1
- package/lib/typescript/module/overlay/index.d.ts +3 -0
- package/lib/typescript/module/overlay/index.d.ts.map +1 -1
- package/lib/typescript/module/styles/radii.d.ts +3 -0
- package/lib/typescript/module/styles/radii.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/BottomSheet.test.tsx +1 -1
- package/src/__tests__/BottomSheetGesture.test.tsx +21 -3
- package/src/bottom-sheet/BottomSheetBase.tsx +33 -15
- package/src/dialog/Dialog.tsx +2 -1
- package/src/dialog/SheetShell.tsx +2 -1
- package/src/overlay/index.tsx +12 -1
- package/src/styles/radii.ts +2 -0
|
@@ -20,6 +20,7 @@ import Animated, {
|
|
|
20
20
|
type SharedValue,
|
|
21
21
|
useAnimatedScrollHandler,
|
|
22
22
|
useAnimatedStyle,
|
|
23
|
+
useDerivedValue,
|
|
23
24
|
useSharedValue,
|
|
24
25
|
withSpring,
|
|
25
26
|
withTiming,
|
|
@@ -27,6 +28,7 @@ import Animated, {
|
|
|
27
28
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
28
29
|
import { Backdrop, BACKDROP_DIM_OPACITY } from '../overlay';
|
|
29
30
|
import { useBloomBlurTarget } from '../overlay/blur-target';
|
|
31
|
+
import { DETACHED_SHEET_RADIUS } from '../styles/radii';
|
|
30
32
|
import { useTheme } from '../theme/use-theme';
|
|
31
33
|
|
|
32
34
|
/** Hook that returns current screen dimensions and updates on rotation/resize. */
|
|
@@ -126,12 +128,11 @@ export interface BottomSheetProps {
|
|
|
126
128
|
*/
|
|
127
129
|
manualActivation?: boolean;
|
|
128
130
|
/**
|
|
129
|
-
* When `true`, the backdrop
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* `backdropOpacity` still controls the resting dim level.
|
|
131
|
+
* When `true`, the backdrop and native blur fade proportionally with drag
|
|
132
|
+
* distance — fully visible at rest and fully gone once the sheet leaves the
|
|
133
|
+
* viewport. The base `backdropOpacity` still controls the resting dim level.
|
|
133
134
|
*
|
|
134
|
-
* Defaults to `false`
|
|
135
|
+
* Defaults to `true`. Set to `false` only for a deliberately fixed backdrop.
|
|
135
136
|
*/
|
|
136
137
|
dynamicBackdrop?: boolean;
|
|
137
138
|
/**
|
|
@@ -219,7 +220,7 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
219
220
|
backdropOpacity = BACKDROP_DIM_OPACITY,
|
|
220
221
|
scrollable = true,
|
|
221
222
|
manualActivation = false,
|
|
222
|
-
dynamicBackdrop =
|
|
223
|
+
dynamicBackdrop = true,
|
|
223
224
|
handleComponent,
|
|
224
225
|
scrollY: externalScrollY,
|
|
225
226
|
headerOverlay,
|
|
@@ -257,6 +258,10 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
257
258
|
}, [screenHeight, screenHeightSV]);
|
|
258
259
|
|
|
259
260
|
const translateY = useSharedValue(screenHeight);
|
|
261
|
+
// The blur must reach zero when the CARD itself has moved fully below the
|
|
262
|
+
// viewport. A short detached dialog can be far smaller than the screen, so
|
|
263
|
+
// screen height is not a valid denominator for this interaction.
|
|
264
|
+
const sheetHeight = useSharedValue(screenHeight);
|
|
260
265
|
const opacity = useSharedValue(0);
|
|
261
266
|
const scrollOffsetY = useSharedValue(0);
|
|
262
267
|
const isScrollAtTop = useSharedValue(true);
|
|
@@ -644,19 +649,25 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
644
649
|
// is multiplied into this group opacity instead, the opaque black child
|
|
645
650
|
// hides the BlurView and Android looks like a plain dark scrim.
|
|
646
651
|
// `dynamicBackdrop` fades the composed blur+dim proportionally with drag.
|
|
647
|
-
|
|
652
|
+
// The SAME progress drives BlurView's native `intensity` prop below:
|
|
653
|
+
// Android's RenderEffect can remain visibly blurred when only an ancestor's
|
|
654
|
+
// alpha changes, so reducing the radius itself is required for the content
|
|
655
|
+
// behind the sheet to become genuinely sharp during the gesture.
|
|
656
|
+
const backdropProgress = useDerivedValue(() => {
|
|
648
657
|
const dragFactor = dynamicBackdrop
|
|
649
658
|
? interpolate(
|
|
650
659
|
translateY.value,
|
|
651
|
-
[0,
|
|
652
|
-
[1, 0
|
|
660
|
+
[0, sheetHeight.value],
|
|
661
|
+
[1, 0],
|
|
653
662
|
'clamp',
|
|
654
663
|
)
|
|
655
664
|
: 1;
|
|
656
|
-
return
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
665
|
+
return opacity.value * dragFactor;
|
|
666
|
+
}, [dynamicBackdrop, opacity, translateY, sheetHeight]);
|
|
667
|
+
|
|
668
|
+
const backdropStyle = useAnimatedStyle(() => ({
|
|
669
|
+
opacity: backdropProgress.value,
|
|
670
|
+
}), [backdropProgress]);
|
|
660
671
|
|
|
661
672
|
const sheetStyle = useAnimatedStyle(() => {
|
|
662
673
|
const scale = interpolate(translateY.value, [0, screenHeightSV.value], [1, 0.95]);
|
|
@@ -692,6 +703,12 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
692
703
|
dismiss();
|
|
693
704
|
}, [onDismissAttempt, dismiss]);
|
|
694
705
|
|
|
706
|
+
const handleSheetLayout = useCallback((event: LayoutChangeEvent) => {
|
|
707
|
+
const measuredHeight = event.nativeEvent.layout.height;
|
|
708
|
+
if (measuredHeight > 0) sheetHeight.value = measuredHeight;
|
|
709
|
+
onLayout?.(event);
|
|
710
|
+
}, [onLayout, sheetHeight]);
|
|
711
|
+
|
|
695
712
|
const scrollHandler = useAnimatedScrollHandler({
|
|
696
713
|
onScroll: (event) => {
|
|
697
714
|
scrollOffsetY.value = event.contentOffset.y;
|
|
@@ -800,13 +817,14 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
800
817
|
onPress={handleBackdropPress}
|
|
801
818
|
dimOpacity={backdropOpacity}
|
|
802
819
|
blurTarget={blurTarget ?? undefined}
|
|
820
|
+
blurProgress={backdropProgress}
|
|
803
821
|
style={[styles.backdrop, backdropStyle]}
|
|
804
822
|
/>
|
|
805
823
|
)}
|
|
806
824
|
|
|
807
825
|
<GestureDetector gesture={panGesture}>
|
|
808
826
|
<Animated.View
|
|
809
|
-
onLayout={
|
|
827
|
+
onLayout={handleSheetLayout}
|
|
810
828
|
style={[dynamicStyles.sheet, sheetMarginStyle, sheetStyle, sheetHeightStyle, style]}
|
|
811
829
|
>
|
|
812
830
|
{backgroundComponent?.({ style: styles.background })}
|
|
@@ -845,7 +863,7 @@ const styles = StyleSheet.create({
|
|
|
845
863
|
sheetDetached: {
|
|
846
864
|
left: 16,
|
|
847
865
|
right: 16,
|
|
848
|
-
borderRadius:
|
|
866
|
+
borderRadius: DETACHED_SHEET_RADIUS,
|
|
849
867
|
},
|
|
850
868
|
sheetNormal: {
|
|
851
869
|
left: 0,
|
package/src/dialog/Dialog.tsx
CHANGED
|
@@ -26,6 +26,7 @@ import Animated, {
|
|
|
26
26
|
} from 'react-native-reanimated';
|
|
27
27
|
|
|
28
28
|
import { BottomSheet, type BottomSheetRef } from '../bottom-sheet';
|
|
29
|
+
import { DETACHED_SHEET_RADIUS } from '../styles/radii';
|
|
29
30
|
import { Z_INDEX, Z_INDEX_LAYER_STEP } from '../styles/z-index';
|
|
30
31
|
import { useTheme } from '../theme/use-theme';
|
|
31
32
|
import { Context, useDialogControl } from './context';
|
|
@@ -251,7 +252,7 @@ function CenteredOrSideDialog({
|
|
|
251
252
|
// All four corners rounded — bloom's BottomSheet defaults to top-only
|
|
252
253
|
// radius in flush mode, but we use `detached` so the whole card is
|
|
253
254
|
// floating and rounded uniformly.
|
|
254
|
-
borderRadius:
|
|
255
|
+
borderRadius: DETACHED_SHEET_RADIUS,
|
|
255
256
|
},
|
|
256
257
|
// Drives the card's `height` only while a morph is in flight; at rest it
|
|
257
258
|
// resolves to `height: 'auto'` — the card's normal content sizing.
|
|
@@ -14,6 +14,7 @@ import React, { useCallback, useImperativeHandle, useMemo, useRef } from 'react'
|
|
|
14
14
|
import { Pressable, StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native';
|
|
15
15
|
|
|
16
16
|
import { BottomSheet, type BottomSheetRef } from '../bottom-sheet';
|
|
17
|
+
import { DETACHED_SHEET_RADIUS } from '../styles/radii';
|
|
17
18
|
import { Z_INDEX } from '../styles/z-index';
|
|
18
19
|
import { useTheme } from '../theme/use-theme';
|
|
19
20
|
import { Context } from './context';
|
|
@@ -87,7 +88,7 @@ export function SheetShell({
|
|
|
87
88
|
() => ({
|
|
88
89
|
maxWidth: 500,
|
|
89
90
|
backgroundColor: theme.colors.background,
|
|
90
|
-
borderRadius:
|
|
91
|
+
borderRadius: DETACHED_SHEET_RADIUS,
|
|
91
92
|
}),
|
|
92
93
|
[theme.colors.background],
|
|
93
94
|
);
|
package/src/overlay/index.tsx
CHANGED
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
*/
|
|
42
42
|
import { forwardRef, memo, type ReactNode, type RefObject } from 'react';
|
|
43
43
|
import { BlurView } from 'expo-blur';
|
|
44
|
+
import Animated, { type SharedValue, useAnimatedProps } from 'react-native-reanimated';
|
|
44
45
|
import {
|
|
45
46
|
Platform,
|
|
46
47
|
Pressable,
|
|
@@ -61,6 +62,8 @@ export const BACKDROP_BLUR_INTENSITY = 40;
|
|
|
61
62
|
/** Dim laid over the blur — the blur alone does not give enough contrast. */
|
|
62
63
|
export const BACKDROP_DIM_OPACITY = 0.45;
|
|
63
64
|
|
|
65
|
+
const AnimatedBlurView = Animated.createAnimatedComponent(BlurView);
|
|
66
|
+
|
|
64
67
|
export interface OverlayRootProps {
|
|
65
68
|
children?: ReactNode;
|
|
66
69
|
style?: StyleProp<ViewStyle>;
|
|
@@ -98,6 +101,8 @@ export interface BackdropProps {
|
|
|
98
101
|
dimOpacity?: number;
|
|
99
102
|
/** Android view sampled by the native blur. Modal surfaces receive this from BloomProvider. */
|
|
100
103
|
blurTarget?: RefObject<NativeView | null>;
|
|
104
|
+
/** Live visibility progress used to reduce native blur while a surface leaves. */
|
|
105
|
+
blurProgress?: SharedValue<number>;
|
|
101
106
|
/** Extra style on the press target — animated opacity, insets, z-index. */
|
|
102
107
|
style?: StyleProp<ViewStyle>;
|
|
103
108
|
/** Rendered ON TOP of the dim, inside the press target (Dialog's panel does this). */
|
|
@@ -120,6 +125,7 @@ export const Backdrop = memo(forwardRef<View, BackdropProps>(function Backdrop(
|
|
|
120
125
|
dimColor = '#000',
|
|
121
126
|
dimOpacity = BACKDROP_DIM_OPACITY,
|
|
122
127
|
blurTarget,
|
|
128
|
+
blurProgress,
|
|
123
129
|
style,
|
|
124
130
|
children,
|
|
125
131
|
accessibilityLabel = 'Dismiss',
|
|
@@ -128,6 +134,10 @@ export const Backdrop = memo(forwardRef<View, BackdropProps>(function Backdrop(
|
|
|
128
134
|
ref,
|
|
129
135
|
) {
|
|
130
136
|
const inert = disabled || !onPress;
|
|
137
|
+
const animatedBlurProps = useAnimatedProps(() => ({
|
|
138
|
+
intensity: Math.max(0, Math.min(100, blurIntensity * (blurProgress?.value ?? 1))),
|
|
139
|
+
}), [blurIntensity, blurProgress]);
|
|
140
|
+
|
|
131
141
|
return (
|
|
132
142
|
<Pressable
|
|
133
143
|
// MUST forward the ref: surfaces animate the backdrop through
|
|
@@ -150,8 +160,9 @@ export const Backdrop = memo(forwardRef<View, BackdropProps>(function Backdrop(
|
|
|
150
160
|
style={[StyleSheet.absoluteFill, style]}
|
|
151
161
|
>
|
|
152
162
|
{blurIntensity > 0 ? (
|
|
153
|
-
<
|
|
163
|
+
<AnimatedBlurView
|
|
154
164
|
intensity={blurIntensity}
|
|
165
|
+
animatedProps={animatedBlurProps}
|
|
155
166
|
tint={blurTint}
|
|
156
167
|
blurTarget={blurTarget}
|
|
157
168
|
// Expo disables Android blur without an explicit target. Sheets get
|