React Native: pass different styles in a map - javascript

I want to have 4 boxes, each box with a different color, and I want to do that loading each style from map(). The below code doesn't compile, I wrote it so you understand what I'm trying to do. The error derives from inside the View at styles.{box.name}, I want instead of {box.name} to put array's elements so the function can take Stylesheet's props.
export default function Imagesfun() {
const array = [{
name: "box1",
},
{
name: "box2",
},
{
name: "box3",
},
{
name: "box4",
},
{
name: "box5",
}]
return (
<View style={styles.container}>
{array.map(box => <Text style={styles.{box.name}} key={box.name}>{box.name}</Text>)}
</View >
)
}
const styles = StyleSheet.create({
container: {
justifyContent: "space-around",
alignContent: "center",
backgroundColor: 'black',
},
box1: {
backgroundColor: 'lightblue',
},
box2: {
backgroundColor: 'lightred',
},
box3: {
backgroundColor: 'lightyellow',
},
box4: {
backgroundColor: 'lightpurple',
},
box5: {
backgroundColor: 'lightgreen',
},
});

Change {styles.{box.name}} to {styles[box.name]}. Check this Q & A for more details.

Try as following:
<View style={styles.container}>
{array.map(box => <Text style={styles.[box.name]} key={box.name}>{box.name}</Text>)}
</View >

Related

How to set Switch component separately for each item that comes From API in React native

I have an API and I need to set the switch button separately for each
item. I read different answers but didn't solve my problem as I tried
all of the answers.
const results = [
{
Id: "IySO9wUrt8",
Name: "Los Stand",
Category: "Mexican",
Status: true,
},
{
Id: "IySO9wUrt8",
Name: "Los Stand 2",
Category: "Burger",
Status: true,
},
{
Id: "IySO9wUrt8",
Name: "Los Stand 3",
Category: "BBq",
Status: true,
},
];
in the above code I need to set the Status in switch . If status is
true then the switch will be ON
for all the code I share the link of expo for live editing
Expo Link for Editing
You need to create a component that receives the item information, and inside the component update the state individually for each switch, otherwise the state is shared among the number of items you have.
The link for Expo is here
If you turn your results into a state you can do it link:
import React, { useEffect, useState } from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Image,
ScrollView,
FlatList,
SafeAreaView,
Switch,
RefreshControl,
Vibration,
ActivityIndicator,
} from 'react-native';
import { Card, TextInput, RadioButton } from 'react-native-paper';
const results = [
{
Id: 'IySO9wUrt8',
Name: 'Los Stand',
Category: 'Mexican',
Status: true,
},
{
Id: 'IySO9wUrt8',
Name: 'Los Stand 2',
Category: 'Burger',
Status: true,
},
{
Id: 'IySO9wUrt8',
Name: 'Los Stand 3',
Category: 'BBq',
Status: true,
},
];
export default function App() {
const [data, setData] = useState(results);
const updateItem = (newItem, index) => {
// when an array is used with useState it should be treated immutable
// if the array have nested objects/arrays then you will need
// a different cloning technique
const dataClone = [...data];
const currentItem = dataClone[index];
dataClone[index] = { ...currentItem, ...newItem };
setData(dataClone);
};
const renderItem = ({ item, index }) => {
let items = [];
return (
<>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: 280,
}}>
<Text>{item.Name}</Text>
<Switch
key={item.Id}
style={{ alignSelf: 'center' }}
trackColor={{ false: '#767577', true: '#81b0ff' }}
thumbColor={item.Status ? '#f5dd4b' : '#f4f3f4'}
ios_backgroundColor="#3e3e3e"
onValueChange={(val) => updateItem({Status: val }, index)}
value={item.Status}
/>
</View>
</>
);
};
return (
<SafeAreaView style={styles.container}>
<FlatList
style={styles.container}
data={data}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 2,
backgroundColor: 'white',
},
textStyle: {
marginHorizontal: 20,
marginTop: 10,
color: 'black',
fontWeight: '600',
},
singleRadioButtonContainer: {
flexDirection: 'row',
alignItems: 'center',
marginRight: 10,
},
});
If converting result into state is not desireable then you can move renderItem into its own file so that it can have state of its own link:
import React, { useState } from 'react';
import { View, Switch, Text } from 'react-native';
export default function Item({ item, index }) {
const [enabled, setEnabled] = useState(item.Status)
return (
<>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: 280,
}}>
<Text>{item.Name}</Text>
<Switch
key={item.Id}
style={{ alignSelf: 'center' }}
trackColor={{ false: '#767577', true: '#81b0ff' }}
thumbColor={enabled ? '#f5dd4b' : '#f4f3f4'}
ios_backgroundColor="#3e3e3e"
onValueChange={setEnabled}
value={enabled}
/>
</View>
</>
);
}

