How can I put an icon inside a TextInput in React Native?
JavascriptReact NativeJavascript Problem Overview
I am thinking of having something like this https://android-arsenal.com/details/1/3941 where you have icon that you press to show password as plaintext, not as dots. However, I was unable to find any custom component that would help me.
I don't want to put too much time on such a minor feature, so I'm asking without having attempted anything yet: Is there a custom component I've missed? If not, is there a simple way to add children to TextInput? Or should I just have TextInput and Touchable side by side?
Javascript Solutions
Solution 1 - Javascript
You can use combination of View, Icon and TextInput like so:
<View style={styles.searchSection}>
<Icon style={styles.searchIcon} name="ios-search" size={20} color="#000"/>
<TextInput
style={styles.input}
placeholder="User Nickname"
onChangeText={(searchString) => {this.setState({searchString})}}
underlineColorAndroid="transparent"
/>
</View>
and use flex-direction for styling
searchSection: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
searchIcon: {
padding: 10,
},
input: {
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 0,
backgroundColor: '#fff',
color: '#424242',
},
Icons were taken from "react-native-vector-icons"
Solution 2 - Javascript
Basically you can’t put an icon inside of a textInput but you can fake it by wrapping it inside a view and setting up some simple styling rules.
Here's how it works:
-
put both Icon and TextInput inside a parent View
-
set flexDirection of the parent to ‘row’ which will align the children next to each other
-
give TextInput flex 1 so it takes the full width of the parent View
-
give parent View a borderBottomWidth and push this border down with paddingBottom (this will make it appear like a regular textInput with a borderBottom)
-
(or you can add any other style depending on how you want it to look)
Code:
<View style={styles.passwordContainer}>
<TextInput
style={styles.inputStyle}
autoCorrect={false}
secureTextEntry
placeholder="Password"
value={this.state.password}
onChangeText={this.onPasswordEntry}
/>
<Icon
name='what_ever_icon_you_want'
color='#000'
size={14}
/>
</View>
Style:
passwordContainer: {
flexDirection: 'row',
borderBottomWidth: 1,
borderColor: '#000',
paddingBottom: 10,
},
inputStyle: {
flex: 1,
},
(Note: the icon is underneath the TextInput so it appears on the far right, if it was above TextInput it would appear on the left.)
Solution 3 - Javascript
This is working for me in ReactNative 0.60.4
View
<View style={styles.SectionStyle}>
<Image
source={require('../assets/images/ico-email.png')} //Change your icon image here
style={styles.ImageStyle}
/>
<TextInput
style={{ flex: 1 }}
placeholder="Enter Your Name Here"
underlineColorAndroid="transparent"
/>
</View>
Styles
SectionStyle: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
borderWidth: 0.5,
borderColor: '#000',
height: 40,
borderRadius: 5,
margin: 10,
},
ImageStyle: {
padding: 10,
margin: 5,
height: 25,
width: 25,
resizeMode: 'stretch',
alignItems: 'center',
}
Solution 4 - Javascript
In case is useful I share what I find a clean solution:
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
onChangeText={(text) => onChange(text)}
value={value}
/>
<Icon style={styles.icon} name="your-icon" size={20} />
</View>
and then in your css
inputContainer: {
justifyContent: 'center',
},
input: {
height: 50,
},
icon: {
position: 'absolute',
right: 10,
}
Solution 5 - Javascript
You can use this module which is easy to use: https://github.com/halilb/react-native-textinput-effects
Solution 6 - Javascript
You can wrap your TextInput
in View
.
and dynamically calculate width, if you want add an icon,
iconWidth = 0.05*viewWidth
textInputWidth = 0.95*viewWidth
otherwise textInputwWidth = viewWidth
.
View
and TextInput
background color are both white. (Small hack)
Solution 7 - Javascript
import { TextInput } from 'react-native-paper';
<TextInput
label="Password"
secureTextEntry
right={<TextInput.Icon name="eye" />}
/>
Solution 8 - Javascript
//This is an example code to show Image Icon in TextInput//
import React, { Component } from 'react';
//import react in our code.
import { StyleSheet, View, TextInput, Image } from 'react-native';
//import all the components we are going to use.
export default class App extends Component<{}> {
render() {
return (
<View style={styles.container}>
<View style={styles.SectionStyle}>
<Image
//We are showing the Image from online
source={{uri:'http://aboutreact.com/wp-content/uploads/2018/08/user.png',}}
//You can also show the image from you project directory like below
//source={require('./Images/user.png')}
//Image Style
style={styles.ImageStyle}
/>
<TextInput
style={{ flex: 1 }}
placeholder="Enter Your Name Here"
underlineColorAndroid="transparent"
/>
</View>
<View style={styles.SectionStyle}>
<Image
//We are showing the Image from online
source={{uri:'http://aboutreact.com/wp-content/uploads/2018/08/phone.png',}}
//You can also show the image from you project directory like below
//source={require('./Images/phone.png')}
//Image Style
style={styles.ImageStyle}
/>
<TextInput
style={{ flex: 1 }}
placeholder="Enter Your Mobile No Here"
underlineColorAndroid="transparent"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 10,
},
SectionStyle: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
borderWidth: 0.5,
borderColor: '#000',
height: 40,
borderRadius: 5,
margin: 10,
},
ImageStyle: {
padding: 10,
margin: 5,
height: 25,
width: 25,
resizeMode: 'stretch',
alignItems: 'center',
},
});
Solution 9 - Javascript
Anyone who's struggling on this
you can try to follow mine also
<View style={{flex:1}}>
<KeyboardAvoidingView enabled>
<View style={{flexDirection:'row',paddingBottom:5, borderColor:'#ccc',borderBottomWidth:1}}>
<TextInput
style={{flex:1}}
onChangeText={(UserEmail) => setUserEmail(userEmail)}
placeholder="Password"
placeholderTextColor="#ccc"
autoCapitalize="none"
keyboardType="default"
returnKeyType="next"
ref={passwordInputRef}
onSubmitEditing={Keyboard.dismiss}
blurOnSubmit={false}
/>
<FontAwesome5 name={"eye"} size={25} style={{alignSelf:'center'}}/>
</View>
</KeyboardAvoidingView>
</View>
Solution 10 - Javascript
Here you have an example I took from my own project, i have just removed what i thought we didnt need for the example.
import React, { Component } from 'react';
import {
Text,
TouchableOpacity,
View,
StyleSheet,
Dimensions,
Image
} from 'react-native';
class YourComponent extends Component {
constructor(props) {
super(props);
this._makeYourEffectHere = this._makeYourEffectHere.bind(this);
this.state = {
showPassword: false,
image: '../statics/showingPassImage.png'
}
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={this._makeYourEffectHere}>
<Text>button</Text>
<Image style={styles.image} source={require(this.state.image)}></Image>
</TouchableOpacity>
<TextInput password={this.state.showPassword} style={styles.input} value="abc" />
</View>
);
}
_makeYourEffectHere() {
var png = this.state.showPassword ? '../statics/showingPassImage.png' : '../statics/hidingPassImage.png';
this.setState({showPassword: !this.state.showPassword, image: png});
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
flexDirection: 'column',
alignItems: 'center',
},
button: {
width: Dimensions.get('window').width * 0.94,
height: 40,
backgroundColor: '#3b5998',
marginTop: Dimensions.get('window').width * 0.03,
justifyContent: 'center',
borderRadius: Dimensions.get('window').width * 0.012
},
image: {
width: 25,
height: 25,
position: 'absolute',
left: 7,
bottom: 7
},
input: {
width: Dimensions.get('window').width * 0.94,
height: 30
}
});
module.exports = YourComponent;
I hope It helps you.
Let me know if it was useful.
Solution 11 - Javascript
you can also do something more specific like that based on Anthony Artemiew's response:
<View style={globalStyles.searchSection}>
<TextInput
style={globalStyles.input}
placeholder="Rechercher"
onChangeText={(searchString) =>
{this.setState({searchString})}}
underlineColorAndroid="transparent"
/>
<Ionicons onPress={()=>console.log('Recherche en cours...')} style={globalStyles.searchIcon} name="ios-search" size={30} color="#1764A5"/>
</View>
Style:
searchSection: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
borderRadius:50,
marginLeft:35,
width:340,
height:40,
margin:25
},
searchIcon: {
padding: 10,
},
input: {
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 0,
marginLeft:10,
borderTopLeftRadius:50,
borderBottomLeftRadius:50,
backgroundColor: '#fff',
color: '#424242',
},