'react-native-web picker strange behavior on web mobile
We're using react-native-web which allows for reactJS and react-native in one codebase. Form components can be tricky in getting them to work for web, mobile web and native. We're using Picker for a dropdown menu on a modal form and so far it works in full web and native but on mobile web, the drop down menu placement is above and to the side of the actual picker. Is there a way to force it to use the device selector at a certain screen size?
Here's an example of our reusable selector component:
import React, { useState, useEffect } from 'react'
import {
View,
Text,
Platform,
TextInputProps,
StyleSheet,
ViewStyle,
StyleProp,
} from 'react-native'
import { isAndroid } from 'shared/util/style'
import { withTranslation, WithTranslation } from 'react-i18next'
// @ts-ignore
import Picker from 'shared/components/Picker'
// @ts-ignore
import Tooltip from 'shared/components/Tooltip'
import { fonts, colors, isIE } from '../util/style'
const styles = StyleSheet.create({
container: {
paddingTop: 10,
paddingBottom: 6,
width: '100%',
},
label: {
...fonts.regularSemibold,
color: colors.black,
marginBottom: 6,
},
bottomContainer: {
flexDirection: 'row',
alignItems: 'center',
paddingTop: 5,
},
errorText: {
...fonts.bodyRegular,
color: colors.orange,
fontWeight: '100',
},
picker: {
backgroundColor: colors.white,
borderWidth: 0,
padding: 10,
width: '100%',
height: isIE ? 'auto' : 60,
...fonts.bodyRegular,
},
pickerIOS: {
width: '100%',
},
pickerText: {
...fonts.bodyRegular,
color: 'blue',
},
})
type AccessibleSelectProps = TextInputProps & {
readonly label?: string
readonly onValueChange: any
readonly defaultValue?: string | undefined | null | number
readonly fieldError?: string
readonly refToAttachToInput?: any
readonly additionalContainerStyles?: StyleProp<ViewStyle>
readonly inputStyle?: any
readonly leftButtonIcon?: number
readonly onFocus?: (event: any) => void
readonly options: Array<{ label: string; value: string }>
readonly selectedValue: string | number | undefined
readonly tooltipText?: string
readonly tooltipContent?: string
readonly tooltipPlacement?: string
} & WithTranslation
const AccessibleSelect = ({
onValueChange,
selectedValue,
defaultValue,
fieldError,
label,
additionalContainerStyles,
options,
refToAttachToInput,
inputStyle,
tooltipText,
tooltipContent,
tooltipPlacement,
}: AccessibleSelectProps) => {
const [borderColor, setBorderColor] = useState(colors.grey1)
const checkError = () => {
if (fieldError) {
setBorderColor(colors.orange)
}
}
useEffect(checkError, [fieldError])
return (
<View style={[styles.container, additionalContainerStyles]}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<Text style={styles.label}>{label}</Text>
<Tooltip
text={tooltipText}
content={tooltipContent}
placement={tooltipPlacement}
/>
</View>
<Picker
ref={refToAttachToInput}
style={[
Platform.OS === 'ios'
? styles.pickerIOS
: [
styles.picker,
{ borderColor, borderStyle: 'solid', borderWidth: 1 },
],
inputStyle,
]}
selectedValue={selectedValue}
onValueChange={onValueChange}
defaultValue={defaultValue && defaultValue}
itemStyle={styles.pickerText}
mode={isAndroid && 'dropdown'}
>
{options.map((o) => (
<Picker.Item label={o.label} key={o.value} value={o.value} />
))}
</Picker>
<View
style={[
styles.bottomContainer,
{ justifyContent: fieldError ? 'space-between' : 'flex-end' },
]}
>
{!!fieldError && (
<Text accessibilityLiveRegion="assertive" style={styles.errorText}>
{fieldError}
</Text>
)}
</View>
</View>
)
}
export default withTranslation('Login')(AccessibleSelect)
The Picker component is imported in 2 ways: 1 for native and 1 for web:
For Native:
import { Picker } from '@react-native-picker/picker'
export default Picker
For Web:
import { Picker } from 'react-native'
export default Picker
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|

