React-native-paper: How to link picker component to the Text input UI component of React Paper?

Created on 22 Oct 2018  路  10Comments  路  Source: callstack/react-native-paper


Current behaviour

Currently I'm using react paper outlined text input component layout. Is there any picker component available in your libraries as it is not mentioned in the documentation. The default picker component UI causes inconsistency. Therefore , is it possible to link the picker when then text input is on focus?

If yes, then please provide the code snippet.

Most helpful comment

I don't know if this is a good approach but here's how I did it:

<TextInput
    label="City"
    mode="outlined"
    value={this.state.city}
    render={(props) => (
        <Picker
            selectedValue={this.state.city}
            onValueChange={(itemValue, itemIndex) => {
                this.setState({ city: itemValue });
            }}
            style={{ height: 54, marginTop: 10 }}
        >
            {this.renderCityItems()}
        </Picker>
    )}
/>

Note that I had to set both value and selectedValue to work and do a little styling on Picker component.

All 10 comments

Ah, This page is to track issue not to help people try posting this same message in discord channel of Callstack.

@raajnadar Its more like a required feature enhancement if not available.

@ManigandanRaamanathan You can submit PR that implements such Picker and follow Material Design Guidelines.

I don't know if this is a good approach but here's how I did it:

<TextInput
    label="City"
    mode="outlined"
    value={this.state.city}
    render={(props) => (
        <Picker
            selectedValue={this.state.city}
            onValueChange={(itemValue, itemIndex) => {
                this.setState({ city: itemValue });
            }}
            style={{ height: 54, marginTop: 10 }}
        >
            {this.renderCityItems()}
        </Picker>
    )}
/>

Note that I had to set both value and selectedValue to work and do a little styling on Picker component.

I don't know if this is a good approach but here's how I did it:

<TextInput
  label="City"
  mode="outlined"
  value={this.state.city}
  render={(props) => (
      <Picker
          selectedValue={this.state.city}
          onValueChange={(itemValue, itemIndex) => {
              this.setState({ city: itemValue });
          }}
          style={{ height: 54, marginTop: 10 }}
      >
          {this.renderCityItems()}
      </Picker>
  )}
/>

Note that I had to set both value and selectedValue to work and do a little styling on Picker component.

Tried your method. worked perfectly. I just removed the label prop cuz it was bugging the textinput. and tweaked the style of picker. Thanks for sharing.

I don't know if this is a good approach but here's how I did it:

<TextInput
    label="City"
    mode="outlined"
    value={this.state.city}
    render={(props) => (
        <Picker
            selectedValue={this.state.city}
            onValueChange={(itemValue, itemIndex) => {
                this.setState({ city: itemValue });
            }}
            style={{ height: 54, marginTop: 10 }}
        >
            {this.renderCityItems()}
        </Picker>
    )}
/>

Note that I had to set both value and selectedValue to work and do a little styling on Picker component.

Tried your method. worked perfectly. I just removed the label prop cuz it was bugging the textinput. and tweaked the style of picker. Thanks for sharing.

Did not work; maybe this solution is deprecated?

For anyone searching a solution, the solution from @majugurci is outdate, but the solution I used is very similar.

  1. Install the react-native-picker-select

  2. This is the code I used:

import React from 'react';
import {StyleSheet} from 'react-native';
import RNPickerSelect from 'react-native-picker-select';
import {theme} from '../../styles/theme.js';
import Icon from 'react-native-vector-icons/Entypo.js';
import {TextInput} from 'react-native-paper';
Icon.loadFont();

export const Picker = ({value, onValueChange, label, items}) => {
    return (
        <TextInput
            mode="outlined"
            label={label}
            value={value}
            render={() => (
                <RNPickerSelect
                    items={items}
                    selectedValue={value}
                    onValueChange={onValueChange}
                    placeholder={{label: '', value: ''}}
                    useNativeAndroidPickerStyle={false}
                    style={pickerStyles}
                    Icon={() => (
                        <Icon name="chevron-down" size={24} color="gray" />
                    )}
                />
            )}
        />
    );
};

