React Native Helpers
Created
September 5, 2020 23:07
-
-
Save GGrassiant/22b727e57d695bf73229237bb5d54682 to your computer and use it in GitHub Desktop.
React Native Helpers
This file contains hidden or 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
| // Libs | |
| import { Dimensions, PixelRatio } from 'react-native'; | |
| const screenWidth = Dimensions.get('window').width; | |
| const screenHeight = Dimensions.get('window').height; | |
| const pixelRatio = PixelRatio.get(); | |
| const fontScale = PixelRatio.getFontScale(); | |
| // utils from https://github.com/marudy/react-native-responsive-screen | |
| // Emulate vw | |
| export const widthPercentageToDP = (widthPercent: number) => { | |
| return PixelRatio.roundToNearestPixel((screenWidth * widthPercent) / 100); | |
| }; | |
| // Emulate vh | |
| export const heightPercentageToDP = (heightPercent: number) => { | |
| return PixelRatio.roundToNearestPixel((screenHeight * heightPercent) / 100); | |
| }; | |
| // Normalize size in pixel to dp based on device pixel ratio | |
| // Tweaked from from react-native-elements | |
| // https://github.com/react-native-elements/react-native-elements/blob/next/src/helpers/normalizeText.js | |
| export const normalizeSize = (size: number) => { | |
| if (pixelRatio >= 2 && pixelRatio < 3) { | |
| // iphone 5s and older Androids | |
| if (screenWidth < 360) { | |
| return PixelRatio.roundToNearestPixel(size * 0.95 * fontScale); | |
| } | |
| // iphone 5 | |
| if (screenHeight < 667) { | |
| return PixelRatio.roundToNearestPixel(size * fontScale); | |
| // iphone 6-6s | |
| } | |
| if (screenHeight >= 667 && screenHeight <= 735) { | |
| return PixelRatio.roundToNearestPixel(size * 1.15 * fontScale); | |
| } | |
| // older phablets | |
| return PixelRatio.roundToNearestPixel(size * 1.25 * fontScale); | |
| } | |
| if (pixelRatio >= 3 && pixelRatio < 3.5) { | |
| // catch Android font scaling on small machines | |
| // where pixel ratio / font scale ratio => 3:3 | |
| if (screenWidth <= 360) { | |
| return PixelRatio.roundToNearestPixel(size * fontScale); | |
| } | |
| // Catch other weird android width sizings | |
| if (screenHeight < 667) { | |
| return PixelRatio.roundToNearestPixel(size * 1.15 * fontScale); | |
| // catch in-between size Androids and scale font up | |
| // a tad but not too much | |
| } | |
| if (screenHeight >= 667 && screenHeight <= 735) { | |
| return PixelRatio.roundToNearestPixel(size * 1.2 * fontScale); | |
| } | |
| // catch larger devices | |
| // ie iphone 6s plus / 7 plus / mi note 等等 | |
| return PixelRatio.roundToNearestPixel(size * 1.27 * fontScale); | |
| } | |
| if (pixelRatio >= 3.5) { | |
| // catch Android font scaling on small machines | |
| // where pixel ratio / font scale ratio => 3:3 | |
| if (screenWidth <= 360) { | |
| return PixelRatio.roundToNearestPixel(size * fontScale); | |
| // Catch other smaller android height sizings | |
| } | |
| if (screenHeight < 667) { | |
| return PixelRatio.roundToNearestPixel(size * 1.2 * fontScale); | |
| // catch in-between size Androids and scale font up | |
| // a tad but not too much | |
| } | |
| if (screenHeight >= 667 && screenHeight <= 735) { | |
| return PixelRatio.roundToNearestPixel(size * 1.25 * fontScale); | |
| } | |
| // catch larger phablet devices | |
| return PixelRatio.roundToNearestPixel(size * 1.4 * fontScale); | |
| } | |
| return size * fontScale; | |
| }; |
This file contains hidden or 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
| export const defaultTimeOut: number = 3000; | |
| export const layoutGridPadding: number = widthPercentageToDP(10); | |
| export const defaultAvatarUri: string = 'https://placedog.net/180/180?random'; | |
| export const defaultViewWrapper: { [key: string]: number } = { | |
| flexGrow: 1, | |
| // react-navigation SafeAreaView padding top for portrait is 44 | |
| // and padding bottom is 34 | |
| flexBasis: heightPercentageToDP(100) - normalizeSize(44) - normalizeSize(34), | |
| }; | |
| export const defaultContainer: { [key: string]: number } = { | |
| ...defaultViewWrapper, | |
| width: Dimensions.get('window').width, | |
| paddingHorizontal: layoutGridPadding, | |
| }; | |
| export const defaultButton: { | |
| [key: string]: number | string | { [key: string]: number }; | |
| } = { | |
| alignSelf: 'stretch', | |
| justifyContent: 'center', | |
| alignItems: 'center', | |
| height: normalizeSize(48), | |
| borderRadius: normalizeSize(16), | |
| }; | |
| export const defaultBoxShadow: { | |
| [key: string]: number | string | { [key: string]: number }; | |
| } = { | |
| shadowColor: colors.shadow, | |
| shadowOffset: { width: 0, height: normalizeSize(2) }, | |
| shadowRadius: normalizeSize(4), | |
| shadowOpacity: 0.9, | |
| elevation: 3, | |
| }; | |
| export const defaultInstructions: { | |
| [key: string]: { [key: string]: number | string | { [key: string]: number } }; | |
| } = { | |
| instructionsWrapper: { | |
| flex: 1, | |
| justifyContent: 'center', | |
| }, | |
| instructionItemTitle: { | |
| fontFamily: defaultFontFamily, | |
| fontSize: caption3, | |
| lineHeight: normalizeSize(14), | |
| color: colors.grey4, | |
| marginBottom: normalizeSize(2), | |
| }, | |
| instructionItemWrapper: { | |
| flexDirection: 'row', | |
| }, | |
| instructionItem: { | |
| flex: 1, | |
| paddingLeft: normalizeSize(5), | |
| fontFamily: defaultFontFamily, | |
| fontSize: caption3, | |
| lineHeight: normalizeSize(14), | |
| color: colors.grey3, | |
| }, | |
| }; | |
| export const renderNode = ( | |
| ComponentElement: typeof Text | typeof IconButton, | |
| content: any, | |
| defaultProps?: any, | |
| ): React.ReactNode | null => { | |
| if (content == null || content === false) { | |
| return null; | |
| } | |
| if (React.isValidElement(content)) { | |
| return content; | |
| } | |
| if (typeof content === 'function') { | |
| return content(); | |
| } | |
| // Just in case | |
| if (content === true) { | |
| return <ComponentElement {...defaultProps} />; | |
| } | |
| if (typeof content === 'string' || typeof content === 'number') { | |
| return <ComponentElement {...defaultProps}>{content}</ComponentElement>; | |
| } | |
| return <ComponentElement {...defaultProps} {...content} />; | |
| }; | |
| export const renderText = ( | |
| content: string, | |
| style: ViewStyle | TextStyle | ImageStyle, | |
| ): React.ReactNode | null => | |
| renderNode(Text, content, { | |
| style: StyleSheet.flatten(style), | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment