Platform Styles

Coming from a web development background, having to maintain styles for both Android and iOS takes some getting used to. React Native ships with a couple ways to handle this. For complex components with vast disparities, it might be a good idea to separate out iOS and Android components into separate files. 
For our purposes here, I will focus on the approach we are using with the Platform module. As the example below illustrates, importing the Platform module into a stylesheet will tap into React Native’s platform-detection logic and apply the appropriate styles. In this case, we are applying a base font family for each platform.
import { Platform, StyleSheet } from 'react-native';
 
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    ...Platform.select({
      ios: {
        fontFamily: 'Arial',
      },
      android: {
        fontFamily: 'Roboto',
      },
    }),
  },
});
While this pattern is useful, it’s a little verbose. With a bit of configuration, we can fairly easily create our own PlatformStyleSheet that wraps the StyleSheet object and automatically selects and applies platform-specific styles.
/*
* @providesModule PlatformStyleSheet
*/
import { Platform, StyleSheet } from 'react-native';


const PlatformStyleSheet = {
  create(styles) {
    const styleKeys = Object.keys(styles);
    const keptStyles = {};


    styleKeys.forEach((key) => {
      const { ios, android, ...style } = styles[key];


      keptStyles[key] = { ...style, ...Platform.select({ ios, android }) };
    });


    return StyleSheet.create(keptStyles);
  },
};


export default PlatformStyleSheet;
Here we are declaring a PlatformStyleSheet object with a create method that takes in a style’s object as a parameter. It then iterates through the keys of the style object and selects both the generic styles and the styles specific to that platform before returning a StyleSheet created with those keptStyles. The providesModule PlatformStyleSheet is a little bit of syntactic sugar from the folks at Facebook for module loading that allows us to import anywhere from PlatformStyleSheet without having to remember its relative path. So far we’ve chosen to use the providesModule sparingly for ubiquitous modules while defaulting to ES6 module loading via relative path.
Here is an example of a stylesheet created with our new PlatformStyleSheet. All we have to do now is confine our platform-specific styles to the iOS and Android keys for each declared style’s object and our custom create method will take care of the filtering process.
import PlatformStyleSheet from 'PlatformStyleSheet';
  
  
const styles = PlatformStyleSheet.create({
    container: {
        backgroundColor: '#ffffff',
        ios: {
            fontFamily: ‘Arial’,
        },
        android: {
            fontFamily: ‘Roboto’,
        },
    },
});

Comments

Popular posts from this blog