How to change color in Input from react native elements - react-native

I have an Input from react native elements which looks like this
<Input
placeholderTextColor={constants.inputPlaceholderFontColor}
inputContainerStyle={{marginTop: 30, borderBottomColor: constants.dimmedFontColor}}
placeholder='Spieleranzahl'
keyboardType='numeric'
leftIconContainerStyle={{marginRight: 10, marginBottom: 8}}
leftIcon={
<Icon
name='user'
size={ 24 }
color= {constants.iconColor}/>
}
onChangeText={input => this.setState({numberOfPlayers: input})}
I tried to set the color by
style={{color: 'white'}}
inputStyle={{color: 'white'}}
inputContainerStyle={{color: 'white'}}
The documentation says: "This component inherits all native TextInput props that come with a standard React Native TextInput element, along with the following..." so I dont understand why the style property doesn't work because it works with the standard TextInput component.
Also, the documentation says about inputStyle: "style that will be passed to the style props of the React Native TextInput" so that should also work because this is the way to set color on the standard Text component.
Am I missing something?

I've created an example on snack.expo and inputStyle works perfectly on both iOS and Android. Most probably there is another issue, that's why I would recommend to reimplement my simple example and see if it works.
Update: Maybe only your placeholdertext is shown. I can't see the place in your code, where you pass the value prop to your input.
Demo:
https://snack.expo.io/Yunjp2ozw
Output:
Code:
export default function App() {
const [text, setText] = React.useState('Test');
return (
<View style={styles.container}>
<Input
value={text}
onChangeText={(text) => setText(text)}
inputStyle={{'color': 'red'}}
/>
</View>
);
}

Related

Vertically align Pressable inside a Text component

