I want to customize this context menu rather than displaying default actions like copy, select all etc.
Here is my code snippet:
<TextInput
showSoftInputOnFocus={false}
multiline
value={text}
editable={false}
style={{
color: '#000',
maxWidth: Dimensions.get('screen').width / 1.25,
textAlign: 'center',
}}
onSelectionChange={(e) => {
let start = e.nativeEvent.selection.start;
let end = e.nativeEvent.selection.end;
setSelectedText(text.substring(start, end));
}}
/>
Unable to see the list items in the result list. Spent a full day figuring out what it might be, still unable to resolve it.
When search results appear, I cannot see the text. listview style doesn't color the text.
<GooglePlacesAutocomplete
returnKeyType={'default'}
fetchDetails={true}
minLength={2}
placeholder="Search"
textInputProps={{
placeholderTextColor: '#32a852',
returnKeyType: 'search',
}}
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
console.log(data, details);
}}
query={{
key: GOOGLE_API_KEY,
language: 'en',
}}
styles={{
textInput: {
height: 38,
color: '#5d5d5d',
fontSize: 16,
},
predefinedPlacesDescription: {
color: '#1faadb',
},
listView: {color: 'black', zIndex: 100000}, // doesnt work, text is still white?
}}
/>
</View>
In styles, add description for changing the color or any other style attribute.
styles = {{
...
description : {color : 'black'}
}}
I have seen a few posts explaining how to set multiple countries for google places autocomplete in javascript/react as so:
componentRestrictions: {country: ["gb", "fr"]}
but for react-native GooglePlacesAutocomplete, the advice is to put a components option within query. Unsure if here we can pass multiple countries... have tried and failed to pass an array here as looks like it needs to just be a string containing one country code. Would appreciate any help...
<GooglePlacesAutocomplete
placeholder={placeholder}
listViewDisplayed={true}
fetchDetails={true}
textInputProps={{
borderColor: color,
fontSize: 18,
borderWidth: 1,
borderRadius: 4,
flex: 1,
padding: 7
}}
onPress={(data, details = null) => {
console.log(data, details)
}}
query={{
key: googleApiKey,
language: "en",
components: "country:gb",
types: types ? types : null
}}
/>
You can use the component restrictions like so components: "country:gb|country:us"
See full code example below
<GooglePlacesAutocomplete
placeholder={placeholder}
listViewDisplayed={true}
fetchDetails={true}
textInputProps={{
borderColor: color,
fontSize: 18,
borderWidth: 1,
borderRadius: 4,
flex: 1,
padding: 7
}}
onPress={(data, details = null) => {
console.log(data, details)
}}
query={{
key: googleApiKey,
language: "en",
components: "country:gb|country:us",
types: types ? types : null
}}
/>
I'am using react-native-element to create a button group, that embedded an Icon from react-native-vector-icons .
the problem is that when the icon is touched, onPress does not get triggered
constructor(props) {
super(props);
this.state = { selectedIndex: 0 };
this.SetSelected = this.SetSelected.bind(this);
}
SetSelected(index) {
this.setState({ selectedIndex: index });
}
return(
<ButtonGroup
selectedIndex={this.state.selectedIndex}
onPress={this.SetSelected}
selectedButtonStyle={{ backgroundColor: 'blue' }}
buttons={[
{
element: () => (
<Icon.Button
name="slack"
style={{ backgroundColor: 'white' }}
color={'black'}
size={30}
title="Inbox"
>
<Text style={{ color: 'black', fontSize: 15, textAlignVertical: 'center', textAlign: 'center' }}
>
All
</Text>
</Icon.Button>
),
})
Thanks to Kyle Roach,
the reason is
because I am using an Icon.Button which is touchable. So when I try to tap to change the ButtonGroup, the touch event will be caught by Icon.Button instead of the button for the buttonGroup.
I should use Icon instead of Icon.Button.
Try making it a function.
onPress={() => {this.SetSelected()}}
If it doesn't work please provide the this.SetSelected function.
How do I make a single word in a Text field bold or italics? Kind of like this:
<Text>This is a sentence <b>with</b> one word in bold</Text>
If I create a new text field for the bold character it will separate it onto another line so that's surely not the way to do it. It would be like creating a < p > tag within a < p > tag just to make one word bold.
You can use <Text> like a container for your other text components.
This is example:
...
<Text>
<Text>This is a sentence</Text>
<Text style={{fontWeight: "bold"}}> with</Text>
<Text> one word in bold</Text>
</Text>
...
Here is an example.
For a more web-like feel:
const B = (props) => <Text style={{fontWeight: 'bold'}}>{props.children}</Text>
<Text>I am in <B>bold</B> yo.</Text>
you can use https://www.npmjs.com/package/react-native-parsed-text
import ParsedText from 'react-native-parsed-text';
class Example extends React.Component {
static displayName = 'Example';
handleUrlPress(url) {
LinkingIOS.openURL(url);
}
handlePhonePress(phone) {
AlertIOS.alert(`${phone} has been pressed!`);
}
handleNamePress(name) {
AlertIOS.alert(`Hello ${name}`);
}
handleEmailPress(email) {
AlertIOS.alert(`send email to ${email}`);
}
renderText(matchingString, matches) {
// matches => ["[#michel:5455345]", "#michel", "5455345"]
let pattern = /\[(#[^:]+):([^\]]+)\]/i;
let match = matchingString.match(pattern);
return `^^${match[1]}^^`;
}
render() {
return (
<View style={styles.container}>
<ParsedText
style={styles.text}
parse={
[
{type: 'url', style: styles.url, onPress: this.handleUrlPress},
{type: 'phone', style: styles.phone, onPress: this.handlePhonePress},
{type: 'email', style: styles.email, onPress: this.handleEmailPress},
{pattern: /Bob|David/, style: styles.name, onPress: this.handleNamePress},
{pattern: /\[(#[^:]+):([^\]]+)\]/i, style: styles.username, onPress: this.handleNamePress, renderText: this.renderText},
{pattern: /42/, style: styles.magicNumber},
{pattern: /#(\w+)/, style: styles.hashTag},
]
}
childrenProps={{allowFontScaling: false}}
>
Hello this is an example of the ParsedText, links like http://www.google.com or http://www.facebook.com are clickable and phone number 444-555-6666 can call too.
But you can also do more with this package, for example Bob will change style and David too. foo#gmail.com
And the magic number is 42!
#react #react-native
</ParsedText>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
url: {
color: 'red',
textDecorationLine: 'underline',
},
email: {
textDecorationLine: 'underline',
},
text: {
color: 'black',
fontSize: 15,
},
phone: {
color: 'blue',
textDecorationLine: 'underline',
},
name: {
color: 'red',
},
username: {
color: 'green',
fontWeight: 'bold'
},
magicNumber: {
fontSize: 42,
color: 'pink',
},
hashTag: {
fontStyle: 'italic',
},
});
It is not in a text field as asked but wrapping separate text elements into a view would give the desired output. This can be used if you don't want to add another library into your project just for styling a few texts.
<View style={{flexDirection: 'row'}}>
<Text style={{fontWeight: '700', marginRight: 5}}>Contact Type:</Text>
<Text>{data.type}</Text>
</View>
Would result as follows
You can also put a Text tag inside of another Text tag. The second text tag will inherit the styling of the first, but you maintain the ability to style it independently from its parent.
<Text style={styles.bold}>Level:
<Text style={styles.normal}>Easy</Text>
</Text>
//in your stylesheet...
bold: {
fontSize: 25,
fontWeight: "bold",
color: "blue",
},
normal: {
// will inherit size and color attributes
fontWeight: "normal",
}
Use this react native library
To install
npm install react-native-htmlview --save
Basic Usage
import React from 'react';
import HTMLView from 'react-native-htmlview';
class App extends React.Component {
render() {
const htmlContent = 'This is a sentence <b>with</b> one word in bold';
return (
<HTMLView
value={htmlContent}
/> );
}
}
Supports almost all html tags.
For more advanced usage like
Link handling
Custom Element Rendering
View this ReadMe
You could just nest the Text components with the required style. The style will be applied along with already defined style in the first Text component.
Example:
<Text style={styles.paragraph}>
Trouble singing in. <Text style={{fontWeight: "bold"}}> Resolve</Text>
</Text>
Bold text:
<Text>
<Text>This is a sentence</Text>
<Text style={{fontWeight: "bold"}}> with</Text>
<Text> one word in bold</Text>
</Text>
Italic text:
<Text>
<Text>This is a sentence</Text>
<Text style={{fontStyle: "italic"}}> with</Text>
<Text> one word in italic</Text>
</Text>
I am a maintainer of react-native-spannable-string
Nested <Text/> component with custom style works well but maintainability is low.
I suggest you build spannable string like this with this library.
SpannableBuilder.getInstance({ fontSize: 24 })
.append('Using ')
.appendItalic('Italic')
.append(' in Text')
.build()
for example!
const TextBold = (props) => <Text style={{fontWeight: 'bold'}}>Text bold</Text>
<Text>
123<TextBold/>
</Text>
<Text>
<Text style={{fontWeight: "bold"}}>bold</Text>
normal text
<Text style={{fontStyle: "italic"}}> italic</Text>
</Text>
There seems to be one or two components out there like react-native-markup-text, but if you don't mind using regular expressions to parse small markup.
Snack Demo
import * as React from 'react';
import { Text, View, StyleSheet, Image } from 'react-native';
/**
* #typedef MiniMarkupTextProps
* #type {object}
* #property {string|null|undefined} text - a piece of mini markup text.
* #property {object|null|undefined} itemStyle - itemStyle;
*/
export default React.memo((/** #type {MiniMarkupTextProps} */ props) => {
const markup = props.text;
const mappings = new Map([
[
'p',
(text, index) => {
return (
<Text key={index} style={props.itemStyle}>
{text}
</Text>
);
},
],
[
'b',
(text, index) => {
return (
<Text key={index} style={[{ fontWeight: 'bold' }, props.itemStyle]}>
{text}
</Text>
);
},
],
]);
const keys = Array.from(mappings.keys());
const regExp = new RegExp(
`(${keys.map((e) => `<${e}>`).join('|')})(.*?)(${keys
.map((e) => `<\\/${e}>`)
.join('|')})|(\\s*)`,
'g'
);
return (
<Text>
{markup?.match(regExp)?.map(function (tag) {
const isEmpty = tag.trim().length === 0;
return isEmpty ? (
<Text> </Text>
) : (
tag?.match(/<[a-z]>/g)?.map(function (t, index) {
const text = tag.replace(/<[^>]+>/g, '');
return (
mappings.get?.(t.replace(/<|>/g, ''))?.(text, index) ?? null
);
})
);
})}
</Text>
);
});
Usage
<MiniMarkupText
text="<p>This is a simple</p> <b>test</b> <p>and it could be useful</p> <b>. Then again it all depends...</b>"
itemStyle={{ color: 'red', textAlign: 'center'}}
/>
Nesting Text components is not possible now, but you can wrap your text in a View like this:
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<Text>
{'Hello '}
</Text>
<Text style={{fontWeight: 'bold'}}>
{'this is a bold text '}
</Text>
<Text>
and this is not
</Text>
</View>
I used the strings inside the brackets to force the space between words, but you can also achieve it with marginRight or marginLeft. Hope it helps.
This worked for me
<h2>
{`Step ${activeStep+1}/3 - `} <strong>{stepName}</strong>
</h2>
//output Step 1/3 - Information