Vertically Stacked Views with Static and Dynamic Heights - React Native - css

I am trying to acheive what the image below represents with Flexbox in React Native with Views, if you have a basic example of this that would be amazing:

Something like this:
<View style={{ flex: 1, flexDirection: 'column'}}>
<View style={{ height: 70, backgroundColor: 'blue' }}>
</View>
<View style={{ height: 70, backgroundColor: 'green' }}>
</View>
<View style={{ flex: 1, backgroundColor: 'yellow' }}>
</View>
</View>
Not sure if the blue lines are lines / padding / etc, but you should be able to add those into this shell.

Related

Partially changing background color of a <View> component in React Native based on %

So I have these Views in react native I am using as cards, and I want to partially change the background of the view based on a %
So for example I would find what % 230 is of 1000 and I would fill the background of the card that % to a different color. Anyone have any suggestions on doing the background color with a % like that? I know I can fill it with border and border width but the issue is that pushes the content out of the way to fill it. I need the content to stay in place but the background color change partially based on the %. I also tried making another View overtop of this one and adding the border and border width and filling the top one, but that covers the content of the bottom one, which doesnt really help either.
Not sure a code snippet is needed for this question but screw it:
<View key={value.title + index} style={{ backgroundColor: 'white', margin: 10, borderRadius: 5, width: '90%', height: 70, alignSelf: 'center', justifyContent: 'center' }}>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View style={{ margin: 15 }}>
<IconX
size={30}
origin={ICON_TYPE.FONT_AWESOME5}
name={'piggy-bank'}
color={'black'}
/>
</View>
<View style={{ flexDirection: 'column', width: 125 }}>
<Text style={{ fontWeight: 'bold' }}>{value.title}</Text>
{value.date && (
<Text>{value.date.toDateString()}</Text>
)}
</View>
<View style={{ flexDirection: 'column', marginLeft: '-5%' }}>
<View style={{ width: 150 }}>
<Text style={{ fontWeight: 'bold', textAlign: 'right', color: '#F36A53' }}> ${value.currentAmount} / ${value.goalAmount}</Text>
</View>
</View>
</View>
</View>
I ended up just adding another card overtop of it and just using a transparent border color so it didnt cover the content, but I am not totally happy with this solution, so am open to any other answers. Thanks.

Display inline-block equivalent in react native

I need to achieve this:
https://jsfiddle.net/ghxfpL7j/1/
In React Native but:
You can't have a View inside a Text
You can't set a margin or padding for a Text
I tried having the "C" inside a View and the text and then another view for the other Text with the number but I couldn't achieve the same because when the name is too long it does not work.
This is what I tried:
<View style={a}>
<View style={b}><Text style={c}>C</Text></View>
<Text style={d}>Player name</Text>
<View style={e}>20</View>
</View>
and then styles:
a: {
flexDirection: 'row',
flexWrap: 'wrap'
}
b:{
width: 20,
backgroundColor: '#000'
}
c:{
color: '#ddd
}
d:{
flex: 1,
text-align: 'right'
}
e:{
text-align: 'right'
}
Per your link, which could be:
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 1 }}>
<Text>C</Text>
</View>
<Text>Player Name</Text>
<Text>25</Text>
</View>

React Native shadow adds shadow to everything inside card

I am trying to generate a box shadow equivalent for React Native.
Here is my code:
<View style={{
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 5,
},
shadowOpacity: 1,
shadowRadius: 5,
elevation: 5,
}}
>
<View styleName={"card promocard cardsize"} style={{
marginBottom: this.state.promoBottom, marginRight: this.state.promoRight,
}}>
<View styleName="promo-name" style={{ backgroundColor: this.rand }}>
<View styleName="promo-name-child">
<Image style={{ borderRadius: 50, resizeMode: "contain", backgroundColor: "#FFF" }} styleName="promocard-logo-img" source={{ url: this.props.promo.merchant.logo }} />
<Text style={{ color: "#fff" }} styleName="promo-name-text">{this.props.promo.merchant.name}</Text>
</View>
</View>
<View styleName="promo-inner-card">
<Image styleName="promo-main-img" source={{ url: this.props.promo.photo }} />
<View>
<View styleName="promo-title">
<Text styleName="promo-title-text">{this.props.promo.title}</Text>
</View>
<View styleName="promo-desc">
<Text styleName="promo-desc-text">{this.props.promo.text}</Text>
</View>
</View>
</View>
</View>
</View>
Rather than generate styles correctly around the rectangle (which is 330 by 175), it seems to apply the shadow to every element INSIDE the box.
I want something that looks like this:
https://ethercreative.github.io/react-native-shadow-generator/
I have been tearing my hair out, because every example I am seeing looks similar to the code I've got in my top level view, and yet I am getting shadows on all the text, and the images inside my view.
This was solved by adding a background color.
backgroundColor: "#FFF"

