Different style files for different components - react-native

I'm learning react-native and have came up with a problem. I'm following a Tutorial series but might have missed something. I'm trying to use different style files for different components but the styles doesn't seem to apply.
Here is the snippet of the code:
index.ios.js
import React, {
AppRegistry,
Component,
Text,
View,
StatusBar
} from 'react-native';
StatusBar.setBarStyle('light-content');
class iTunesBrowser extends Component {
render() {
return (
<View style={styles.global.mainContainer} >
<View style={styles.navbar.appearance}>
<View style={styles.navbar.button} ></View>
<Text style={styles.navbar.title}>iTunesBrowser</Text>
<Text style={styles.navbar.button} >Search</Text>
</View>
<View style={styles.global.content}>
<Text> Some Text </Text>
</View>
</View>
);
}
}
import styles from './styles';
AppRegistry.registerComponent('iTunesBrowser', () => iTunesBrowser);
styles.js
export default {
global: require('./styles/global'),
navbar: require('./styles/navbar')
};
styles/global.js
import React, {StyleSheet} from 'react-native';
export default StyleSheet.create({
mainContainer: {
flex: 1
},
content: {
flex: 1,
backgroundColor: '#ccc'
}
});
styles/navbar.js
import React, {StyleSheet} from 'react-native';
export default StyleSheet.create({
appearance: {
backgroundColor: '#003333',
paddingTop: 30,
paddingBottom: 10,
flexDirection: 'row'
},
title: {
color: '#FFFFFF',
textAlign: 'center',
fontWeight: 'bold',
flex: 1
},
button: {
width: 50,
color: '#FEFEFE',
textAlign: 'center'
}
});
The styles work when put on the index or in a single style file.

I've tried your example and it works when you use JS files with this pattern:
import React, {StyleSheet} from 'react-native';
var global = StyleSheet.create({
mainContainer: {
flex: 1
},
content: {
flex: 1,
backgroundColor: '#ccc'
}
});
module.exports = global;
and
import React, {StyleSheet} from 'react-native';
var navbar = StyleSheet.create({
appearance: {
backgroundColor: '#003333',
paddingTop: 30,
paddingBottom: 10,
flexDirection: 'row'
},
title: {
color: '#FFFFFF',
textAlign: 'center',
fontWeight: 'bold',
flex: 1
},
button: {
width: 50,
color: '#FEFEFE',
textAlign: 'center'
}
});
module.exports = navbar;

The typical way to work with component styles in React Native is to keep the creation of your StyleSheets in the components themselves, not in separate files as you may be used to on the web with CSS. That way everything about the Component, the structure and the style are in the same file.
You can still have a global stylesheet, and pull in those styles when needed, but keep Component styles in the Component.
For a great example on how the community and Facebook recommends styling your components check out: http://makeitopen.com/

Related

React-Native-Paper surface component not loading

I have a component that loads into my app, however I can't get the Surface component to load. The text inside it renders fine, however the parent Surface component does not. It also does not appear in the inspector
My component is below. Any ideas?
import React, {useState, useContext} from 'react';
import {StyleSheet, View} from 'react-native';
import {Surface, Text} from 'react-native-paper';
function UpComing({navigation}) {
return (
<View style={styles.container}>
<Text style={{fontWeight: 'bold', fontSize: 15}}>Upcoming Classes</Text>
<Surface styles={styles.surface}>
<Text>Test</Text>
</Surface>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginHorizontal: 20,
marginVertical: 10,
},
surface: {
padding: 8,
height: 80,
width: 80,
alignItems: 'center',
justifyContent: 'center',
elevation: 4,
},
});
export default UpComing;

background color in cardview title (react-native)

I am trying to create a cardview in react-native with a title and body. however, i want to add a background color to the tittle but not able to do it.
i was able to create the cardview with a title header but not able to add a background color that covers the entire portion of the header.
see image attached for an example of what i want to implement.
As you can see, the card view has a tittle of summary and the title/header portion has a gray background. below the header is the body which contain the content of the cardview. i want to implement the same in react-native. can someone help? thanks in advance
//This is an example of Card View//
import React from 'react';
//import react in our code.
import { Text, View, StyleSheet } from 'react-native';
//import all the components we are going to use.
import { Card } from 'react-native-elements';
//import Card
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Card title="Local Modules">
{/*react-native-elements Card*/}
<Text style={styles.paragraph}>
This is a card from the react-native-elements
</Text>
</Card>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: 40,
backgroundColor: '#ecf0f1',
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});
Try this:
<Card title={
<View style={{ backgroundColor: 'red'}}>
<Text>Local Modules</Text>
</View>
}
...
/>
Edit your code like this :
//This is an example of Card View//
import React from 'react';
//import react in our code.
import { Text, View, StyleSheet } from 'react-native';
//import all the components we are going to use.
import { Card } from 'react-native-elements';
//import Card
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Card title="Local Modules">
<View style={styles.header}>
<Text> Summary </Text>
</View>
<Text style={styles.paragraph}>
This is a card from the react-native-elements
</Text>
</Card>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: 40,
backgroundColor: '#ecf0f1',
},
header: {
backgroundColor : '#C4C4C4'
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});

