Open Bileeta123 opened 1 year ago
i encounter the same issue. in my case it seems that the flexDirection: 'row'
is causing the issue, when i remove it, the dropdown can scroll normally. still don't know what's the real problem yet
i encounter the same issue. in my case it seems that the
flexDirection: 'row'
is causing the issue, when i remove it, the dropdown can scroll normally. still don't know what's the real problem yet
Yes i also noticed that. It's working without flexbox. I dont no whether this is an RN issue or lib issue.
So, how did you guys solve that issue? Just remove flexDirection:'row' ?
Anyone found a solution for this? I need to display the dropdown next to a TextInput, so I can't just remove flexDirection: 'row'
hi @Bileeta123 ,
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', flex: 0.9, }}>
<Text>T....</Text>
<View style={{ flex:1 }}> // Add this line
<Dropdown
style={{
width: 90, borderWidth: 0.5, borderWidth: 1,
borderColor: '#0C453A',
borderRadius: 10,
minHeight: 40,
backgroundColor: 'white',
}}
placeholderStyle={{}}
selectedTextStyle={{}}
inputSearchStyle={{}}
iconStyle={{}}
data={tokenArr}
search
maxHeight={300}
minHeight={100}
labelField="TokenIdS"
valueField="Id"
searchField="TokenIdS"
placeholder={''}
searchPlaceholder="Search..."
value={selectedToken?.Id}
onFocus={() => setIsFocus(true)}
onBlur={() => setIsFocus(false)}
onChange={(item) => {
//setValue(item.value);
setSelectedToken(item)
//setIsFocus(false);
}}
/>
</View> // Add this line
<TouchableOpacity>
<Icon4/>
</TouchableOpacity>
</View>
You try wrapping outside dropdown can fix this problem?
hi @Bileeta123 ,
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', flex: 0.9, }}> <Text>T....</Text> <View style={{ flex:1 }}> // Add this line <Dropdown style={{ width: 90, borderWidth: 0.5, borderWidth: 1, borderColor: '#0C453A', borderRadius: 10, minHeight: 40, backgroundColor: 'white', }} placeholderStyle={{}} selectedTextStyle={{}} inputSearchStyle={{}} iconStyle={{}} data={tokenArr} search maxHeight={300} minHeight={100} labelField="TokenIdS" valueField="Id" searchField="TokenIdS" placeholder={''} searchPlaceholder="Search..." value={selectedToken?.Id} onFocus={() => setIsFocus(true)} onBlur={() => setIsFocus(false)} onChange={(item) => { //setValue(item.value); setSelectedToken(item) //setIsFocus(false); }} /> </View> // Add this line <TouchableOpacity> <Icon4/> </TouchableOpacity> </View>
You try wrapping outside dropdown can fix this problem?
It still can't scroll at right side of the screen . May be it is react native's issue ,but in ios it work.
If you inspect the dropdown when it is expanded, it looks like the scrollable view is placed to the left of the screen.
It is also a problem with other dropdown libaries, so maybe it is a React Native issue?
Guysss,any solution for this?
I end up making my own dropdown component
Can you please share your own custom-built component? I have been stuck with this dropdown component issues
it's just a basic implementation of the dropdown, but here you go.
import { FlatList, Modal, StyleSheet, View } from 'react-native';
import React, { memo, useCallback, useMemo, useRef, useState } from 'react';
import { RectButton } from 'react-native-gesture-handler';
import { Text } from './Themed';
import { Ionicons } from '@expo/vector-icons';
import { Colors } from '../constants';
import { Pressable } from 'react-native';
const ITEM_HEIGHT = 35;
const PickerItem = memo(
({
item,
labelStyle,
style,
activeStyle,
activeLabelStyle,
selected,
onChange
}) => (
<Pressable
android_ripple={{ color: Colors.ripple }}
style={[
styles.item,
style,
selected ? activeStyle || styles.itemActive : {}
]}
onPress={() => {
onChange(item);
}}
>
<Text
style={[
styles.itemLabel,
labelStyle,
selected ? activeLabelStyle || styles.itemLabelActive : {}
]}
numberOfLines={1}
>
{item.label}
</Text>
</Pressable>
),
({ item: p, selected: s1 }, { item: n, selected: s2 }) =>
p.label === n.label && s1 === s2
);
const Picker = ({
items,
value,
setValue,
setLabel,
style,
iconStyle,
itemStyle,
labelStyle,
itemLabelStyle,
activeItemStyle,
activeLabelStyle,
offset = 5
}) => {
const view = useRef(null);
const list = useRef(null);
const [layout, setLayout] = useState(null);
const [visible, setVisible] = useState(false);
const current = useMemo(() => {
const index = items.findIndex(({ value: v }) => v === value);
return {
index,
label: items[index].label
};
}, [value]);
const openModal = () => {
setVisible(true);
onLayout();
};
const closeModal = () => {
setVisible(false);
};
const onValueChange = useCallback(({ label, value }) => {
setLabel(label);
setValue(value);
closeModal();
}, []);
const renderItem = ({ item }) => (
<PickerItem
item={item}
style={itemStyle}
labelStyle={itemLabelStyle}
activeStyle={activeItemStyle}
activeLabelStyle={activeLabelStyle}
selected={value === item.value}
onChange={onValueChange}
/>
);
const keyExtractor = ({ label }) => label;
const onLayout = () => {
view.current?.measure((fx, fy, width, height, x, y) => {
if (!x || layout?.trusty) return;
setLayout({
trusty: !!layout,
height,
width,
x,
y: height + y + offset - 10
});
});
};
const getItemLayout = (_, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index
});
const layoutStyle = useMemo(
() => ({
position: 'absolute',
top: layout?.y ?? 0,
left: layout?.x ?? 0,
width: layout?.width,
maxHeight: 300
}),
[layout]
);
return (
<View ref={view} onLayout={onLayout}>
<RectButton
style={[styles.button, style]}
rippleColor={Colors.ripple}
onPress={openModal}
>
<Text style={[styles.label, labelStyle]} numberOfLines={1}>
{current?.label}
</Text>
<Ionicons name='caret-down' style={[styles.icon, iconStyle]} />
</RectButton>
<Modal
visible={visible}
onRequestClose={closeModal}
transparent
statusBarTranslucent
>
<Pressable style={styles.backdrop} onPress={closeModal} />
<View style={[styles.listContainer, layoutStyle]}>
<FlatList
ref={list}
data={items}
renderItem={renderItem}
keyExtractor={keyExtractor}
initialNumToRender={10}
contentContainerStyle={styles.contentContainer}
showsVerticalScrollIndicator={false}
getItemLayout={getItemLayout}
initialScrollIndex={current.index}
/>
</View>
</Modal>
</View>
);
};
export default Picker;
const styles = StyleSheet.create({
button: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 15,
paddingVertical: 10
},
label: {
flex: 1,
fontSize: 10,
color: Colors.secondary
},
icon: {
fontSize: 10,
color: Colors.secondary
},
backdrop: {
flex: 1
},
listContainer: {
borderRadius: 10,
overflow: 'hidden',
backgroundColor: Colors.card,
elevation: 2
},
contentContainer: { paddingVertical: 5 },
item: {
paddingHorizontal: 10,
justifyContent: 'center',
height: ITEM_HEIGHT
},
itemLabel: {
color: Colors.secondary,
fontSize: 10
},
itemActive: { backgroundColor: Colors.primary },
itemLabelActive: { color: Colors.text }
});
it's kinda customizable, but lot of hard coded styling
Facing same issue. any fixes available ?
`import React, {FC, ReactElement, useRef, useState} from 'react'; import { FlatList, StyleSheet, Text, TouchableOpacity, Modal, View, FlatListProps, Platform, } from 'react-native'; import theme from '../utils/theme'; import Icon from 'react-native-vector-icons/FontAwesome5'; import InputSearch from './InputSearch';
interface Props { labelField?: string; data: Array
const AutoComplete: FC
const toggleDropdown = (): void => { visible ? setVisible(false) : openDropdown(); };
const openDropdown = (): void => { if (DropdownButton && DropdownButton?.current) { DropdownButton.current?.measure((_fx, _fy, _w, h, _px, py) => { if (!py || !h) { return; } if (Platform.OS === 'ios') { setDropdownTop(py + h); } else { setDropdownTop(py + 20); } }); setVisible(true); setLayoutLoaded(true); } };
const onItemPress = (item): void => { setSelected(item); onSelect(item); setVisible(false); };
const filteredOptions = data.filter((option: any) =>
// convert to string in case of type error
${option[labelField]}
.toLowerCase()
?.includes(${inputValue}
.toLowerCase()),
);
const renderItem = ({item}): ReactElement<any, any> => ( <TouchableOpacity style={styles.item} onPress={() => onItemPress(item)}>
</TouchableOpacity>
);
const renderDropdown = (): ReactElement<any, any> => { return (
);
};
return ( <TouchableOpacity ref={DropdownButton} style={[styles.button, style]} onPress={toggleDropdown}>
<Icon name="angle-down" size={20} />
{layoutLoaded && renderDropdown()}
</TouchableOpacity>
); };
const styles = StyleSheet.create({ button: { height: 50, flexDirection: 'row', alignItems: 'center', backgroundColor: theme.white, borderRadius: 5, paddingHorizontal: 10, justifyContent: 'space-between', zIndex: 1, }, buttonText: { marginLeft: 5, }, dropdown: { position: 'absolute', backgroundColor: theme.white, width: '100%', shadowColor: '#000000', shadowRadius: 4, shadowOffset: {height: 3, width: 0}, maxHeight: 300, shadowOpacity: 0.5, paddingHorizontal: 10, }, overlay: { width: '100%', height: '100%', }, item: { paddingHorizontal: 10, paddingVertical: 10, //borderBottomWidth: 1, }, });
export default AutoComplete;`
Here is my solution.End up with writing custom but this solution also has issue that is for the first time dropdown picker appear suddenly drop from top but after it appear excepted.if you found the solution for that issue, please point on that.
This is my view hierarchy looks like,
`<View style={{flexDirection: 'row', flex: 1.2}}> <View style={{ flexDirection: 'row', flex: 1, alignItems: 'center', justifyContent: 'center' }}> <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', flex: 0.8, }}> <Text>.....</Text> <TouchableOpacity> <TextInput /> </TouchableOpacity> </View> <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', flex: 0.9, }}> <Text>T....</Text> <Dropdown style={{ width: 90, borderWidth: 0.5, borderWidth: 1, borderColor: '#0C453A', borderRadius: 10, minHeight: 40, backgroundColor: 'white', }} placeholderStyle={{}} selectedTextStyle={{}} inputSearchStyle={{}} iconStyle={{}} data={tokenArr} search maxHeight={300} minHeight={100} labelField="TokenIdS" valueField="Id" searchField="TokenIdS" placeholder={''} searchPlaceholder="Search..." value={selectedToken?.Id} onFocus={() => setIsFocus(true)} onBlur={() => setIsFocus(false)} onChange={(item) => { //setValue(item.value); setSelectedToken(item) //setIsFocus(false); }} /> <TouchableOpacity> <Icon4/> </TouchableOpacity> </View> </View> <View style={{ flexDirection: 'row', flex: 0.91, alignItems: 'center'}}> <View> <View> <Icon1/> <Text>.....</Text> <Text>.....</Text> </View> <View> </View> <View> <Icon2/> <Text>.....</Text> <Text>.....</Text> </View> </View> <View> <Button> ...... </Button> </View> </View> </View>`
Drop down opens but cannot scroll it. But if i move the dropdown top of the hierarchy, as the first ui component of the parent view, it's working. Anyone know a fix?
"react-native": "0.71.2" "react-native-element-dropdown": "^2.8.0" "react-native-gesture-handler": "^2.9.0"
It's a bug from the package it self. Please install the version <= 2.5.3.
I was having a similar issue using the MultiSelect
component but for Android only.
I've created a patch with the solution in this related issue.
It might be helpful to solve the issue with the Dropdown
component as well.
I encountered the same issue when I wrapped the Dropdown component with a view using 'flex-direction: row
Here are two solutions that have worked for me:
1 -Modify the _measure function to include the pageX value:
const _measure = useCallback(() => {
if (ref && ref?.current) {
ref.current.measureInWindow((pageX, pageY, width, height) => {
const isFull = isTablet
? false
: mode === 'modal' || orientation === 'LANDSCAPE';
const top = isFull ? 20 : height + pageY + 2;
const bottom = H - top + height;
const left = I18nManager.isRTL ? W - width - pageX : pageX;
setPosition({
isFull,
width: Math.floor(width + pageX), // Added pageX
top: Math.floor(top + statusBarHeight),
bottom: Math.floor(bottom - statusBarHeight),
left: Math.floor(left),
height: Math.floor(height),
});
});
}
}, [H, W, orientation, mode]);
2 - Modify the _renderModal function to replace the width property with flex: 1:
<View
style={StyleSheet.flatten([
styles.flex1,
{
flex: 1, // added
},
!isTopPosition
? { paddingTop: extendHeight }
: {
justifyContent: 'flex-end',
paddingBottom: extendHeight,
},
isFull && styles.fullScreen,
])}
>
I encountered the same issue when I wrapped the Dropdown component with a view using 'flex-direction: row
Here are two solutions that have worked for me:
1 -Modify the _measure function to include the pageX value:
const _measure = useCallback(() => { if (ref && ref?.current) { ref.current.measureInWindow((pageX, pageY, width, height) => { const isFull = isTablet ? false : mode === 'modal' || orientation === 'LANDSCAPE'; const top = isFull ? 20 : height + pageY + 2; const bottom = H - top + height; const left = I18nManager.isRTL ? W - width - pageX : pageX; setPosition({ isFull, width: Math.floor(width + pageX), // Added pageX top: Math.floor(top + statusBarHeight), bottom: Math.floor(bottom - statusBarHeight), left: Math.floor(left), height: Math.floor(height), }); }); } }, [H, W, orientation, mode]);
2 - Modify the _renderModal function to replace the width property with flex: 1:
<View style={StyleSheet.flatten([ styles.flex1, { flex: 1, // added }, !isTopPosition ? { paddingTop: extendHeight } : { justifyContent: 'flex-end', paddingBottom: extendHeight, }, isFull && styles.fullScreen, ])} >
Thanks pro!
+1
_renderModal
Are you changing the package itself?
I encountered the same issue when I wrapped the Dropdown component with a view using 'flex-direction: row Here are two solutions that have worked for me: 1 -Modify the _measure function to include the pageX value:
const _measure = useCallback(() => { if (ref && ref?.current) { ref.current.measureInWindow((pageX, pageY, width, height) => { const isFull = isTablet ? false : mode === 'modal' || orientation === 'LANDSCAPE'; const top = isFull ? 20 : height + pageY + 2; const bottom = H - top + height; const left = I18nManager.isRTL ? W - width - pageX : pageX; setPosition({ isFull, width: Math.floor(width + pageX), // Added pageX top: Math.floor(top + statusBarHeight), bottom: Math.floor(bottom - statusBarHeight), left: Math.floor(left), height: Math.floor(height), }); }); } }, [H, W, orientation, mode]);
2 - Modify the _renderModal function to replace the width property with flex: 1:
<View style={StyleSheet.flatten([ styles.flex1, { flex: 1, // added }, !isTopPosition ? { paddingTop: extendHeight } : { justifyContent: 'flex-end', paddingBottom: extendHeight, }, isFull && styles.fullScreen, ])} >
Thanks pro!
How can you modified it inside node_modules
I encountered the same issue when I wrapped the Dropdown component with a view using 'flex-direction: row Here are two solutions that have worked for me: 1 -Modify the _measure function to include the pageX value:
const _measure = useCallback(() => { if (ref && ref?.current) { ref.current.measureInWindow((pageX, pageY, width, height) => { const isFull = isTablet ? false : mode === 'modal' || orientation === 'LANDSCAPE'; const top = isFull ? 20 : height + pageY + 2; const bottom = H - top + height; const left = I18nManager.isRTL ? W - width - pageX : pageX; setPosition({ isFull, width: Math.floor(width + pageX), // Added pageX top: Math.floor(top + statusBarHeight), bottom: Math.floor(bottom - statusBarHeight), left: Math.floor(left), height: Math.floor(height), }); }); } }, [H, W, orientation, mode]);
2 - Modify the _renderModal function to replace the width property with flex: 1:
<View style={StyleSheet.flatten([ styles.flex1, { flex: 1, // added }, !isTopPosition ? { paddingTop: extendHeight } : { justifyContent: 'flex-end', paddingBottom: extendHeight, }, isFull && styles.fullScreen, ])} >
Thanks pro!
How can you modified it inside node_modules
Bạn bấm ctrl rồi click vào Dropdown thì sẽ đến component của Dropdown thì bạn tìm đến đoạn được note ở trên để sửa
I encountered the same issue when I wrapped the Dropdown component with a view using 'flex-direction: row
Here are two solutions that have worked for me:
1 -Modify the _measure function to include the pageX value:
const _measure = useCallback(() => { if (ref && ref?.current) { ref.current.measureInWindow((pageX, pageY, width, height) => { const isFull = isTablet ? false : mode === 'modal' || orientation === 'LANDSCAPE'; const top = isFull ? 20 : height + pageY + 2; const bottom = H - top + height; const left = I18nManager.isRTL ? W - width - pageX : pageX; setPosition({ isFull, width: Math.floor(width + pageX), // Added pageX top: Math.floor(top + statusBarHeight), bottom: Math.floor(bottom - statusBarHeight), left: Math.floor(left), height: Math.floor(height), }); }); } }, [H, W, orientation, mode]);
2 - Modify the _renderModal function to replace the width property with flex: 1:
<View style={StyleSheet.flatten([ styles.flex1, { flex: 1, // added }, !isTopPosition ? { paddingTop: extendHeight } : { justifyContent: 'flex-end', paddingBottom: extendHeight, }, isFull && styles.fullScreen, ])} >
This is definitely not maintainable in the long-term, but an interesting solution nonetheless.
This is my view hierarchy looks like,
Drop down opens but cannot scroll it. But if i move the dropdown top of the hierarchy, as the first ui component of the parent view, it's working. Anyone know a fix?
"react-native": "0.71.2" "react-native-element-dropdown": "^2.8.0" "react-native-gesture-handler": "^2.9.0"