-
Notifications
You must be signed in to change notification settings - Fork 138
Description
Introduction
Current implementation of theming doesn't allow developers to assign theme-dependant changes inside StyleSheet
Details
React Native has a built-in support for theming which is a great addition itself but at the moment it only gives developers information about what theme device has currently and based on this, developer can decide what styles to use in components which can be done different ways, but it always brings to something similar to this:
render() {
const colorScheme = Appearance.getColorScheme();
return (
<View style={colorScheme === "dark" ? darkStyles.container : lightStyles.container}>
{children}
</View>
);
}
const lightStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.white,
},
});
const darkStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.backgroundDark,
},
});
So now in order to have different styles working, a developer needs to manually check current theme and apply the styles, and in case if user has a lot of components it creates a lot of clutter and separates the styles by different constants (dark, light).
Besides, styles could have a lot of properties and in order to avoid copying and pasting them, one need to create one more constant style (i.e. commonStyles) and merge it with dark and light ones.
To “avoid” (mitigate) this comparison and “improve” merging, something like this can be done:
getThemeStyle(lightStyles, darkStyles) {
return Appearance.getColorScheme() == "light" ? lightStyles : darkStyles;
}
render() {
const styles = getThemeStyle(lightStyles, darkStyles);
return (
<View style={styles.container}>
{children}
</View>
);
}
const commonStyles = StyleSheet.create({
container: {
flex: 1,
},
});
const lightStyles = StyleSheet.create({
container: {
...commonStyles.container,
backgroundColor: Colors.white,
},
});
const darkStyles = StyleSheet.create({
container: {
...commonStyles.container,
backgroundColor: Colors.backgroundDark,
},
});
What if instead creating separate styles and merging them, and in most of the cases get rid of Appearance.getColorScheme() == “light"
comparison, developers could define their theme styles inside StyleSheet.create
similar way we have platform dependant code using Platform.select
?
So that it could look something like this:
const styles = StyleSheet.create({
container: {
flex: 1,
...Appearance.select({
dark: {
backgroundColor: Colors.backgroundDark
},
light: {
backgroundColor: Colors.white,
},
}),
},
});
Discussion points
- Implement a similar to
Platform.select
mechanism to have theme-dependant selection insideStyleSheet
style