From 9284745896872d12f300c32e44f91321c8e41d94 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubaczkowski Date: Thu, 4 Jun 2026 10:49:11 +0200 Subject: [PATCH] fix(adapters): recover gorhom from dropped onChange; drop dead swmansion guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gorhom: under rapid open/close (switch then an immediate dismiss), gorhom can drop its onChange, leaving a re-revealed sheet stuck in 'opening'. That permanently trips the open() guard (hasOpeningInGroup), so every later open is a no-op. Report opened from the animated index as a reliable backstop (idempotent via the status guard). swmansion: onSettle is now optimistic (fires when the animation starts), so a settle at the collapsed detent only ever follows a real close. The closeRequestedRef guard is dead — drop it and handle the settle directly. example: ScannerSheet (persistent) now uses the swmansion adapter, covering the swmansion + persistent (defaultIndex < 0) path. --- example/src/sheets/ScannerSheet.tsx | 168 ++++++++++-------- .../gorhom-sheet/GorhomSheetAdapter.tsx | 17 +- .../swmansion/SwmansionSheetAdapter.tsx | 9 +- 3 files changed, 102 insertions(+), 92 deletions(-) diff --git a/example/src/sheets/ScannerSheet.tsx b/example/src/sheets/ScannerSheet.tsx index c37b609..b02648d 100644 --- a/example/src/sheets/ScannerSheet.tsx +++ b/example/src/sheets/ScannerSheet.tsx @@ -1,4 +1,3 @@ -import type { BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types'; import { forwardRef, useCallback, useState } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { @@ -6,11 +5,13 @@ import { useBottomSheetManager, } from 'react-native-bottom-sheet-stack'; -import { Badge, Button, SecondaryButton, Sheet } from '../components'; +import type { SheetAdapterRef } from '../../../src/adapter.types'; +import { SwmansionSheetAdapter } from '../../../src/adapters/swmansion'; +import { Badge, Button, SecondaryButton } from '../components'; import { ScannerNestedSheet1 } from './ScannerNestedSheets'; import { colors, sharedStyles } from '../styles/theme'; -export const ScannerSheet = forwardRef((_, ref) => { +export const ScannerSheet = forwardRef((_, ref) => { const { close, params } = useBottomSheetContext<'scanner-sheet'>(); const { open } = useBottomSheetManager(); const [isScanning, setIsScanning] = useState(false); @@ -39,92 +40,101 @@ export const ScannerSheet = forwardRef((_, ref) => { }, []); return ( - - - - - - {title} - - This sheet is always mounted (keepMounted). It opens instantly without - mount delay and preserves state between open/close cycles. - + + + + + + + {title} + + This sheet is always mounted (keepMounted). It opens instantly without + mount delay and preserves state between open/close cycles. + - {/* Scanner viewport */} - - {isScanning ? ( - - - Scanning... - - ) : scanResult ? ( - - Scanned Code: - {scanResult} - - ) : ( - - [ ] - Ready to scan - - )} - + {/* Scanner viewport */} + + {isScanning ? ( + + + Scanning... + + ) : scanResult ? ( + + Scanned Code: + {scanResult} + + ) : ( + + [ ] + Ready to scan + + )} + - {/* Actions */} - - {scanResult ? ( - <> -