mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 15:48:05 +00:00
2.2 KiB
2.2 KiB
Nested Modals with PlatformDropdown
Issue
PlatformDropdowns inside BottomSheetModals don't open on Android, or dropdowns reopen unexpectedly after navigation.
Solution
-
Add controlled state for each PlatformDropdown:
const [open, setOpen] = useState(false); <PlatformDropdown open={open} onOpenChange={setOpen} // ... /> -
Memoize groups and callbacks to prevent unnecessary re-renders:
const handleOption1 = useCallback(() => { // handler logic }, [dependencies]); const dropdownGroups = useMemo(() => [ { title: "Group 1", options: [ { type: "radio", label: "Option 1", value: "option1", selected: state === "option1", onPress: handleOption1, }, ], }, ], [state, handleOption1]); <PlatformDropdown groups={dropdownGroups} // ... /> -
Use
Viewfor triggers, notTouchableOpacity:// ✅ Correct <PlatformDropdown trigger={<View>...</View>} /> // ❌ Wrong - causes nested TouchableOpacity conflicts <PlatformDropdown trigger={<TouchableOpacity>...</TouchableOpacity>} /> -
Add
stackBehavior='push'to parent BottomSheetModal:<BottomSheetModal stackBehavior='push' // ... /> -
Reset dropdown states on modal dismiss:
const handleDismiss = useCallback(() => { setDropdown1Open(false); setDropdown2Open(false); // reset all dropdown states onDismiss?.(); }, [onDismiss]); <BottomSheetModal onDismiss={handleDismiss} // ... />
Why
- PlatformDropdown wraps triggers in TouchableOpacity on Android. Nested TouchableOpacity causes touch event conflicts.
- PlatformDropdown tracks internal
isModalShowingstate to prevent duplicateshowModal()calls when dependencies change. - Memoizing groups prevents the useEffect from re-triggering unnecessarily, which can cause modals to reopen after navigation.
- Dropdown states must be reset on modal dismiss to prevent them from reopening automatically when parent modal reopens.