<View
style={{
flexDirection: "row",
}}
>
<Text
style={{
flex: 1,
}}
>
By continuing, you agree to our{" "}
<Pressable
onPress={...}
>
<Text>
Terms of Service
</Text>
</Pressable>
</Text>
</View>
"Terms of Service" is printed higher than "By continuing, you agree to our". How do I vertically align them?
Or more precisely - how do I get the Pressable Text to vertically align to the bottom?
This is a bug in React Native itself. There are several open reports of this bug on React Native's GitHub, but the chances of it being fixed don't look good:
https://github.com/facebook/react-native/issues/30375 - for the general problem of Views nested in Text being mis-aligned on Android, and a core contributor responded, but appeared to get derailed and stuck in some details specific to mimicking superscript and subscript.
https://github.com/facebook/react-native/issues/31955 - specific to Pressable and someone posted a PR to fix it, but Facebook closed it because no-one from Facebook got around to reviewing it before it became stale and out of date with the main branch.
There's also some discussion in this issue comment, but the issue got closed.
In React Native >= 0.65, if your inline pressable element uses only text styles, you can work around this issue by using <Text> with onPress (and onPressIn and onPressOut to style the pressed state). Crude example:
/**
* Like a simplified Pressable that doesn't look broken inline in `Text` on Android
*/
const TextButton = ({ children, onPress, style, ...rest } => {
const [pressed, setPressed] = useState(false)
const onPressIn = () => setPressed(true)
const onPressOut = () => setPressed(false)
return (
<Text
onPress={onPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
style={typeof style === 'function' ? style({ pressed }) : style}
{...rest}
>
{typeof children === 'function' ? children({ pressed }) : children}
</Text>
)
}
Beware, however, that there are also bugs around selecting interactive elements nested inside text using accessibility tools. If you can simply avoid nesting the interactive element in text, and have it on its own line, that's probably better: link-like interactive nested text isn't well supported in React Native currently.
On older versions of React Native before 0.65, Text didn't support onPressIn or onPressOut:
If you don't need Pressable's pressed state, use Text instead of Pressable (as the asker did: https://stackoverflow.com/a/66590787/568458)
If you do need pressed state, Text doesn't support the required onPressIn/Out handlers. However, TouchableWithoutFeedback does support those, and works by injecting props into its child so the Text will remain Text with no wrapping View. Wrap a Text in TouchableWithoutFeedback and pass the touchable onPress with onPressIn and onPressOut handlers and store the pressed state yourself.
/**
* Like a simplified Pressable that doesn't look broken inline in `Text` on Android
*/
const TextButton = ({ children, onPress, style, ...rest } => {
const [pressed, setPressed] = useState(false)
const onPressIn = () => setPressed(true)
const onPressOut = () => setPressed(false)
// TouchableWithoutFeedback modifies and returns its child; this returns `Text`
// plus press in/out events attached that aren't supported by Text directly.
return (
<TouchableWithoutFeedback
onPress={onPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
>
<Text
style={typeof style === 'function' ? style({ pressed }) : style}
{...rest}
>
{typeof children === 'function' ? children({ pressed }) : children}
</Text>
</TouchableWithoutFeedback>
)
}
Warning: if you're also using React Native Web and React Navigation, don't use the TouchableWithoutFeedback approach on Web, use pure Pressable on web, because React Navigation's navigate functions don't reliably work when passed to Touchable*s on Web due to a quirk of how the event handlers are set up (but they do work in Pressable), and this issue doesn't exist on Web.
Ended up doing this differently, using the onPress property of the <Text> component and finally wrapping all <Text> components in another <Text> component to have a proper line break:
<View>
<Text>
<Text>
By continuing, you agree to our{" "}
</Text>
<Text onPress={() => {...}}>
Terms of Service
</Text>
<Text>
{" "}and our{" "}
</Text>
<Text onPress={() => {...}}>
Privacy Policy
</Text>
</Text>
</View>
The snippet below should work but hard to understand without giving a shot. If you can provide screenshots I can help more in sake of getting a more proper result.
<View>
<Text style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
}}>
By continuing, you agree to our{" "}
<Pressable
onPress={() => {
navigate("LegalStack", { screen: "Terms" });
}}
>
<Text style={{margin: 'auto'}}>
Terms of Service
</Text>
</Pressable>
</Text>
</View>
I found a very hackidy-hack solution...
<Text selectable={true}>
<Text>if you click</Text>
<TouchableOpacity
style={{flexDirection: 'row'}}
onPress={() => Linking.openURL("https://www.google.com")}
>
<Text
style={{
alignSelf: 'flex-end',
marginBottom: -4,
}}
>
here
</Text>
</TouchableOpacity>
<Text>, it will open google</Text>
</Text>
By default the flexDirection is column. Change it to flexDirection:"row"

What is an alternative of textarea in react-native?

Is there any built in text area component for react-native? I have tried to implement these ones:
https://github.com/buildo/react-autosize-textarea
https://github.com/andreypopp/react-textarea-autosize
but getting an error "Expected a component class got object object".
Yes there is. It's called TextInput, the normal TextInput Component supports multiple lines.
Just assign following properties to your TextInput Component
multiline = {true}
numberOfLines = {4}
At the end you should have this:
<TextInput
multiline={true}
numberOfLines={4}
onChangeText={(text) => this.setState({text})}
value={this.state.text}/>
Source https://facebook.github.io/react-native/docs/textinput
If you want to see your TextInput component like a textarea, you will need to add this
<TextInput
multiline={true}
numberOfLines={10}
style={{ height:200, textAlignVertical: 'top',}}/>
I build text areas in react-native by wrapping a TextInput component into a View the following way:
<View style={styles.textAreaContainer} >
<TextInput
style={styles.textArea}
underlineColorAndroid="transparent"
placeholder="Type something"
placeholderTextColor="grey"
numberOfLines={10}
multiline={true}
/>
</View>
...
const styles = StyleSheet.create({
textAreaContainer: {
borderColor: COLORS.grey20,
borderWidth: 1,
padding: 5
},
textArea: {
height: 150,
justifyContent: "flex-start"
}
})
I am using this component:
https://www.npmjs.com/package/react-native-autogrow-textinput
It expands automatically on-text growth. I created my own reusable component with the autogrow-textinput as part of it, which inside the component looks like that:
<AutoGrowingTextInput
minHeight={40}
maxHeight={maxHeight} // this is a flexible value that I set in my
component, where I use this reusable component, same below, unless specified the other
onChangeText={onChangeText}
placeholder={placeholder}
placeholderTextColor='#C7C7CD'
style={inputStyle}
value={value}
/>
If you are using only react-native components your option is TextInput
As "funkysoul" explained:
Just assign following properties to your TextInput Component
multiline = {true}
numberOfLines = {4}
If you want to see this component as the classic textarea (bigger than an inline text-input), you usually will need to add the height style-property. See the following example:
<TextInput
multiline={true}
numberOfLines={10}
style={{ height:200, backgroundColor:'red'}}
/>
I added the backgroundColor for a better understanding of the height role. Please don't use it on your project ;)

Is there a way to do letterSpacing for TextInput in React Native?

I've been trying to give <TextInput> a letterSpacing style but it seems it only works for <Text>. Is there a way in React Native to increase the space between characters in TextInput?
This increases the space between characters
<Text style={{'letterSpacing': 5}}>Some Text</Text>
This won't work
<TextInput style={{'letterSpacing': 5}} />
I think this is a hack - nevertheless, it works:
<TextInput letterSpacing={5} ... />
I have asked here on SO why style keys also work as props on components, still no answer.
Do not consider this solution permanent, this is obviously not the intended way to style components in RN.
This is a possible solution, maybe not the better.
Jsfiddle
class Form extends React.Component {
constructor() {
super();
this.state = {
value: '',
};
this.onChangeText = this.onChangeText.bind(this);
}
onChangeText(e) {
const val = e.target.value.replace(/ /g, '').split('');
const spaced = val.join(' ');
this.setState({
value: spaced,
});
}
render() {
return(
<div style={{flexDirection: 'column'}}>
<div>Type Text</div>
<input
type='text'
onChange={this.onChangeText}
value={this.state.value}
/>
</div>
);
}
}
You should give letterSpacing inside inputStyle prop.
Example:
<TextInput inputStyle={{ letterSpacing: 20 }}/>
Check out this component
https://github.com/wix/react-native-ui-lib#masked-input
it allows you to render custom masked input in any way you want it, without affecting the actual value of the input.
just put text inside textInput and style it like below
<TextInput
placeholder={'1 2 3 4 5 6'}
style={textInputViewStyle}
onChangeText={setCode}
maxLength={6}
>
<Text style={{ letterSpacing: 19 }}>{code}</Text>
</TextInput>

React Native - Default style for elements

Is there a way in React Native to set the style for standard elements without adding a style tag to each and every one? Like for example I want to alter the style for these:
<Text>This is test</Text>
<Text>This is also text</Text>
<Text>And so is this</Text>
As I understand it the only way to say a margin indent is to do this:
<Text style={styles.indentText}>This is test</Text>
<Text style={styles.indentText}>This is also text</Text>
<Text style={styles.indentText}>And so is this</Text>
In ordinary website CSS you can obviously just set some styles for all HTML elements without needing to add a class or ID to them. How is it done in React Native?
You can set an abstraction layer just for it:
IndentedText = React.createClass({
render: () {
<Text style={styles.indentText}>{this.props.text}</Text>
}
})
And then in your other components:
<IndentedText text={"This is a text"} />
<IndentedText text={"This is also a text"} />
<IndentedText text={"And so is this"} />

ReactNative TextInput placeholderTextColor doesn't seem to be working

It seems like such a simple thing, I don't see how I'm not getting this right, but placeholderTextColor on a ReactNative TextInput isn't doing anything for me.
http://facebook.github.io/react-native/docs/textinput.html#placeholdertextcolor
<TextInput
style={styles.input}
placeholder="Foobar"
placeholderTextColor="#FFFFFF"/>
does nothing....
This works -
<TextInput
placeholder="Enter password"
placeholderTextColor="white"
/>
Hope it helps! Cheers!
<TextInput
value={this.state.environment}
onChangeText={(environment) => this.setState({ environment })}
placeholder={'Environment'}
placeholderTextColor="#202020"
secureTextEntry={true}
style={styles.input}
underlineColorAndroid='rgba(0,0,0,0)'
/>
I did this and it works quite well:
// use standard input
import { TextInput } from 'react-native';
<TextInput
style={[styles.searchInput, { opacity: this.state.location.length ? 1 : 0.6 }]}
placeholder="Location"
placeholderTextColor={colors.lighterGrey}
onChangeText={location => this.setState({ location })}
value={this.state.location}
/>
const styles = StyleSheet.create({
searchInput: {
flex: 1,
lineHeight: 22,
fontSize: 17,
fontFamily: fonts.secondary.regular,
color: colors.white,
padding: 5,
},
});
I was having issues getting the opacity to work, so I found the above solution worked well as a minimal markup solution:
style={[styles.searchInput, { opacity: this.state.location.length ? 1 : 0.6 }]}
The style prop can accept an Array of style Objects which has right to left precedence, so you can override default styles with state-based addons. I might also say it is related to CSS specificity.
In my case, I was having trouble modulating the text colours between the placeholder text and 'filled-in text. The opacity of styles.searchInput was affecting the <TextInput placeholderTextColor=""> prop.
My solution here handles the opacity concern on both iOS and Android and demonstrates a pretty normal <TextInput> setup.
In the context of my example code above, a person can always examine this.state.location.length to see if the field is empty or not.
If so, use TextInput's style prop with computed props (same as in Vue.js). You could drop a function in there, like:
style={[styles.textInput, calculatedStyles()]}
Don't forget you can spread in Objects also:
style={[...inputStyles, ...errorStyles]}
As Asanka Sampath shows in another answer, depending on your design, underlineColorAndroid can be a very useful TextInput prop.
placeholder: "Enter password",
placeholderTextColor: "white"
try this in Latest Version in React Native
Simple and easy solution
<TextInput
style={styles.textInputStyle} //if you want give style to the TextInput
placeholder="Email"
placeholderTextColor="steelblue"
/>