Adding a solid stroke to Text - react-native

I am trying to add a thick solid stroke to some Text in React Native. I've added a snippet with the desired CSS.
I've tried directly applying the CSS via styled-components but I get an error stating that my value is unable to be parsed.
const Title = styled.Text`
text-shadow: 2px 2px 0px #000, -2px -2px 0px #000, 2px -2px 0px #000, -2px 2px 0px #000;
`;
I have tried using textShadow but this does not apply a solid stroke. This prop relies on a width and height prop for an offset.
Here's a snack for example - https://snack.expo.io/#hannigan/ba7574
h1 {
text-shadow: 2px 2px 0px #000, -2px -2px 0px #000, 2px -2px 0px #000, -2px 2px 0px #000;
color: white;
font-family: 'Arial';
}
<h1>Hello World</h1>

So this works for me, are you sure that it won't work for you in dynamic height?
Edit: I might have now found what you were talking about. I am checking if I can update the snack to work for dynamic views.
Edit2: Alright, made it work. You just need to make the first text non-absolute.
https://snack.expo.io/Bk8ifP!4I
Edit3: As mentioned by Vencovsky it might break if you need to use flex around it. You can hack it with a onLayout like in this Snack: https://snack.expo.io/HJ!PRUKNL
basically you save the height of the text and then use it for height and margin on other views. It hacky, but I have used it in other settings and works fine.
export default class App extends React.Component {
render() {
const myText = 'Hello World. This is my very long text, that can be a few lines height'
return (
<View style={styles.container}>
<View>
<Text style={[styles.paragraph]}>{myText}</Text>
<Text style={[styles.paragraph, styles.abs, {textShadowOffset: {width: -2, height: -2}}]}>{myText}</Text>
<Text style={[styles.paragraph, styles.abs, {textShadowOffset: {width: -2, height: 2}}]}>{myText}</Text>
<Text style={[styles.paragraph, styles.abs, {textShadowOffset: {width: 2, height: -2}}]}>{myText}</Text>
</View>
<Text> 'Here another text' </Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8
},
paragraph: { fontSize: 50, color: '#FFF', textShadowColor: 'black', textShadowRadius: 1, textShadowOffset: {
width: 2,
height: 2
}},
abs: {
position: 'absolute',
top: 0, left: 0, right: 0, bottom: 0
}
});

I couldn't find a way to do this with react native's css but I found a way to do a stoke in the text with react-native-svg
<Svg height="60" width="200">
<Text
fill="none"
stroke="purple"
fontSize="20"
fontWeight="bold"
x="100"
y="20"
textAnchor="middle"
>
STROKED TEXT
</Text>
</Svg>
Edit
I know this answer isn't the perfect one, but so far is the only answer I found to do this, but unfortunately it isn't good for dynamic text.

Related

Align view and Text for responsive screen in React Native

I want to align all view and text parts like the above image. if the number may be big or small but the upper title should be in the middle of the value.
same alignment for the right side views also.
and the view and alignment should be responsive for every ios and android.
I have tried:
<ZekifutSchumView>
<ZekifutSchumText>סה”כ</ZekifutSchumText>
</ZekifutSchumView>
<HefreshimForLoTashlumView>
<HefreshimForLoTashlumText>
{props.hefreshimTotalForLoTashlum}
</HefreshimForLoTashlumText>
</HefreshimForLoTashlumView>
const ZekifutSchumText = styled(Text)``;
const ZekifutSchumView = styled(View)`
right: 2px;
`;
const HefreshimForLoTashlumView = styled(View)`
top: 15px;
${Platform.select({
ios: `
right: 30px;
`,
android: `
right: 26px;
`,
})};
border-right-width: 1px;
border-color: #ddd;
height: 18px;
`;
const HefreshimForLoTashlumText = styled(Text)`
${Platform.select({
ios: `
right: 20px;
`,
android: `
right: 21px;
`,
})};
`;
The same code is for the right side view also.
How can I align these view??
<View style={styles.app}>
<View style={{flexDirection: 'row', justifyContent: 'space-evenly'}}>
<View style={{alignItems: 'center'}}>
<Text>$</Text>
<Text>123,345,77</Text>
</View>
<View style={{
height: '50%',
width: 1,
backgroundColor: 'grey',
position: 'absolute',
bottom: 0}}/>
<View style={{alignItems: 'center'}}>
<Text>$</Text>
<Text>123,345,77</Text>
</View>
</View>
</View>
Note: pls do not use inline styles, just added them here for easy viewing

Horizontal ScrollView Not Scrolling in React Native