Native Base button with margin in style does not the text inside it

I wrote an app on react native using native base. when I try to put margin in button it will not show the text inside the button. How can I fix it?
When I delete the margin it work fine. but when i put the margin back it do not work. I search many source but no one show any solution at all.
Here is the code:
import React, { Component } from 'react';
import { Platform, StyleSheet, View, Image } from 'react-native';
import FloatLabelInput from './src/components/FloatLabelInput';
import {Button, Text} from 'native-base'
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Image
style={styles.background_Image}
source={require('./media/free-blurry-background-1636594.jpg')}
/>
<Image source={require('./media/Save-the-Children-Logo.png')}
style={{height: '10%', width: '100%'}}/>
<FloatLabelInput name='Username' security='false'/>
<FloatLabelInput name='Password' security='true'/>
<Button block rounded danger
onPress={() => console.log('my first app')}
style = {styles.button_style}
// accessibilityLabel="Learn more about this purple button"
>
<Text >LOGIN</Text>
</Button>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#C0C0C0',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
background_Image: {
backgroundColor: '#ccc',
flex: 1,
position: 'absolute',
width: '100%',
height: '100%',
justifyContent: 'center',
},
button_style: {
margin: '5%'
}
});
I believe this is a bug related to percentage by referring to this issue https://github.com/facebook/react-native/issues/19164.. For alternative solution try using px
button_style: {
margin: 5
}

React Native : how to import flexbox styles from another file js?

I'm a newbie in React Native, and I try to learn basic flexbox from tutorial point but I always get an error, I have two file index.android.js and MyPresentationalComponent.js for styles code file.
This error picture, when I run myproject
index.android.js
import React, { Component } from 'react';
import {
AppRegistry,
styles,
View
} from 'react-native';
import MyPresentationalComponent from './MyPresentationalComponent';
export default class belajar extends Component {
constructor() {
super();
this.state = {
myText: 'Lorem ipsum dolor sit amet.'
};
}
render() {
return (
<View>
<MyPresentationalComponent style={styles.container} />
</View>
);
}
}
AppRegistry.registerComponent('belajar', () => belajar);
MyPresentationalComponent.js
import React, { Component } from 'react';
import {
View,
StyleSheet
} from 'react-native';
const MyPresentationalComponent = (props) => {
return (
<View style={styles.container}>
<View style={styles.redbox} />
<View style={styles.bluebox} />
<View style={styles.blackbox} />
</View>
);
};
export default MyPresentationalComponent;
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'grey',
height: 600
},
redbox: {
width: 100,
height: 100,
backgroundColor: 'red'
},
bluebox: {
width: 100,
height: 100,
backgroundColor: 'blue'
},
blackbox: {
width: 100,
height: 100,
backgroundColor: 'black'
},
});
The problem is that you are not exporting the styles variable out of the file, and so it will not be visible to other files, even when you import the class marked with export default. I would suggest the following:
import React, { Component } from 'react';
import {
View,
StyleSheet
} from 'react-native';
const MyPresentationalComponent = (props) => {
return (
<View style={styles.container}>
<View style={styles.redbox} />
<View style={styles.bluebox} />
<View style={styles.blackbox} />
</View>
);
};
export default MyPresentationalComponent;
export const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'grey',
height: 600
},
redbox: {
width: 100,
height: 100,
backgroundColor: 'red'
},
bluebox: {
width: 100,
height: 100,
backgroundColor: 'blue'
},
blackbox: {
width: 100,
height: 100,
backgroundColor: 'black'
},
});
Then, your index.android.js should look like this:
import React, { Component } from 'react';
import {
AppRegistry,
styles,
View
} from 'react-native';
import MyPresentationalComponent, {styles} from './MyPresentationalComponent';
export default class belajar extends Component {
constructor() {
super();
this.state = {
myText: 'Lorem ipsum dolor sit amet.'
};
}
render() {
return (
<View>
<MyPresentationalComponent style={styles.container} />
</View>
);
}
}
AppRegistry.registerComponent('belajar', () => belajar);
Please note the difference between defaut exports and named exports. You can have just one default export, and the name that you give it is not relevant at all, when you import it, it can use a different name. For named imports, you need to use the curly braces notation and the name must be the same in both export and import . However, you can have as many of them as you want.
According to #Gui Herzog answer simplier solution to include any external style file can be done:
stylesheet file
import {
StyleSheet
} from 'react-native';
export default styles = StyleSheet.create({
// or export const styles = StyleSheet.create({
Container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
})
Than simply use in your components:
import styles from './styles'
// or import { styles } from './styles'
using:
<View style={styles.Container}>
The problem is because you're exporting only the component MyPresentationalComponentand not its StyleSheet. If you want to have global styles I recommend you to create a different file. You could call it Styles.js and export it so you can use on all components you need. For example:
import { StyleSheet } from 'react-native'
module.exports = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'grey',
height: 600
},
})
Then you can import it on your MyPresentationalComponent and Index.js using:
import STYLES from 'Styles.js'
And to use you could:
<Component style={STYLES.container} />
Hope this helps!