How to create text border radius without wrap view in React Native?

In React-Native, how do I set borderRadius to Text-components?
I've tried using borderRadius in text stylesheet but it not work:
import { formatPhone, mapNameWithLocalContact } from '#chat/common/Utils/ChatUtils';
import ChatFunctions from '#chat/service/ChatFunctions';
import { Colors, Text } from '#momo-platform/component-kits';
import React from 'react';
import { StyleSheet, View, TextStyle } from 'react-native';
import { parseValue } from 'react-native-controlled-mentions';
import { MessageText } from 'react-native-gifted-chat';
// #ts-ignore
import ParsedText from 'react-native-parsed-text';
import { partTypes } from '../menstions';
const textStyle = {
fontSize: 16,
lineHeight: 20,
marginTop: 5,
marginBottom: 5,
marginLeft: 10,
marginRight: 10,
};
const styles = {
left: StyleSheet.create({
container: {},
text: {
color: 'black',
...textStyle,
},
link: {
color: 'black',
textDecorationLine: 'underline',
},
textMention: {
color: Colors.pink_05_b,
fontWeight: 'bold',
},
mentionMe: isMe =>
isMe
? {
color: Colors.white,
backgroundColor: Colors.pink_05_b,
}
: {},
}),
right: StyleSheet.create({
container: {},
text: {
color: 'white',
...textStyle,
},
link: {
color: 'white',
textDecorationLine: 'underline',
},
textMention: {
color: 'white',
fontWeight: 'bold',
},
mentionMe: () => ({}),
}),
};
export default class MessageTextCustom extends MessageText {
constructor() {
super(...arguments);
}
render() {
const linkStyle = [
styles[this.props.position].link,
this.props.linkStyle && this.props.linkStyle[this.props.position],
];
const { parts } = parseValue(this.props.currentMessage.text, partTypes);
return (
<View
style={[
styles[this.props.position].container,
this.props.containerStyle && this.props.containerStyle[this.props.position],
]}
>
<ParsedText
style={[
styles[this.props.position].text,
this.props.textStyle && this.props.textStyle[this.props.position],
this.props.customTextStyle,
]}
parse={[
...this.props.parsePatterns(linkStyle),
{ type: 'url', style: linkStyle, onPress: this.onUrlPress },
{ type: 'phone', style: linkStyle, onPress: this.onPhonePress },
{ type: 'email', style: linkStyle, onPress: this.onEmailPress },
]}
childrenProps={{ ...this.props.textProps }}
>
{this.props.isGroup ? (
<Text>
{parts.map(({ text, partType, data }, index) =>
partType ? (
<Text
key={`${index}-${data?.trigger ?? 'pattern'}`}
style={[
styles[this.props.position].textMention,
styles[this.props.position].mentionMe(
formatPhone(data.id) === ChatFunctions.phoneNumber
),
]}
onPress={() =>
this.props.onPressMenstion &&
this.props.onPressMenstion(data.id)
}
>
{`${data?.trigger}${mapNameWithLocalContact({
phone: data?.id,
name: data?.name,
})}`}
</Text>
) : (
<Text
key={index}
style={[
styles[this.props.position].text,
this.props.textStyle &&
this.props.textStyle[this.props.position],
this.props.customTextStyle,
]}
>
{text}
</Text>
)
)}
</Text>
) : (
this.props.currentMessage.text
)}
</ParsedText>
</View>
);
}
}
My expected style
I cannot use view to wrap this text because my text component is wrap by other text component
I've worked on it on snack you can check out this link and make sure you wrap those text with a View and use
flexDirection: 'row';
alignItems: 'center';
So to stop the View from filling the screen 100% add
alignSelf: 'start';
Checkout this link to see the code I've written for this
https://snack.expo.dev/#rajibola/spontaneous-beef-jerky
For TextStyle, borderTopRightRadius, borderTopLeftRadius, borderBottomRightRadius, borderBottomLeftRadius don't work. Only borderRadius works.
Maybe it's a bug!

React native flatlist image list