I'm trying to render a horizontal scroll view of clickable photos.
The vertical scroll works fine, but once I set horizontal={true}, I'm limited to how far I can scroll horizontally. It prevents me from scrolling more than what is shown in this image.
<Container>
<ScrollView
horizontal={true}
contentContainerStyle={{
flex: 1,
paddingTop: "5%"
}}
>
{posts.map(post => {
return (
<TouchableOpacity
key={post.id}
style={{
width: width,
flex: 1,
height: height / 3,
borderRadius: "8px",
overflow: "hidden",
marginRight: "2%"
}}
>
<Thumbnail
source={{
uri: uri`
}}
/>
<PostTitle>{post.name}</PostTitle>
</TouchableOpacity>
);
})}
</ScrollView>
</Container>
const Container = styled.View`
flex: 1;
padding-top: 18%;
background: #fff;
`;
const Title = styled.Text`
color: #333;
text-transform: uppercase;
font-weight: 600;
padding-left: 8%;
padding-bottom: 5%;
`;
const Thumbnail = styled.Image`
flex: 1;
justify-content: center;
align-items: center;
resize-mode: cover;
`;
const PostTitle = styled.Text`
color: #fdfdfd;
font-size: 16px;
font-weight: bold;
position: absolute;
top: 10%;
left: 8%;
`;
Fixed. Removed "marginRight" and it worked. Horizontal ScrollView doesn't like styling its children's margins.
The problem certainly is from the margin. However, I've found that specifically, setting the margin in percentage values or adding flex: 1 to contentContainerStyle is what causes this problem.

React Native: Text gets cut when using numberOfLines & align-items

I'm trying to style a Splash Screen, I'm using styled-components.
I want the Text & Image to be swipeable on the screen so I created a card.
now the text in the card gets broken only on android, it just gets cuts off when I use align-items with numberOfLines
Here is the Splash Screen
import React from "react";
import { StyleSheet, Text, Dimensions, Button } from "react-native";
import styled from "styled-components/native";
import SplashCard from "../components/SplashCard";
const windowWidth = Dimensions.get("window").width;
const windowHeight = Dimensions.get("window").height;
export default class SplashScreen extends React.Component {
render() {
return (
<Container>
<LogoView>
<Text style={logo.text}>
{" "}
Jennya's <Text style={logo.studio}>Studio </Text>
</Text>
</LogoView>
<CardView>
<SplashCard />
</CardView>
<DotsView></DotsView>
<ButtonView></ButtonView>
<LoginView></LoginView>
</Container>
);
}
}
//Container And Background
const Container = styled.View`
flex: 1;
margin-top: 30px;
margin-bottom: 20px;
margin-left: 18px;
margin-right: 18px;
flex-direction: column;
background-color: #ffffff;
`;
const LogoView = styled.View`
width: 100%;
height: 10%;
background-color: #ff0;
justify-content: center;
align-items: center;
`;
//Logo Styling
const logo = StyleSheet.create({
text: {
fontFamily: "Carrington",
fontSize: 42,
fontWeight: "normal",
fontStyle: "normal",
letterSpacing: -1.01,
textAlign: "center",
color: "#7356bf",
},
studio: {
color: "#ffc043",
},
});
const CardView = styled.View`
height: 55%;
background-color: #7532a8;
`;
const DotsView = styled.View`
height: 3%;
background-color: #eb0e28;
`;
const ButtonView = styled.View`
height: 27%;
background-color: #2929;
`;
const LoginView = styled.View`
height: 5%;
background-color: #f929;
`;
Here is the Splash Screen Card
import React from "react";
import styled from "styled-components/native";
import { Dimensions } from "react-native";
const window = Dimensions.get("window");
//Image Ratio
const ratio = window.width / 240;
const SplashCard = (props) => (
<Container>
<ImageView>
<IllustrationImage
resizeMode="contain"
source={require("../../assets/Illustartions/Illustration1.png")}
/>
</ImageView>
<TitleView>
<Title>Welcome</Title>
</TitleView>
<TextView>
<Text numberOfLines={4} style={{ flex: 1, flexWrap: "wrap" }}>
This can either be a string or a function. Strings are with the rules
as-is. Functions will receive the styled component's props as the first
and only argument.
</Text>
</TextView>
</Container>
);
export default SplashCard;
//Main Card Container
const Container = styled.View`
flex: 1;
background-color: #ffffff;
`;
//Image Position & Size
const ImageView = styled.View`
height: 70%;
justify-content: center;
align-items: center;
background-color: #0f48a3;
`;
const IllustrationImage = styled.Image`
flex: 1;
height: ${ratio * 240}px;
width: ${window.width}px;
max-width: 240px;
max-height: 240px;
`;
//Title Position & Size
const TitleView = styled.View`
height: 10%;
justify-content: center;
align-items: center;
background-color: #8d14de;
`;
const Title = styled.Text`
flex: 1;
font-family: Metropolis-SemiBold;
font-size: 30px;
font-weight: 600;
font-style: normal;
letter-spacing: -0.72px;
text-align: center;
color: #000000;
`;
//Text View
const TextView = styled.View`
flex: 1;
background-color: #db07bf;
`;
//Text Style
const Text = styled.Text`
font-family: Metropolis-Medium;
font-size: 18px;
font-weight: 500;
font-style: normal;
letter-spacing: 1.1px;
text-align: center;
color: #171415;
`;
Here is What it looks like on both android and ios
Image of the cut text in android
Setting a margin around the Text might do the trick. For example, set marginHorizontal style to Text in SplashCard
<Text numberOfLines={4} style={{ flex: 1, flexWrap: "wrap", marginHorizontal:10 }}>
This can either be a string or a function. Strings are with the rules
as-is. Functions will receive the styled component's props as the first
and only argument.
</Text>

View is shaking by no reason on React Native iOS

I have detected a weird behaviour in the RN app I'm developing. By no reason apparently, one of the components of the screen starts to shake when refresh the app. This happens both on iOS simulator and iPhone device. It does not happen every time I refresh, but most of the time, and when it happens the simulator becomes unresponsive.
Here is the GIF of what happens: https://gph.is/g/EvAqBgg
Here is the code of the screen and the shaking component:
Screen
<Container>
<SafeAreaView />
<Header>
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<MaterialIcons name="menu" size={24} color="black" />
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate('Filter')}>
<MaterialIcons name="search" size={24} color="black" />
</TouchableOpacity>
</Header>
<FlatList
data={products}
renderItem={({ item }) => (
<ProductItem
product={item}
onPress={() => navigation.navigate('Product', { product: item })}
/>
)}
keyExtractor={(item) => item.id}
numColumns={2}
ListEmptyComponent={() => <Text>No hay elementos</Text>}
ListHeaderComponent={<HomeHeader />}
></FlatList>
<ShoppingCartButton
items={itemsInCart}
onPress={() => navigation.navigate('ShoppingCart')}
price={price}
></ShoppingCartButton>
</Container>
);
}
const Container = styled.View`
flex: 1;
align-items: center;
justify-content: center;
background-color: white;
`;
const Header = styled.View`
width: 100%;
height: 40px;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-left: 16px;
padding-right: 16px;
`;
Shaking component
export default function ShoppingCartButton({ onPress, price, items }) {
return (
<ButtonArea>
<Container onPress={onPress}>
<CartIndicator>
<CartQuantity>{items}</CartQuantity>
</CartIndicator>
<ButtonTitle>Ver carrito</ButtonTitle>
<Price>{price} €</Price>
</Container>
<SafeAreaView />
</ButtonArea>
);
}
const ButtonArea = styled.View`
width: 100%;
padding: 16px;
border-top-width: 1px;
border-top-color: ${colors.separatorGrey};
background-color: ${colors.white};
box-shadow: 0px -4px 4px rgba(222, 222, 222, 0.2);
`;
const Container = styled.TouchableOpacity`
height: 48px;
width: 100%;
flex-direction: row;
justify-content: space-between;
align-items: center;
background-color: ${colors.mainBlue};
border-radius: 5px;
padding-left: 16px;
padding-right: 16px;
`;
const CartIndicator = styled.View`
background-color: #2c81ab;
padding: 4px;
padding-left: 8px;
padding-right: 8px;
border-radius: 3px;
`;
const CartQuantity = styled.Text`
font-family: 'Medium';
color: ${colors.white};
`;
const ButtonTitle = styled.Text`
font-family: 'Medium';
color: ${colors.white};
`;
const Price = styled.Text`
font-family: 'Book';
color: ${colors.white};
`;
Try using https://www.npmjs.com/package/react-native-safe-area-context instead of SafeAreaView from React Native.
Another thing you can try is to set fixed height to ButtonArea component.
Can't guarantee that these will work, but it fixed the shaking issue for me.

Icon to de right side of the view React-native

im trying to keep my icon in the right side of View component. But im failed.
<StyledView>
<StyledListItem {...props}>
{value}
<Icon name="add" size={24} style={{ right: 0 }} />
</StyledListItem>
<StyledLine></StyledLine>
</StyledView>
styles components:
import styled from 'styled-components/native';
import colors from "../../../styles/colors";
import { styledfont } from "../../../styles/fonts";
export const StyledList = styled.TextInput`
height: 40px;
border: 1px solid gray;
width: 100%;
padding: 0 10px;
`;
export const StyledListItem = styled.Text`
${styledfont.h4}
color: ${colors.blue.primary};
width: 72%;
margin-bottom: 15px;
margin-top: 13px;
margin-left:28px;
flex-direction: row;
`;
export const StyledView = styled.View`
width: 100%;
height: 68px;
`;
export const StyledLine = styled.View`
width: 100%;
height: 1px;
background-color: ${colors.blue.primaryopc20};
`;
export const StyledContainer = styled.View`
width: 100%;
top: 0;
flex: 1;
`;
I try a lot of things, someone can help me? I think that I should use something like flex row, but I do not know how to apply that.
You can add positioning to your components. In this case, I'd try:
<StyledView>
<StyledListItem style={{position: 'relative'}} {...props}>
{value}
<Icon name="add" size={24} style={{ position: 'absolute', right: 0 }} />
</StyledListItem>
<StyledLine></StyledLine>
</StyledView>
You can even leave out the relative positioning on the parent since in react native everything is positioned relative by default
you can wrap icon in view and use marginLeft:'auto' property as:-
```
<StyledView>
<StyledListItem {...props}>
{value}
<View style={{marginLeft:'auto'}}>
<Icon name="add" size={24} style={{ right: 0 }} />
</View>
</StyledListItem>
<StyledLine></StyledLine>
</StyledView>
```