Select is positioned incorrectly if is nested inside a portal
I have a drawer component that has a Portal components and it wraps the select component the first time i open the select, it is positioned at the bottom of the screen if i reopen it then it is correctly placed
Hey @Alvi24 , please provide a minimal reproduction repo
Hi @mrzachnugent: Here is a overall structure of my component:
<Drawer>
<Portal>
<View className="absolute h-screen bottom-0 translate-y-[60%]>
<Select/>
</View>
</Portal>
</Drawer>
1st time i open select component:
2nd time:
Unfortunately, I need a minimal reproduction repo to help.
I have experienced same issue in gorhom/bottom-sheet-modal component. Basically on first render of <SelectContent /> component it's a lot lower as it should be. @mrzachnugent
// _layout.tsx
function RootLayoutNav() {
return (
<ThemeProvider value={DefaultTheme}>
<GestureHandlerRootView>
<BottomSheetModalProvider>
<Slot />
</BottomSheetModalProvider>
<PortalHost />
</GestureHandlerRootView>
</ThemeProvider>
);
}
// task-filter-sheet.tsx
interface Disposable {
present: () => void;
}
const TaskFilterSheet = forwardRef<Disposable>((_, ref) => {
const { t } = useTranslation();
const bottomSheetRef = useRef<BottomSheetModal>(null);
const snapPoints = useMemo(() => [600], []);
const handleClose = () => {
if (!bottomSheetRef || !bottomSheetRef.current) return;
bottomSheetRef.current.dismiss();
};
useImperativeHandle(ref, () => ({
present: () => {
if (!bottomSheetRef.current) return;
bottomSheetRef.current.present();
},
}));
return (
<BottomSheetModal
name="task-filter"
ref={bottomSheetRef}
style={{ flex: 1 }}
snapPoints={snapPoints}
index={1}
backgroundComponent={(props) => (
<View className="bg-white rounded-2xl" {...props} />
)}
backdropComponent={(props) => (
<View
className="bg-black text-brand-primary opacity-10"
{...props}
/>
)}
handleComponent={() => null}
handleIndicatorStyle={{ backgroundColor: '#AC145A' }}
>
<BottomSheetView className="flex-1 gap-8 px-8 pt-5 pb-10">
<View className="flex-row items-center justify-between">
<H3 className="font-normal">{t('filter')}</H3>
</View>
<View className="gap-6">
<SortByFilter />
</View>
</BottomSheetView>
</BottomSheetModal>
);
});
// sort-by-filter.tsx
const SortByFilter = () => {
const { t } = useTranslation();
const sortBy = useTaskFilterStore((state) => state.sortBy);
const setSortBy = useTaskFilterStore((state) => state.setSortBy);
return (
<Select
onValueChange={(opt) =>
setSortBy((opt?.value as TaskFilterState['sortBy']) ?? null)
}
value={sortBy ? { value: sortBy, label: sortBy } : undefined}
>
<SelectTrigger
className={cn(
'border border-paragraph rounded-[4] h-14 flex-row items-center justify-between px-4',
)}
>
<Text
className={cn(
'absolute -top-[10] left-3 text-xs bg-white text-paragraph px-1',
)}
>
{t('sort')}
</Text>
{sortBy ? (
<Text className="text-brand-secondary">
{t(sortByLabels[sortBy])}
</Text>
) : (
<Text className="text-paragraph">{t('sort_task_by')}</Text>
)}
</SelectTrigger>
<SelectContent insets={{ top: 10, right: 10 }} align="end">
<SelectGroup>
{SORT_OPTIONS.map((value) => (
<SelectItem key={value} label={value} value={value}>
<Text>{t(sortByLabels[value])}</Text>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
);
};
I have experienced same issue in gorhom/bottom-sheet-modal component. Basically on first render of component it's a lot lower as it should be. @mrzachnugent
// _layout.tsx function RootLayoutNav() { return ( <ThemeProvider value={DefaultTheme}> <GestureHandlerRootView> <BottomSheetModalProvider> <Slot /> </BottomSheetModalProvider> <PortalHost /> </GestureHandlerRootView> </ThemeProvider> ); } // task-filter-sheet.tsx interface Disposable { present: () => void; } const TaskFilterSheet = forwardRef<Disposable>((_, ref) => { const { t } = useTranslation(); const bottomSheetRef = useRef<BottomSheetModal>(null); const snapPoints = useMemo(() => [600], []); const handleClose = () => { if (!bottomSheetRef || !bottomSheetRef.current) return; bottomSheetRef.current.dismiss(); }; useImperativeHandle(ref, () => ({ present: () => { if (!bottomSheetRef.current) return; bottomSheetRef.current.present(); }, })); return ( <BottomSheetModal name="task-filter" ref={bottomSheetRef} style={{ flex: 1 }} snapPoints={snapPoints} index={1} backgroundComponent={(props) => ( <View className="bg-white rounded-2xl" {...props} /> )} backdropComponent={(props) => ( <View className="bg-black text-brand-primary opacity-10" {...props} /> )} handleComponent={() => null} handleIndicatorStyle={{ backgroundColor: '#AC145A' }} > <BottomSheetView className="flex-1 gap-8 px-8 pt-5 pb-10"> <View className="flex-row items-center justify-between"> <H3 className="font-normal">{t('filter')}</H3> </View> <View className="gap-6"> <SortByFilter /> </View> </BottomSheetView> </BottomSheetModal> ); }); // sort-by-filter.tsx const SortByFilter = () => { const { t } = useTranslation(); const sortBy = useTaskFilterStore((state) => state.sortBy); const setSortBy = useTaskFilterStore((state) => state.setSortBy); return ( <Select onValueChange={(opt) => setSortBy((opt?.value as TaskFilterState['sortBy']) ?? null) } value={sortBy ? { value: sortBy, label: sortBy } : undefined} > <SelectTrigger className={cn( 'border border-paragraph rounded-[4] h-14 flex-row items-center justify-between px-4', )} > <Text className={cn( 'absolute -top-[10] left-3 text-xs bg-white text-paragraph px-1', )} > {t('sort')} </Text> {sortBy ? ( <Text className="text-brand-secondary"> {t(sortByLabels[sortBy])} </Text> ) : ( <Text className="text-paragraph">{t('sort_task_by')}</Text> )} </SelectTrigger> <SelectContent insets={{ top: 10, right: 10 }} align="end"> <SelectGroup> {SORT_OPTIONS.map((value) => ( <SelectItem key={value} label={value} value={value}> <Text>{t(sortByLabels[value])}</Text> </SelectItem> ))} </SelectGroup> </SelectContent> </Select> ); };
Me too
Please provide a minimal reproduction repo.
Closed due to missing reproduction repo. Should be fixed with latest update: https://reactnativereusables.com/docs/changelog#august-2025-fullwindowoverlay-ios