underline the clicked text element - javascript

I have a list of text elements that I want to underline when clicked. If I add the text decoration to the tabText then obviously it is applied to all items. How can I make sure that the when I click on another tab, the underline from the previous tab gets removed?
Is there any way I can add or remove items from the style element upon clicking on an item?
//onPress={() => {}}>
const tabs = [
{
id: 1,
text: 'Alle List',
},
{
id: 2,
text: 'Second',
},
];
export const Tab: React.FunctionComponent = () => {
return (
<View style={styles.tabView}>
{tabs.map((item: any) => (
<View>
<Text style={styles.tabText}>{item.text}</Text>
</View>
))}
</View>
);
};
const styles = StyleSheet.create({
tabView: {
paddingTop: moderateScale(15),
paddingLeft: moderateScale(20),
paddingRight: moderateScale(20),
flexDirection: 'row',
justifyContent: 'space-between',
},
tabText: {
color: 'white',
paddingBottom: moderateScale(10),
//textDecorationLine: 'underline'
},
});
Codesandbox (with tabText items as an array too):
https://snack.expo.io/#nhammad/shallow-watermelon

You can use useState to save the selected index and then apply another style based on the selected index. Here is a quick modification to your script and the snack link is at the end.
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
const tabs = [
{
id: 1,
text: 'All Friends',
},
{
id: 2,
text: 'Second',
},
{
id: 3,
text: 'Third',
},
];
export default function App() {
const [selected, setSelected] = React.useState(null)
return (
<View style={styles.container}>
<View style={styles.tabView}>
{tabs.map((item: any, index) => (
<TouchableOpacity onPress={()=>setSelected(index)}>
<View>
<Text style={[styles.tabText,selected===index?styles.selected:null]}>{item.text}</Text>
</View>
</TouchableOpacity>
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
tabView: {
paddingTop: 15,
paddingLeft: 20,
paddingRight: 20,
flexDirection: 'row',
justifyContent: 'space-between',
},
tabText: {
color: 'black',
paddingBottom: 10,
},
selected: {
textDecorationLine: 'underline'
},
});
https://snack.expo.io/#saachitech/da6280

You can add different styles for your tab depending on active route
<Text style={[(this.props.activeRouteName == route.routeName) ? styles.tabActiveText: styles.tabText]}>{item.text}</Text>
And then in the styles
tabActiveText: {
color: 'white',
paddingBottom: moderateScale(10),
textDecorationLine: 'underline'
}

Related

FlatList Horizontal Scrolling

I'm creating onBoarding screens and I have created each of the screen item as a component and trying to render them with Flatlist so far everything is working smoothly but when I swipe the flatlist to see the other screens it's not working it swipes 40% and and forcefully shows the current screen it seems like there is some flex styling issues and I could able to figure it out please suggest.
Here is the video for explaination: https://youtube.com/shorts/pHbTs7ifMww
OnBoardingScreen.js
import React, { useState } from 'react';
import { Dimensions, FlatList, SafeAreaView, View, StyleSheet, Text, Image } from 'react-native';
const { width, height } = Dimensions.get('window');
const COLORS = {primary : '#ff006c', white: '#ffffff', black: '#000000'};
const slides = [
{
id: '1',
image: require('../../images/OnBoardingImages/1.png'),
title: 'You can mark time',
description: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual',
},
{
id: '2',
image: require('../../images/OnBoardingImages/2.png'),
title: 'You can mark time',
description: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual',
},
{
id: '3',
image: require('../../images/OnBoardingImages/3.png'),
title: 'You can mark time',
description: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual',
},
]
const Slide = ({item}) => {
return (
<View style={styles.slideView}>
<Image source={item.image} style={styles.slideImage} />
<Text style={styles.slideTitle}>{item.title}</Text>
<Text style={styles.slideDescription}>{item.description}</Text>
</View>
);
}
const OnBoardingScreen = ({ navigation }) => {
const [currentSlideIndex, setCurrentSlideIndex] = useState(0);
const Footer = () => {
return (
<View style={styles.footer}>
<View style={styles.pagination}>
{slides.map((_, index) => (<View key={index} style={[styles.paginationItem, currentSlideIndex == index && {backgroundColor: 'grey'} ]} /> ))}
</View>
</View>
);
};
return (
<SafeAreaView style={styles.root}>
<FlatList
data={slides}
contentContainerStyle={{flex: 1}}
showsHorizontalScrollIndicator={false}
horizontal
pagingEnabled
renderItem={({item}) => <Slide item={item} />} />
<Footer />
</SafeAreaView>
);
};
export default OnBoardingScreen;
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: COLORS.white,
},
slideView: {
alignItems: 'center',
},
slideImage: {
height: '75%',
width: width,
resizeMode: 'contain',
},
slideTitle: {
color: COLORS.primary,
fontSize: '22',
fontWeight: 'bold',
marginVertical: 10,
paddingHorizontal: 10,
textAlign: 'center',
},
slideDescription: {
fontSize: 18,
paddingHorizontal: 20,
color: 'grey',
textAlign: 'center',
},
footer: {
height: height * 0.25,
paddingHorizontal: 20,
justifyContent: 'space-between',
},
pagination: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 20,
},
paginationItem: {
height: 10,
width: 10,
backgroundColor: COLORS.primary,
marginHorizontal: 3,
borderRadius: 50,
},
});
App.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import Navigation from './src/navigation';
export default function App() {
return (
<View style={styles.container}>
<Navigation />
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
Update this style
slideView: {
alignItems: 'center',
width: width
},

Add and Remove items from state array with React Native Checkbox

I am trying to add and remove items from a state array using React Hooks and React Native Checkboxes. I am able to add the value of the checkbox to the array when checked, but I am unable to remove the value from the array at all, let alone when the checkbox is un checked. I have tried many different filter solutions, and do not want to use splice to avoid mutation. For now I am trying to use a separate button to delete the value from the array. Here is an expo snack https://snack.expo.dev/jN_QvE7pb
import React, {useState, useEffect, useRef} from 'react';
import {Text, View, StyleSheet, FlatList, Button, Modal, CheckBox} from 'react-native';
// import CheckBox from '#react-native-community/checkbox';
import {Card} from 'react-native-paper';
const data = [
{id: 1, txt: 'item1', isChecked: false},
{id: 2, txt: 'item2', isChecked: false},
{id: 3, txt: 'item3', isChecked: false},
{id: 4, txt: 'item4', isChecked: false},
];
const Example = () => {
const [products, setProducts] = useState(data);
const [arr, setArr] = useState([]);
useEffect(() => {
console.log(arr);
}, [arr]);
const addToArray = id => {
console.log(id);
products.map(product => {
if (id === product.id) {
setArr(prev => [...prev, product.id]);
}
});
};
const removeFromArray = id => {
setArr(arr.filter((e, i) => e.id !== id));
};
return (
<View style={styles.container}>
<FlatList
data={products}
renderItem={({item}) => (
<Card style={{margin: 5}}>
<View style={styles.card}>
<View
style={{
flexDirection: 'row',
flex: 1,
justifyContent: 'space-between',
}}>
<CheckBox
value={item.isChecked}
onChange={() => {
addToArray(item.id);
}}
/>
<Button
onPress={() => {
removeFromArray(item.id);
}}
title="Remove From Array"
/>
<Text>{item.txt}</Text>
</View>
</View>
</Card>
)}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
card: {
padding: 10,
margin: 5,
flexDirection: 'row',
justifyContent: 'space-between',
},
modalView: {
margin: 20,
backgroundColor: 'white',
borderRadius: 20,
padding: 5,
justifyContent: 'space-between',
alignItems: 'center',
elevation: 5,
},
text: {
textAlign: 'center',
fontWeight: 'bold',
},
});
export default Example;

Redirect link to new page with React Native

I'm learning React Native and need help from the React Native experts out there! Does anyone know how to redirect a link to new page(component).
I have a list of items (Purchases, Settings, Polices, Customer Support) that I want to redirect them to a new page when I click on it. Do I need to use the onPress event or is there another way?
import React, { component} from 'react';
import {Component} from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
import Login from './LogIn';
class Profile extends Component{
state = {
names: [
{
id: 0,
name: 'Purchases',
},
{
id: 1,
name: 'Settings',
},
{
id: 2,
name: 'Policies',
},
{
id: 3,
name: 'Feedback',
},
{
id: 3,
name: 'Customer support',
},
{
id: 3,
name: 'About the app',
}
]
}
render(){
return(
<View style={styles.container}>
<Text style={styles.header}>Welcome to GOLDENSHOE</Text>
<Text style={{fontSize: 16}}>Sign up or log in to access special discounts, your favorites and your account </Text>
<Login />
<View>
{
this.state.names.map((item, index) => (
<TouchableOpacity
key = {item.id}
style = {styles.listCont}
onPress = {() => console.log('hello')}>
<Text style = {styles.text}>
{item.name}
</Text>
</TouchableOpacity>
))
}
</View>
<View style={{marginRight: 50}}>
<Text style={{marginTop: 40, textAlign:"right",fontWeight: "bold"}}>STAY IN TOUCH</Text>
<TextInput style={{textAlign:"right", marginTop: 10, borderColor: 'black'}}placeholder="Sign up for GOLDENSHOE news" type="text" />
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
marginLeft: 10
},
header: {
fontWeight: 'bold',
marginTop: 40,
marginBottom: 30,
color: "lightgreen",
fontSize: 30,
},
button: {
alignItems: 'flex-start',
marginTop: 30,
flexDirection: 'column',
borderBottomColor: "black",
borderBottomWidth: 1,
borderTopColor: "black",
borderTopWidth: 1,
},
listCont: {
padding: 10,
marginTop: 3,
borderBottomWidth: 1
},
login: {
borderRadius: 10
}
})
export default Profile;

React native flatlist multiple selection is not updating

I am using a flatlist to expose all the list of ingredients I have saved on my database, but once I update the state, it is not reflecting on the flatlist component.
The flatlist component
<FlatList
horizontal
bounces={false}
key={ingredientList.id}
data={ingredientList}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => selectedIngredient(item)}>
<Card key={item.id}>
<Text key={item.title} style={styles.titleText}>{item.name}</Text>
<Text key={item.title} style={styles.titleText}>{item.isSelected?'selected':'not selected'}
</Text>
<ImageBackground key={item.illustration} source={item.illustration} style={styles.cardImage}>
</ImageBackground>
</Card>
</TouchableOpacity>
)}
keyExtractor={(item) => item.index}
/>
This is the function that find the selected item "selectedIngredient"
function selectedIngredient(item) {
console.log('received: ', item.name)
item.isSelected = !item.isSelected;
return { ...item.isSelected }
}
That component call is working when I try debbug with console.log after the "item.isSelected = !item.isSelected", but the IU is not updated. Can someone help me to understand how to fix it?
You need to set state by using either setState in a class-based component or either using useState hook in the functional component.
function selectedIngredient(item) {
console.log('received: ', item.name)
item.isSelected = !item.isSelected; //this is not how you set state
return { ...item.isSelected }
}
Screenshot:
here is our old example which I modified for your current scenario:
import React, { useState } from 'react';
import {
Text,
View,
StyleSheet,
FlatList,
TouchableOpacity,
} from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
// or any pure javascript modules available in npm
const ingredientList = [
{
id: 1,
name: 'item1',
selected: false,
},
{
id: 2,
name: 'item 2',
selected: false,
},
{
id: 3,
name: 'item 3',
selected: false,
},
{
id: 8,
name: 'item 4',
selected: false,
},
{
id: 4,
name: 'item 5',
selected: false,
},
{
id: 5,
name: 'item 6',
selected: false,
},
];
export default function App() {
const [selectedItem, setSelectedItem] = useState(null);
const [allItems, setAllItems] = useState(ingredientList);
const selectedIngredient = (item) => {
console.log('selecionado: ' + item.name);
setSelectedItem(item);
/* Below operation can be improved by passing index to the function itself.
so filtering would not be required
*/
let temp = allItems.filter((parentItem) => parentItem.id !== item.id);
item.selected = !item.selected;
temp = temp.concat(item);
temp.sort((a, b) => parseInt(a.id) - parseInt(b.id));
setAllItems(temp);
console.log(allItems);
};
return (
<View style={styles.container}>
<FlatList
style={styles.flatlist}
horizontal
bounces={false}
data={allItems}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.flatListItem}
key={item.id}
onPress={() => selectedIngredient(item)}>
<Text>{item.name}</Text>
{!item.selected ? (
<Text style={{ color: 'red' }}>{'Not Selected'}</Text>
) : (
<Text style={{ color: 'green' }}>{'Selected'}</Text>
)}
</TouchableOpacity>
)}
keyExtractor={(item) => item.index}
/>
{selectedItem ? (
<View style={styles.selectedTextView}>
<Text style={styles.selectedText}>{`${selectedItem.name} ${
selectedItem.selected ? 'selected' : 'not selected'
}`}</Text>
</View>
) : (
<View style={styles.selectedTextView}>
<Text style={styles.selectedText}>{`Nothing selected`}</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
flatListItem: {
width: 100,
height: 100,
backgroundColor: 'white',
margin: 5,
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
},
selectedTextView: {
flex: 8,
backgroundColor: 'white',
margin: 5,
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
fontSize: 20,
},
selectedText: {
fontSize: 30,
},
});
Live Demo