React native flexbox how to align items vertically?

I'm a bit confused as to why this flex won't work.
<View
style={{
display: "flex",
flexWrap: "wrap"
}}
>
<View style={{ width: "40%", alignSelf: "flex-start" }}>
<Button BUY</Button>
<View style={{ alignSelf: "center", marginTop: "2%" }}>// A logo</View>
</View>
<View style={{ width: "40%", alignSelf: "flex-end" }}>
<AreaChart
style={{ height: 250 }}
dataPoints={data}
contentInset={{ top: 30, bottom: 30 }}
curve={shape.curveNatural}
svg={{
fill: "rgba(134, 65, 244, 0.2)",
stroke: "rgb(134, 65, 244)"
}}
/>
</View>
</View>;
The intended layout I want to have is:
BUTTON | <CHART
LOGO | CHART>
The button and logos centered together, and the chart taking up both "boxes" on the right.
However, the above markup produces the following:
BUTTON |
LOGO |
| CHART
| CHART
They're doing the right thing but the Chart starts where the logo ends.
Where did I go wrong with flexbox? How do I produce the right layout?
As the default flexDirection in React Native is column, flex items will stack vertically, hence the chart renders on a row of its own.
By using alignSelf: "flex-end" on the 2nd child View, which for columns control the cross axis (horizontal), it will right align.
To align them side-by-side, add flexDirection: "row" to the parent View.
You can also remove both the alignSelf properties on the two child View's, unless you want the 2nd View (alignSelf: "flex-end") align to bottom.
Updated code sample
<View style={{
display: "flex",
flexDirection: "row",
flexWrap: "wrap"
}}>
<View style={{width: "40%"}}>
<Button
BUY
</Button>
<View style={{alignSelf: "center", marginTop: "2%"}}>
// A logo
</View>
</View>
<View style={{ width: "40%"}}>
<AreaChart
style={{height: 250}}
dataPoints={data}
contentInset={{top: 30, bottom: 30}}
curve={shape.curveNatural}
svg={{
fill: 'rgba(134, 65, 244, 0.2)',
stroke: 'rgb(134, 65, 244)',
}}
/>
</View>
</View>

How can I mix fixed and dynamic size elements in a flexbox container?

I'm trying to create a layout that utilizes flexbox' automatic sizing but also contains fixed-size items:
<View style={{ height: 70, alignItems: "center" }}>
<Text style={{ flex: 1, textAlign: "right", paddingRight: 10 }}>left text</Text>
<Image style={{ width: 70, height: 70 }} src={require('./img.png')} />
<Text style={{ flex: 1, textAlign: "left", paddingLeft: 10 }}>right text</Text>
</View>
I want the image to be centered in the UI and have the text views equally take the remaining width. The actual result is that one of the text views is larger than the other as if the rendering doesn't take the width of the image view into account.
Finally found the correct way of doing this. To have fixed size items in a flex layout one shouldn't use width/height but flex: 0 and flexBasis. This approach initially didn't work for me because a component wrapping my component wasn't sized correctly and messed with the flex rendering. flexBasis seems to be density-independent pixels when it is set to an absolute number.
Proof of concept on expo.io
import React, { Component } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Constants } from 'expo';
export default class App extends Component {
render() {
return (
<View>
<Text>Test</Text>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
<Text>Test</Text>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
view: {
flex: 0,
flexBasis: 50,
height: 50,
backgroundColor: "red",
},
text1: {
flex: 1,
textAlign: "right",
paddingRight: 10,
},
text2: {
flex: 1,
textAlign: "left",
paddingLeft: 10,
}
});

Resources