Giter VIP home page Giter VIP logo

react-native-auto-stylesheet's Introduction

react-native-auto-stylesheet

Drop-in replacement for React Native's StyleSheet that performs automatic scaling of sizes, including margins, paddings, borders and font sizes.

The library's main features are:

  • Scale dimensions based on height ratio, width ratio or their average dependending on the style property.
  • No need to manually call functions or use new units of measurement (though you can if you want to).
  • Use absolute values when creating layouts. No more need to calculate percentages or flex ratios from the design.
  • TypeScript support.

Installation instructions

$ yarn add react-native-auto-stylesheet

Example usage

import { StyleSheet } from 'react-native-auto-stylesheet';

export const styles = StyleSheet.create({
  scaledView: {
    height: 50, // scaled automatically to the device height
    width: 100 // scaled automatically to the device width
  },
  scaledText: {
    fontSize: 18 // scaled automatically to the average of height and width ratios
  }
);

The library assumes that the dimensions are relative to a 375 x 667 design (the logical resolution of an iPhone 6-8). That means that scaledView.width will be 100 on an iPhone 8 and 85.5 on an iPhone SE (PixelRatio.roundToNearestPixel(100 * 320 / 375)).

In practice

Replacing React Native's StyleSheet with react-native-auto-stylesheet in one of our screens (without any other changes) yields immediate results.

Before:

After:

With almost no effort the results are much better. There are still problems with the navigation header and some icons, but they are easy to fix.

Overall this feels like a big win.

Advanced usage

React Native's StyleSheet pass-through

All the calls to existing StyleSheet functionality are passed as they are to the React Native implementation:

import { StyleSheet } from 'react-native-auto-stylesheet';

// these all work as expected
StyleSheet.flatten;
StyleSheet.hairlineWidth;
StyleSheet.absoluteFill;
StyleSheet.absoluteFillObject;

What if I have different design dimensions?

If needed, different values can be set for the relative design dimensions:

// the designs are based on iPad Air dimensions
// make sure to call this as soon as possible, before any styles are calculated
StyleSheet.setGuidelineBaseDimensions(768, 1024);

What if I need to scale using a different factor?

The following example shows how setting a different factor can be achieved for devices with a wide screen.

import { Dimensions } from 'react-native';
const { width } = Dimensions.get('window');

if (width >= 1024) {
  StyleSheet.setFactor(0.5);
  // technically equivalent to:
  // StyleSheet.setGuidelineBaseDimensions(750, 1334);
  // 375 / 0.5 = 750, 667 / 0.5 = 1334
}

What if I need to keep the aspect ratio?

Use the aspectRatio layout property:

export const styles = StyleSheet.create({
  fixedAspectRatio: {
    width: 100, // will get scaled
    aspectRatio: 1 // will set height to the same value as width
  }
);

What if I need to disable scaling for a specific value?

const scaledStyles = StyleSheet.create({
  scaledStyle: {
    width: 100 // will get scaled
  }
});

// equivalent to using `StyleSheet.create` from the RN object
const unscaledStyles = StyleSheet.createUnscaled({
  unscaledStyle: {
    width: 100 // will be fixed to 100
  }
});

export const styles = { ...scaledStyles, ...unscaledStyles };

What if I want to scale manually?

The scaling functions are exposed on the StyleSheet object:

StyleSheet.scaleHorizontally(size: number): number;
StyleSheet.scaleVertically(size: number): number;
StyleSheet.scaleWithAverageRatio(size: number): number;

Limitations

  1. Not all properties are scaled. For now, only these properties are scaled, though the list can easily be extended:

    • Based on height: height, marginTop, marginBottom, marginVertical, paddingTop, paddingBottom, paddingVertical, borderLeftWidth, borderRightWidth, top, bottom.
    • Based on width: width, marginLeft, marginRight, marginHorizontal, paddingLeft, paddingRight, paddingHorizontal, borderTopWidth, borderBottomWidth, left, right.
    • Based on average of height and width ratios: fontSize, margin, padding, borderWidth.
  2. Object or array properties are not scaled recursively. One property that could be useful to be scaled is transform.translateX/Y.

  3. The library does not listen to dimensions change (orientation change or split screen). While it is relatively easy to implement, we did not have the need for this functionality yet.

TSLint rule and automatic code refactoring

You can ignore this section if you are not using TypeScript.

If you decide to use react-native-auto-stylesheet in your app, it is probably a good idea to use it everywhere so inconsistencies are eliminated (the situation when some screens or components are scaled, some are not).

In order to help with establishing this as a best practice, we include a TSLint rule that will signal any use of React Native's StyleSheet. It can be activated by making the following changes in tslint.json:

{
  ...
  "rulesDirectory": ["node_modules/react-native-auto-stylesheet/tslint"],
  "rules": {
    ...
    "no-rn-stylesheet-import": true
  }
}

After this, TSLint should emit a warning any time it encounters import { StyleSheet } from 'react-native';.

Also, importing our library in favor of React Native's implementation can be refactored automatically by simply running ./node_modules/.bin/tslint --fix './src/**/*.ts*'.

react-native-auto-stylesheet's People

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.