Text wrap with chevron on right in React Native ListView item renderer

I am trying to have a list view show up that looks similar to this. The problem I am trying to solve is regarding word wrapping of the label. I do have it working with the code below, but it feels like a hack and doesn't work with device rotation. There has to be a way to do it without using Dimensions and styling.
Here is what I have.
import React, { Component } from 'react';
import {
StyleSheet,
Dimensions,
TouchableOpacity,
Text,
View
} from 'react-native';
import Moment from 'moment'
import Icon from 'react-native-vector-icons/FontAwesome';
class ProjectListItemRenderer extends Component {
componentDidMount() {
//alert(Dimensions.get('window').height)
}
render() {
return (
<View style={styles.projectRow}>
<View style={{width: Dimensions.get('window').width - 50}}>
<Text style={styles.itemName}>{this.props.name}</Text>
<Text style={styles.itemDetails}>{`${Moment(this.props.lastUpdated).fromNow()}`}</Text>
</View>
<View style={styles.moreContainer}>
<Icon name="chevron-right" size={15} style={styles.moreIcon} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
projectRow: {
flexDirection: 'row',
justifyContent: 'flex-start',
padding: 15,
},
itemName: {
fontSize: 18,
color: '#4A90E2',
},
itemDetails: {
fontSize: 12,
color: '#BBBBBB',
},
moreContainer: {
justifyContent: 'center',
alignItems: 'center'
},
moreIcon: {
color: "#d6d7da"
}
});
module.exports = ProjectListItemRenderer;
The other option I tried was absolute positioning, with the label being 20px from the right, and then absolute positioning the chevron on the right. The problem I ran into there was trying to figure out the height of the individual listItem renderer after it is rendered (and word wrapped).
The problem comes from having flexDirection: 'row' in the View containing your text. This makes the text overflow to the right instead of wrapping. If you want your text to wrap, the containing View must have flexDirection: 'column' in the style.
I've modified your code accordingly:
import React, { Component } from 'react';
import {
StyleSheet,
Dimensions,
TouchableOpacity,
Text,
View
} from 'react-native';
import Moment from 'moment'
import Icon from 'react-native-vector-icons/FontAwesome';
class ProjectListItemRenderer extends Component {
componentDidMount() {
//alert(Dimensions.get('window').height)
}
render() {
return (
<View style={styles.projectRow}>
<View style={styles.projectText}>
<Text style={styles.itemName}>{this.props.name}</Text>
<Text style={styles.itemDetails>
{`${Moment(this.props.lastUpdated).fromNow()}`}
</Text>
</View>
<View style={styles.moreContainer}>
<Icon name="chevron-right" size={15} style={styles.moreIcon} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
projectText: {
flex: 1,
flexDirection: 'column'
},
projectRow: {
flexDirection: 'row',
justifyContent: 'flex-start',
padding: 15,
},
itemName: {
fontSize: 18,
color: '#4A90E2',
},
itemDetails: {
fontSize: 12,
color: '#BBBBBB',
},
moreContainer: {
justifyContent: 'center',
alignItems: 'center'
},
moreIcon: {
color: "#d6d7da"
}
});
module.exports = ProjectListItemRenderer;
The only difference is I replaced {width: Dimensions.get('window').width - 50} with {flex: 1, flexDirection: 'column'}.