Skip to content

Commit 22e6b02

Browse files
committed
fix: critical mobile and web bug fixes
- Fix gorhom#2642: isLayoutCalculated logic bug (|| should be &&) causing incorrect detent positions - Fix gorhom#2498: prevent closing two modals at once by guarding splice with sheetIndex !== -1 - Fix gorhom#2342: use Math.floor on animatedIndex to fix Android freeze with reduced animations - Fix gorhom#2595: React 19 compatibility and type safety for findNodeHandle web utility
1 parent 0284774 commit 22e6b02

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

src/components/bottomSheet/BottomSheet.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
246246
let isContainerHeightCalculated = false;
247247
//container height was provided.
248248
if (
249-
_providedContainerHeight !== null ||
249+
_providedContainerHeight !== null &&
250250
_providedContainerHeight !== undefined
251251
) {
252252
isContainerHeightCalculated = true;

src/components/bottomSheetBackdrop/BottomSheetBackdrop.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ const BottomSheetBackdropComponent = ({
116116

117117
//#region effects
118118
useAnimatedReaction(
119-
() => animatedIndex.value <= disappearsOnIndex,
119+
() => Math.floor(animatedIndex.value) <= disappearsOnIndex,
120120
(shouldDisableTouchability, previous) => {
121121
if (shouldDisableTouchability === previous) {
122122
return;

src/components/bottomSheetModalProvider/BottomSheetModalProvider.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ const BottomSheetModalProviderWrapper = ({
9999
* Here we remove the unmounted sheet and update
100100
* the sheets queue.
101101
*/
102-
_sheetsQueue.splice(sheetIndex, 1);
102+
if (sheetIndex !== -1) {
103+
_sheetsQueue.splice(sheetIndex, 1);
104+
}
103105
sheetsQueueRef.current = _sheetsQueue;
104106

105107
/**
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { NodeHandle } from 'react-native';
2+
import {
3+
findNodeHandle as _findNodeHandle,
4+
} from 'react-native';
5+
6+
/**
7+
* Type bridge for accessing undocumented React Native scroll component internals.
8+
* These properties exist at runtime but aren't exposed in RN's public type definitions.
9+
*
10+
* @see https://github.com/facebook/react-native/blob/main/packages/virtualized-lists/Lists/VirtualizedList.js#L1252
11+
*/
12+
interface ScrollComponentInternals {
13+
/** Available on ScrollView, FlatList, etc. to get the underlying native scroll ref */
14+
getNativeScrollRef?: () => NodeHandle | null;
15+
/** Internal property on VirtualizedList storing the scroll ref */
16+
_scrollRef?: NodeHandle | null;
17+
}
18+
19+
export function findNodeHandle(
20+
componentOrHandle: Parameters<typeof _findNodeHandle>['0']
21+
): NodeHandle | null | typeof componentOrHandle {
22+
// Early return for null/undefined (React 19 fix)
23+
if (componentOrHandle == null) {
24+
return null;
25+
}
26+
27+
let nodeHandle: NodeHandle | null = null;
28+
29+
try {
30+
nodeHandle = _findNodeHandle(componentOrHandle);
31+
if (nodeHandle) {
32+
return nodeHandle;
33+
}
34+
} catch {}
35+
36+
// Type bridge: componentOrHandle may have scroll internals at runtime
37+
const scrollable = componentOrHandle as unknown as ScrollComponentInternals;
38+
39+
try {
40+
if (typeof scrollable.getNativeScrollRef === 'function') {
41+
nodeHandle = scrollable.getNativeScrollRef();
42+
if (nodeHandle) {
43+
return nodeHandle;
44+
}
45+
}
46+
} catch {}
47+
48+
if (scrollable._scrollRef != null) {
49+
return scrollable._scrollRef;
50+
}
51+
52+
console.warn('could not find scrollable ref!');
53+
return componentOrHandle;
54+
}

0 commit comments

Comments
 (0)