react-native, extended stylesheet and bootstrap
Learning how to use styles with react-native
I’ve learned that in order to apply styles to react-native, I would use StyleSheet
as such:
// src/components/Header.jsx
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
function Header() {
return (
<View>
<Text style={styles.heading}>Heading</Text>
</View>
)
}
const styles = StyleSheet.create({
heading: {
fontSize: 20,
textAlign: 'center'
}
})
In keeping with my goal of reusing as much of the existing app as possible, I want to use Bootstrap for basic styles. This can be achieved with StyleSheet.compose
. (I’m also splitting the styles into its own module.)
// src/components/Header.jsx
import React from 'react';
import { View, Text } from 'react-native';
import styles from './Header.style.js';
function Header() {
return (
<View>
<Text style={styles.heading}>Heading</Text>
</View>
)
}
// src/components/Header.style.js
import { StyleSheet } from 'react-native';
import BootstrapStyleSheet from 'react-native-bootstrap-styles';
const { bs } = new BootsrtapStyleSheet();
const styles = StyleSheet.create({
heading: {
fontSize: 20,
textAlign: 'center'
}
});
export default {
...styles,
heading: StyleSheet.compose(bs.s1, styles.heading)
}
So far, it’s pretty straightforward.
Next, I want to use CSS features such as rem
units and custom properties, in order to keep the native design as consistent with the web design as possible. From some searching around, the way to use those features is with react-native-extended-stylesheet
. A simple example of its usage would look like so:
// src/components/Header.jsx
import React from 'react';
import { View, Text } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
function Header() {
return (
<View>
<Text style={styles.heading}>Heading</Text>
</View>
)
}
const styles = EStyleSheet.create({
heading: {
fontSize: '1.5rem',
color: '$colorGreen'
}
});
// src/index.jsx
import EStyleSheet from 'react-native-extended-stylesheet';
EStyleSheet.build({
$rem: 16,
$colorGreen: '#4caf50'
});
The EStyleSheet.build()
is important to to define the variables, as well as “calculate” the stylesheets. However, because of that step, we can’t use EStyleSheet
as a drop-in replacement for StyleSheet
when it comes to style composition. At import time, the styles have not been “calculated” yet.
// This does NOT work
// src/components/Header.style.js
import { StyleSheet } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import BootstrapStyleSheet from 'react-native-bootstrap-styles';
const { bs } = new BootsrtapStyleSheet();
const styles = EStyleSheet.create({
heading: {
fontSize: '1.5rem',
color: '$colorGreen'
}
});
export default {
...styles,
heading: StyleSheet.compose(bs.s1, styles.heading)
}
In order to combine extended stylesheet with bootstrap styles, the styles need to be dynamically generated at component runtime:
// src/components/Header.jsx
import React from 'react'
import { View, Text } from 'react-native';
import getStyles from './Header.style.js';
function Header() {
const styles = getStyles();
return (
<View>
<Text style={styles.heading}>Heading</Text>
</View>
)
}
// src/components/Header.style.js
import { StyleSheet } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import BootstrapStyleSheet from 'react-native-bootstrap-styles';
const { bs } = new BootstrapStyleSheet();
const styles = EStyleSheet.create({
heading: {
fontSize: '1.5rem',
color: '$colorGreen'
}
});
export default function () {
return {
...styles,
heading: StyleSheet.compose(bs.h1, styles.heading)
}
}
There is a bit more wrapping layers in this workaround, but it achieves the goal of keeping the styles consistent with the usage of Bootstrap and CSS features.
comments powered by Disqus