Dynamic Styles for React Native and Expo Web
- Dynamic. Based on React Hook. It automatically re-renders when necessary.
- Unopinionated. Use whatever component or theme library you want.
- Simple to use. No HOC, no special syntax. Easily migrate from plain StyleSheet.
- Strictly typed. Take full advantage of TypeScript. Get auto-completions in VSCode.
yarn add react-native-swag-styles
Replace StyleSheet.create
with makeStyles
with callback:
- import { StyleSheet } from 'react-native';
+ import { makeStyles } from 'react-native-swag-styles';
- const styles = StyleSheet.create({
+ const useStyles = makeStyles(() => ({
underlayColor: '#333',
container: {
paddingTop: 24,
paddingBottom: 32,
},
-});
+}));
Use created style hook in component:
const Foo = () => {
const styles = useStyles();
return (
<View style={styles.container}>
<TouchableHighlight underlayColor={styles.underlayColor} />
</View>
);
};
To make the style dynamic, pass props to the style creator:
const useStyles = makeStyles((small: boolean) => {
const iconSize = small ? 16 : 24;
return {
icon: {
width: iconSize,
height: iconSize,
},
// ...
};
});
const Foo = () => {
const styles = useStyles(true);
// ...
};
If you use a theming library, you can attach the theme hook when creating styles:
const useStyles = makeStyles(
useAppTheme,
// first argument is the return value of your theme hook
({ colors, insets }) => ({
underlayColor: colors.grey,
container: {
paddingTop: insets.top,
paddingBottom: insets.bottom,
},
})
);
You can also create styles using multiple hooks, as long as the hooks don’t take any argument:
const useStyles = makeStyles(
useAppTheme,
useWideScreen,
useWindowDimensions,
// The order of arguments matches the order of hooks above
({ colors, fonts }, isWideScreen, { width }) => {
// ...
}
);
Pass hooks and extra props together to the style creator:
const useStyles = makeStyles(
useAppTheme,
useWideScreen,
({ brandColor, colors, fonts }, isWideScreen, small: boolean) => {
// ...
}
);
Important Note: Hook returns and props must be plain (serializable) object/values for memoization to work properly. See fast-memoize.js.
createStyleSheet
extends StyleSheet.create
to support constant values:
import { createStyleSheet } from 'react-native-swag-styles';
const styles = createStyleSheet({
text: 'some kind of string',
regularStyle: {
paddingTop: 24,
paddingBottom: 32,
},
});
To see a full working example, with a custom theme, check out the example
folder.
See the contributing guide to learn how to contribute to the repository and the development workflow.
Thanks to the authors of these libraries for inspiration:
MIT