I'm looking for someone that could help me just images in a flatlist grid.
I was able to get it working with text but not images in the assets folder.
I want to have separate images that will be stored in the assets folder to be in the boxes of the flatlist grid.
Please let me know if you need more information!
Here is the code:
import React from 'react';
import { View, Image, Text, StyleSheet, TouchableOpacity, FlatList, Dimensions } from 'react-native';
import { drawer } from '../navigation/AppNavigation';
import { hp, wp } from '../utils/responsiveScreen';
const dataList = [{ key: '1' }, { key: '2' }, { key: '3' }, { key: '4' }, { key: '5' },{ key: '6' },{ key: '6' },{ key: '6' }]
const numColums = 2
const WIDTH = Dimensions.get('window').width
const Main = () => {
formatData = (data, numColums) =>{
const totalRows = Math.floor(data.length / numColums)
let totalLastRow = dataList.length - (totalRows * numColums)
while(totalLastRow !== 0 && totalLastRow !== numColums){
dataList.push({'key': 'blank', empty: true})
totalLastRow++
}
return dataList
}
_renderItem = ({ item, index }) => {
let {itemStyle, itemText} = styles
if(item.empty){
return <View style={[itemStyle]}/>
}
return (
<View style={itemStyle}>
<Text style={styles.itemText}>{item.key}</Text>
</View>
)
}
return (
<View style={styles.container}>
<TouchableOpacity
style={{ height: 50 }}
onPress={() => drawer.current.open()}>
<Image source={require('../assets/menu.png')} />
</TouchableOpacity>
<Text style={styles.textStyle}>Stars</Text>
<FlatList
data={this.formatData(dataList, numColums)}
renderItem={this._renderItem}
keyExtractor={(item, index) => index.toString()}
numColumns = {numColums}
/>
</View>
);
};
And here is the Style sheet:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
paddingTop: hp(7),
paddingHorizontal: wp(6),
},
textStyle: {
marginBottom: 20,
fontWeight: 'bold',
fontSize: 24,
color: 'black',
},
image: {
alignSelf: 'center',
height: hp(40),
width: hp(40),
marginTop: hp(3),
},
itemStyle: {
backgroundColor: 'pink',
alignItems: 'center',
justifyContent: 'center',
height: 150,
flex: 1,
margin:1,
width: WIDTH / numColums
},
itemText: {
fontSize: 50
}
});
I have attached an image of what it looks like now:
Here
UPDATE
I have updated the datalist to this:
const dataList = [{ key: '1',image: required('../assets/backGround.png')}, { key: '2',image: required('../assets/backGround.png') }, { key: '3' ,image: required('../assets/backGround.png')}]
And the view to this:
<View style={itemStyle}>
{/* <Text style={styles.itemText}>{item.key}</Text> */}
<Image
style={styles.image}
source={item.image}
/>
</View>
and I now get the error:
TypeError: (0, _reactNative.required) is not a function. (In '(0, _reactNative.required)('../assets/backGround.png')', '(0, _reactNative.required)' is undefined)
const dataList = [{ key: '1',image: required('../assets/backGround.png')}, { key: '2',image: required('../assets/backGround.png') }, { key: '3' ,image: required('../assets/backGround.png')}]
needs to be
const dataList = [{ key: '1',image: require('../assets/backGround.png')}, { key: '2',image: require('../assets/backGround.png') }, { key: '3' ,image: require('../assets/backGround.png')}]
you need to add require() to the source in the image tag

Declaring array for use in React Native AutoComplete search engine