How do I center the text within the lightblue flexbox?

import React, { Component } from 'react';
import { View, Text, FlatList, TouchableOpacity, Dimensions, StyleSheet } from 'react-native';
const data = [
{id: 'Music', value: 'Music'},
{id: 'Events', value: 'Events'},
{id: 'About Us', value: 'About Us'},
{id: 'Benefits', value: 'Benefits'},
{id: 'Account', value: 'Account'},
{id: 'Social Media', value: 'Social Media'},
{id: 'FAQ', value: 'FAQ'},
{id: 'Settings', value: 'Settings'}
];
const numColumns = 2;
const size = Dimensions.get('window').width/numColumns;
export const Grid = () => {
return (
<FlatList
style={{ marginTop: 20 }}
data={data}
renderItem={({item}) => (
<TouchableOpacity style={styles.itemContainer}>
<Text style={styles.item}>{item.value}</Text>
</TouchableOpacity>
)}
keyExtractor={item => item.id}
numColumns={numColumns} />
);
}
const styles = StyleSheet.create({
itemContainer: {
width: size,
height: size
},
item: {
flex: 1,
margin: 15,
fontSize: 25,
fontWeight: 'bold',
color: 'white',
backgroundColor: 'lightblue'
}
});
I want to be able to center text in both axes
I tried using justifyContent: "center" in the child and parent views but it doesn't work.
textAlign: "center" is able to align the text horizontally.
try like this.
export const Grid = () => {
return (
<FlatList
style={{ marginTop: 20 }}
data={data}
renderItem={({item}) => (
<TouchableOpacity style={styles.itemContainer}>
<View style={styles.item}>
<Text style={styles.itemText}>{item.value}</Text>
</View>
</TouchableOpacity>
)}
keyExtractor={item => item.id}
numColumns={numColumns} />
);
}
const styles = StyleSheet.create({
itemContainer: {
width: size,
height: size
},
item: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 15,
backgroundColor: 'lightblue'
},
itemText: {
fontSize: 25,
textAlign: 'center',
fontWeight: 'bold',
color: 'white',
}
});
Please attach a screenshot, asking questions about designing in react native. Coming to the answer you can try this.
item:{
alignSelf: 'center',
flex: 1,
margin: 15,
fontSize: 25,
fontWeight: 'bold',
color: 'white',
backgroundColor: 'lightblue'
},
itemContainer: {
width: size,
height: size,
justifyContent: 'center',
alignItems: 'center'
},
Your itemContainer class is missing the display: flex property. This is needed to use flexbox properties on the flex items.

Categories