const pickerStyles = StyleSheet.create({
    iconContainer: {
        justifyContent: 'center',
        height: '100%',
        marginRight: 5,
    },
    inputIOS: {
        fontSize: 16,
        height: 56,
        paddingHorizontal: 14,
        color: theme.colors.primary,
        textAlignVertical: 'center',
        width: '100%',
        paddingRight: 30, // to ensure the text is never behind the icon
    },
    inputAndroid: {
        fontSize: 16,
        height: 56,
        paddingHorizontal: 14,
        color: theme.colors.primary,
        textAlignVertical: 'center',
        width: '100%',
        paddingRight: 30, // to ensure the text is never behind the icon
    },
});

@otaviobps your solution is almost fantastic for me. The only issue is when I click on the TextInput to change the value with the picker, the TextInput outline no longer becomes colorful (which it usually does onFocus). Did this happen to you as well? If so, have you found a workaround?

Hey @grantackerman1 glad that my solution solved your problem. I usually use my components with Formik and it injects onFocus and onBlur to the bottom components.

What I did was pass all props to the TextInput:

import React from 'react';
import {StyleSheet} from 'react-native';
import {TextInput} from 'react-native-paper';
import RNPickerSelect from 'react-native-picker-select';
import Icon from 'react-native-vector-icons/Entypo.js';

import PropTypes from 'prop-types';

import {theme} from '../../styles/theme.js';
Icon.loadFont();

export const Picker = ({
    value,
    onValueChange,
    label,
    items,
    placeholder = {},
    ...rest
}) => {
    return (
        <TextInput
            mode="outlined"
            label={label}
            value={value}
            render={() => (
                <RNPickerSelect
                    items={items}
                    selectedValue={value}
                    onValueChange={onValueChange}
                    placeholder={placeholder}
                    useNativeAndroidPickerStyle={false}
                    style={pickerStyles}
                    Icon={() => (
                        <Icon name="chevron-down" size={24} color="gray" />
                    )}
                />
            )}
            {...rest}
        />
    );
};
Picker.propTypes = {
    value: PropTypes.any.isRequired,
    onValueChange: PropTypes.func.isRequired,
    label: PropTypes.string.isRequired,
    items: PropTypes.arrayOf(PropTypes.object).isRequired,
    placeholder: PropTypes.object,
};

const pickerStyles = StyleSheet.create({
    iconContainer: {
        justifyContent: 'center',
        height: '100%',
        marginRight: 5,
    },
    inputIOS: {
        fontSize: 16,
        height: 56,
        paddingHorizontal: 14,
        color: theme.colors.primary,
        textAlignVertical: 'center',
        width: '100%',
        paddingRight: 30, // to ensure the text is never behind the icon
    },
    inputAndroid: {
        fontSize: 16,
        height: 56,
        paddingHorizontal: 14,
        color: theme.colors.primary,
        textAlignVertical: 'center',
        width: '100%',
        paddingRight: 30, // to ensure the text is never behind the icon
    },
});

Do you see the ...rest prop and the {...rest} in the TextInput? This way I'm forwarding all other props to the TextInput, then it has the values of onBlur and onFocus from Formik

If you don't use Formik, then you might have to implement your own function to onBlur and onFocus

Thanks for your response @otaviobps. Unfortunately, I do not use Formik. Are you saying that within RNPickerSelect, I should use onOpen to call a function that focuses the the TextInput? If so, I unfortunately do not know how to do that, as I am pretty new to React Native (from what I've been reading, it looks like I might need to use the useRef hook, but I'm not sure). I would greatly appreciate any help you could offer but obviously understand if you're too busy.

What's strange to me is part of the TextInputs focus behavior is still happening when I click on it - specifically, the label moves to the border of the box when something is selected. The only thing missing is the color. Maybe it's possible that RNPickerSelect is overriding only the color and not the other aspects of react-native-paper TextInput's focused style?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yaronlevi picture yaronlevi  路  3Comments

talaikis picture talaikis  路  3Comments

zxccvvv picture zxccvvv  路  4Comments

makhataibar picture makhataibar  路  4Comments

sm2017 picture sm2017  路  4Comments