Not sure where I go about declaring the array with which I want to search from, any assistance would be appreciated. I believe my issue is that I am declaring the "services' array in the incorrect area but I am not sure where else to put it! Or if the commas are the right character to be using in between strings/services
import React, { useState, Component } from 'react';
import { StyleSheet, StatusBar, View, Text, Button, TouchableOpacity } from 'react-native';
import AutoComplete from 'react-native-autocomplete-input';
class CareProviderSequenceScreen extends Component {
constructor (props) {
super (props);
this.state = {
services: [],
query: '',
}
}
render() {
const query = this.state;
const services = {
"Pick up my Prescription",
'Pick up groceries',
'Pick up dry cleaning',
'Pick up my pet',
}
return (
<View style={styles.container}>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
containerStyle={styles.autocompleteContainer}
//data to show in suggestion
data={services.length === 1 && comp(query, services[0].title) ? [] : services}
//default value if you want to set something in input
defaultValue={query}
/*onchange of the text changing the state of the query which will trigger
the findFilm method to show the suggestions*/
onChangeText={text => this.setState({ query: text })}
placeholder="Enter your need"
renderItem={({ item }) => (
//you can change the view you want to show in suggestion from here
<TouchableOpacity onPress={() => this.setState({ query: item.title })}>
<Text style={styles.itemText}>
{item.title} ({item.release_date})
</Text>
</TouchableOpacity>
)}
/>
<View style={styles.descriptionContainer}>
{services.length > 0 ? (
<Text style={styles.infoText}>{this.state.query}</Text>
) : (
<Text style={styles.infoText}>Enter The Film Title</Text>
)}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
flex: 1,
padding: 16,
marginTop: 40,
},
autocompleteContainer: {
backgroundColor: '#ffffff',
borderWidth: 0,
},
descriptionContainer: {
flex: 1,
justifyContent: 'center',
},
itemText: {
fontSize: 15,
paddingTop: 5,
paddingBottom: 5,
margin: 2,
},
infoText: {
textAlign: 'center',
fontSize: 16,
},
});
export default CareProviderSequenceScreen ;
CareProviderSequenceScreen .navigationOptions = () => ({
title: "Home & Personal Care",
headerTintColor: '#9EBBD7',
headerStyle: {
height: 65,
backgroundColor: '#1E5797',
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.20,
shadowRadius: 1.41,
elevation: 2,}
});
First, you are assigning an object to services array.
Second, you are not accessing the query state properly. It should be
const { query } = this.state

How to render actions in ToolbarAndroid for React Native

I am using the "react-native-scrollable-tab-view" which is a great Android & iOS Tab Navigation. On top of the tabs i want to render the ToolbarAndroid actions which has it´s own options on each tab. For e.g. tab one has a toolbar with different action icons as tab two has.
How could i solve this?
This is my ScrollableView:
<ScrollableTabView
renderTabBar={() => <CustomTabBar someProp={'here'} />}>
<View style={styles.tabView} tabLabel="Page1">
<Page1View/>
</View>
<View style={styles.tabView} tabLabel="Page2">
<Page2View/>
</View>
</ScrollableTabView>
And here is my CustomTabBar:
var CustomTabBar = React.createClass({
selectedTabIcons: [],
unselectedTabIcons: [],
propTypes: {
goToPage: React.PropTypes.func,
activeTab: React.PropTypes.number,
tabs: React.PropTypes.array
},
renderTabOption( name, page ) {
var isTabActive = this.props.activeTab === page;
return (
<View style={[styles.tab]}>
<Button key={name} onPress={() => this.props.goToPage(page)}>
<Text
style={{color: !isTabActive ? '#6393B8' : 'white', fontWeight: isTabActive ? 'bold' : 'normal', justifyContent: 'center', alignItems: 'center', fontFamily: VALUES.FONTS.FONT_REGULAR}}>
{name}
</Text>
</Button>
</View>
);
},
render() {
var numberOfTabs = this.props.tabs.length;
var tabUnderlineStyle = {
position: 'absolute',
width: deviceWidth / numberOfTabs,
height: 4,
backgroundColor: 'white',
bottom: 0,
};
var left = this.props.scrollValue.interpolate({
inputRange: [ 0, 1 ], outputRange: [ 0, deviceWidth / numberOfTabs ]
});
return (
<View>
<ToolbarAndroid
title="TITLE"
titleColor='white'
style={styles.toolbar}
actions={toolbarActions} ==> render this to be updated to actual tab with different Tab actions
/>
<View style={styles.tabs}>
{this.props.tabs.map(( tab, i ) => this.renderTabOption(tab, i))}
<Animated.View style={[tabUnderlineStyle, {left}]}/>
</View>
</View>
);
},
});
Here is how my current toolbarActions are defined right now:
var toolbarActions = [
{ title: 'Create', icon: require ('image!ic_create_black_48dp'), show: 'always' },
{ title: 'Filter' },
{ title: 'Settings', icon: require ('image!ic_settings_black_48dp'), show: 'always' }
];
This worked for me:
var toolbarActionsForPageOne = [
{ title: 'Option1' },
{ title: 'Option2' },
];
var toolbarActionsForPageTwo = [
{ title: 'Something1', },
{ title: 'Something2', },
];
Then use the activeTab property to identify current tab, and write a function which takes this as parameter to return the needed options:
function toolbarActions ( currentTab ) {
switch (currentTab) {
case 0:
return toolbarActionsPageOne
case 1:
return toolbarActionsPageTwo
}
}
In your ToolbarAndroid View assign it to actions:
actions={toolbarActions(this.props.activeTab)}

Categories

Resources