Created
February 24, 2021 16:34
-
-
Save emeraldsanto/645b44d8ee767aa7ac1f7ea5465f953c to your computer and use it in GitHub Desktop.
A basic implementation of a scaling stylesheet measurements
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Dimensions, StyleSheet } from "react-native"; | |
const SCALABLE_PROPERTIES = [ | |
"padding", | |
"paddingStart", | |
"paddingEnd", | |
"paddingTop", | |
"paddingBottom", | |
"paddingRight", | |
"paddingLeft", | |
"paddingHorizontal", | |
"paddingVertical", | |
"margin", | |
"marginStart", | |
"marginEnd", | |
"marginTop", | |
"marginBottom", | |
"marginRight", | |
"marginLeft", | |
"marginHorizontal", | |
"marginVertical", | |
"fontSize", | |
"lineHeight", | |
"height", | |
"width", | |
"minHeight", | |
"minWidth", | |
"maxHeight", | |
"maxWidth", | |
"borderRadius" | |
]; | |
const BASE_HEIGHT = 812; // iPhone X height (dev device); | |
/** | |
* This class is a wrapper around StylesSheet.create. It is used to make sure | |
* that all values entered into stylesheets are scaled as the screen height | |
* grows and shrinks on different devices. Developers should not use | |
* StyleSheet.create directly but use this class instead | |
*/ | |
export class ScalingStyleSheet { | |
static scaleStyles< | |
T extends StyleSheet.NamedStyles<T> | StyleSheet.NamedStyles<any> | |
>(styles: T): T { | |
const styleKeys = Object.keys(styles) as (keyof typeof styles)[]; | |
// Loop through all scalable properties and scale each property based on the | |
// `scaleProperty` function | |
styleKeys.forEach((styleProp) => { | |
const currentStyle = styles[styleProp]; | |
const stylePropKeys = Object.keys( | |
currentStyle | |
) as (keyof typeof currentStyle)[]; | |
stylePropKeys.forEach((prop) => { | |
if ( | |
SCALABLE_PROPERTIES.includes(prop) && | |
typeof currentStyle[prop] === "number" | |
) { | |
currentStyle[prop] = ScalingStyleSheet.scaleProperty( | |
currentStyle[prop] | |
); | |
} | |
}); | |
}); | |
return styles; | |
} | |
/** | |
* Scales all CSS properties in the app based on the height of the screen | |
* | |
* @param value The raw intended size of a CSS Property | |
*/ | |
static scaleProperty(value: number): number { | |
const currentHeight = Dimensions.get("window").height; | |
if (currentHeight <= BASE_HEIGHT) { | |
return value; | |
} | |
const scaled = (currentHeight / BASE_HEIGHT) * value; | |
return Math.round((scaled + Number.EPSILON) * 100) / 100; | |
} | |
/** | |
* Creates and scales the stylesheet object | |
* | |
* @param styles CSS Style parameters | |
*/ | |
static create< | |
T extends StyleSheet.NamedStyles<T> | StyleSheet.NamedStyles<any> | |
>(styles: T | StyleSheet.NamedStyles<T>): T { | |
return StyleSheet.create(ScalingStyleSheet.scaleStyles(styles)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment