├── .gitignore ├── LICENSE ├── MaM.jpg ├── __tests__ └── index.js ├── components ├── index.js └── react-native-cross-platform-responsive-dimensions.d.ts ├── jsconfig.json ├── package-lock.json ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,macos,reactnative 3 | 4 | ### macOS ### 5 | *.DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | .com.apple.timemachine.donotpresent 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | ### Node ### 32 | # Logs 33 | logs 34 | *.log 35 | npm-debug.log* 36 | yarn-debug.log* 37 | yarn-error.log* 38 | 39 | # Runtime data 40 | pids 41 | *.pid 42 | *.seed 43 | *.pid.lock 44 | 45 | # Directory for instrumented libs generated by jscoverage/JSCover 46 | lib-cov 47 | 48 | # Coverage directory used by tools like istanbul 49 | coverage 50 | 51 | # nyc test coverage 52 | .nyc_output 53 | 54 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 55 | .grunt 56 | 57 | # Bower dependency directory (https://bower.io/) 58 | bower_components 59 | 60 | # node-waf configuration 61 | .lock-wscript 62 | 63 | # Compiled binary addons (http://nodejs.org/api/addons.html) 64 | build/Release 65 | 66 | # Dependency directories 67 | node_modules/ 68 | jspm_packages/ 69 | 70 | # Typescript v1 declaration files 71 | typings/ 72 | 73 | # Optional npm cache directory 74 | .npm 75 | 76 | # Optional eslint cache 77 | .eslintcache 78 | 79 | # Optional REPL history 80 | .node_repl_history 81 | 82 | # Output of 'npm pack' 83 | *.tgz 84 | 85 | # Yarn Integrity file 86 | .yarn-integrity 87 | 88 | # dotenv environment variables file 89 | .env 90 | 91 | 92 | ### ReactNative ### 93 | # React Native Stack Base 94 | ### ReactNative.Gradle Stack ### 95 | .gradle 96 | **/build/ 97 | 98 | # Ignore Gradle GUI config 99 | gradle-app.setting 100 | 101 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 102 | !gradle-wrapper.jar 103 | 104 | # Cache of project 105 | .gradletasknamecache 106 | 107 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 108 | # gradle/wrapper/gradle-wrapper.properties 109 | 110 | ### ReactNative.Node Stack ### 111 | # Logs 112 | 113 | # Runtime data 114 | 115 | # Directory for instrumented libs generated by jscoverage/JSCover 116 | 117 | # Coverage directory used by tools like istanbul 118 | 119 | # nyc test coverage 120 | 121 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 122 | 123 | # Bower dependency directory (https://bower.io/) 124 | 125 | # node-waf configuration 126 | 127 | # Compiled binary addons (http://nodejs.org/api/addons.html) 128 | 129 | # Dependency directories 130 | 131 | # Typescript v1 declaration files 132 | 133 | # Optional npm cache directory 134 | 135 | # Optional eslint cache 136 | 137 | # Optional REPL history 138 | 139 | # Output of 'npm pack' 140 | 141 | # Yarn Integrity file 142 | 143 | # dotenv environment variables file 144 | 145 | 146 | ### ReactNative.Android Stack ### 147 | # Built application files 148 | *.apk 149 | *.ap_ 150 | 151 | # Files for the ART/Dalvik VM 152 | *.dex 153 | 154 | # Java class files 155 | *.class 156 | 157 | # Generated files 158 | bin/ 159 | gen/ 160 | out/ 161 | 162 | # Gradle files 163 | .gradle/ 164 | build/ 165 | 166 | # Local configuration file (sdk path, etc) 167 | local.properties 168 | 169 | # Proguard folder generated by Eclipse 170 | proguard/ 171 | 172 | # Log Files 173 | 174 | # Android Studio Navigation editor temp files 175 | .navigation/ 176 | 177 | # Android Studio captures folder 178 | captures/ 179 | 180 | # Intellij 181 | *.iml 182 | .idea/workspace.xml 183 | .idea/tasks.xml 184 | .idea/gradle.xml 185 | .idea/dictionaries 186 | .idea/libraries 187 | 188 | # External native build folder generated in Android Studio 2.2 and later 189 | .externalNativeBuild 190 | 191 | # Freeline 192 | freeline.py 193 | freeline/ 194 | freeline_project_description.json 195 | 196 | ### ReactNative.Xcode Stack ### 197 | # Xcode 198 | # 199 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 200 | 201 | ## Build generated 202 | DerivedData/ 203 | 204 | ## Various settings 205 | *.pbxuser 206 | !default.pbxuser 207 | *.mode1v3 208 | !default.mode1v3 209 | *.mode2v3 210 | !default.mode2v3 211 | *.perspectivev3 212 | !default.perspectivev3 213 | xcuserdata/ 214 | 215 | ## Other 216 | *.moved-aside 217 | *.xccheckout 218 | *.xcscmblueprint 219 | 220 | ### ReactNative.Linux Stack ### 221 | *~ 222 | 223 | # temporary files which can be created if a process still has a handle open of a deleted file 224 | .fuse_hidden* 225 | 226 | # KDE directory preferences 227 | .directory 228 | 229 | # Linux trash folder which might appear on any partition or disk 230 | .Trash-* 231 | 232 | # .nfs files are created when an open file is removed but is still being accessed 233 | .nfs* 234 | 235 | ### ReactNative.Buck Stack ### 236 | buck-out/ 237 | .buckconfig.local 238 | .buckd/ 239 | .buckversion 240 | .fakebuckversion 241 | 242 | ### ReactNative.macOS Stack ### 243 | 244 | # Icon must end with two \r 245 | Icon 246 | 247 | 248 | # Thumbnails 249 | 250 | # Files that might appear in the root of a volume 251 | 252 | # Directories potentially created on remote AFP share 253 | 254 | # End of https://www.gitignore.io/api/node,macos,reactnative -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 drumnation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /MaM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drumnation/react-native-cross-platform-responsive-dimensions/ae54d3287f5f86d0fa80f86d90caa2f2bd27cebc/MaM.jpg -------------------------------------------------------------------------------- /__tests__/index.js: -------------------------------------------------------------------------------- 1 | import { Text, View } from 'react-native'; 2 | import React from 'react'; 3 | import { isPortrait, isLandscape } from '../components/index.js'; 4 | // Note: test renderer must be required after react-native. 5 | import renderer from 'react-test-renderer'; 6 | -------------------------------------------------------------------------------- /components/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017-present David Mieloch 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | import { NativeModules, Platform, Dimensions } from "react-native"; 26 | import DeviceInfo from "react-native-device-info"; 27 | 28 | const { height, width } = Dimensions.get("window"); 29 | export const isPortrait = () => { 30 | if (height > width) return true; 31 | return false; 32 | }; 33 | 34 | export const isLandscape = () => { 35 | if (height < width) return true; 36 | return false; 37 | }; 38 | 39 | export const responsiveHeight = h => height * (h / 100); 40 | 41 | export const responsiveWidth = w => width * (w / 100); 42 | 43 | export const responsiveFontSize = f => 44 | Math.sqrt(height * height + width * width) * (f / 100); 45 | 46 | 47 | export const crossResponsiveHeight = ( 48 | iosPhone, 49 | iosTablet, 50 | androidPhone, 51 | androidTablet 52 | ) => { 53 | const dimension = 54 | Platform.OS === "ios" 55 | ? !NativeModules.RNDeviceInfo.isTablet 56 | ? responsiveHeight(iosPhone) 57 | : responsiveHeight(iosTablet) 58 | : !NativeModules.RNDeviceInfo.isTablet 59 | ? responsiveHeight(androidPhone) 60 | : responsiveHeight(androidTablet); 61 | return dimension; 62 | }; 63 | 64 | export const crossResponsiveWidth = ( 65 | iosPhone, 66 | iosTablet, 67 | androidPhone, 68 | androidTablet 69 | ) => { 70 | const dimension = 71 | Platform.OS === "ios" 72 | ? !NativeModules.RNDeviceInfo.isTablet 73 | ? responsiveWidth(iosPhone) 74 | : responsiveWidth(iosTablet) 75 | : !NativeModules.RNDeviceInfo.isTablet 76 | ? responsiveWidth(androidPhone) 77 | : responsiveWidth(androidTablet); 78 | return dimension; 79 | }; 80 | 81 | export const crossResponsiveFontSize = ( 82 | iosPhone, 83 | iosTablet, 84 | androidPhone, 85 | androidTablet 86 | ) => { 87 | const fontSize = 88 | Platform.OS === "ios" 89 | ? !NativeModules.RNDeviceInfo.isTablet 90 | ? responsiveFontSize(iosPhone) 91 | : responsiveFontSize(iosTablet) 92 | : !NativeModules.RNDeviceInfo.isTablet 93 | ? responsiveFontSize(androidPhone) 94 | : responsiveFontSize(androidTablet); 95 | return fontSize; 96 | }; 97 | 98 | export const crossPlatformOS = (ios, android) => 99 | Platform.OS === "ios" ? ios : android; 100 | 101 | export const crossPlatformImg = image => 102 | Platform.OS === "ios" ? image : image.slice(0, -4); 103 | 104 | export const crossPlatformDevice = ( 105 | iosPhone, 106 | iosTablet, 107 | androidPhone, 108 | androidTablet 109 | ) => { 110 | const deviceProperty = 111 | Platform.OS === "ios" 112 | ? !NativeModules.RNDeviceInfo.isTablet ? iosPhone : iosTablet 113 | : !NativeModules.RNDeviceInfo.isTablet ? androidPhone : androidTablet; 114 | return deviceProperty; 115 | }; 116 | 117 | // iPhoneX 118 | 119 | export const crossHeightX = ( 120 | iosPhone, 121 | iosTablet, 122 | androidPhone, 123 | androidTablet, 124 | iPhoneX 125 | ) => { 126 | if ( 127 | Platform.OS === "ios" && 128 | !NativeModules.RNDeviceInfo.isTablet && 129 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 130 | ) { 131 | dimension = responsiveHeight(iosPhone); 132 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 133 | dimension = responsiveHeight(iosTablet); 134 | } else if ( 135 | Platform.OS === "android" && 136 | !NativeModules.RNDeviceInfo.isTablet 137 | ) { 138 | dimension = responsiveHeight(androidPhone); 139 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 140 | dimension = responsiveHeight(androidTablet); 141 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 142 | dimension = responsiveHeight(iPhoneX); 143 | } 144 | return dimension; 145 | }; 146 | 147 | export const heightX = (height, iPhoneX) => { 148 | if ( 149 | Platform.OS === "ios" && 150 | !NativeModules.RNDeviceInfo.isTablet && 151 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 152 | ) { 153 | dimension = responsiveHeight(height); 154 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 155 | dimension = responsiveHeight(height); 156 | } else if ( 157 | Platform.OS === "android" && 158 | !NativeModules.RNDeviceInfo.isTablet 159 | ) { 160 | dimension = responsiveHeight(height); 161 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 162 | dimension = responsiveHeight(height); 163 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 164 | dimension = responsiveHeight(iPhoneX); 165 | } 166 | return dimension; 167 | }; 168 | 169 | export const crossWidthX = ( 170 | iosPhone, 171 | iosTablet, 172 | androidPhone, 173 | androidTablet, 174 | iPhoneX 175 | ) => { 176 | if ( 177 | Platform.OS === "ios" && 178 | !NativeModules.RNDeviceInfo.isTablet && 179 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 180 | ) { 181 | dimension = responsiveWidth(iosPhone); 182 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 183 | dimension = responsiveWidth(iosTablet); 184 | } else if ( 185 | Platform.OS === "android" && 186 | !NativeModules.RNDeviceInfo.isTablet 187 | ) { 188 | dimension = responsiveWidth(androidPhone); 189 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 190 | dimension = responsiveWidth(androidTablet); 191 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 192 | dimension = responsiveWidth(iPhoneX); 193 | } 194 | return dimension; 195 | }; 196 | 197 | export const widthX = (width, iPhoneX) => { 198 | if ( 199 | Platform.OS === "ios" && 200 | !NativeModules.RNDeviceInfo.isTablet && 201 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 202 | ) { 203 | dimension = responsiveWidth(width); 204 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 205 | dimension = responsiveWidth(width); 206 | } else if ( 207 | Platform.OS === "android" && 208 | !NativeModules.RNDeviceInfo.isTablet 209 | ) { 210 | dimension = responsiveWidth(width); 211 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 212 | dimension = responsiveWidth(width); 213 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 214 | dimension = responsiveWidth(iPhoneX); 215 | } 216 | return dimension; 217 | }; 218 | 219 | export const crossFontSizeX = ( 220 | iosPhone, 221 | iosTablet, 222 | androidPhone, 223 | androidTablet, 224 | iPhoneX 225 | ) => { 226 | if ( 227 | Platform.OS === "ios" && 228 | !NativeModules.RNDeviceInfo.isTablet && 229 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 230 | ) { 231 | dimension = responsiveFontSize(iosPhone); 232 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 233 | dimension = responsiveFontSize(iosTablet); 234 | } else if ( 235 | Platform.OS === "android" && 236 | !NativeModules.RNDeviceInfo.isTablet 237 | ) { 238 | dimension = responsiveFontSize(androidPhone); 239 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 240 | dimension = responsiveFontSize(androidTablet); 241 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 242 | dimension = responsiveFontSize(iPhoneX); 243 | } 244 | return dimension; 245 | }; 246 | 247 | export const fontSizeX = (size, iPhoneX) => { 248 | if ( 249 | Platform.OS === "ios" && 250 | !NativeModules.RNDeviceInfo.isTablet && 251 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 252 | ) { 253 | dimension = responsiveFontSize(size); 254 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 255 | dimension = responsiveFontSize(size); 256 | } else if ( 257 | Platform.OS === "android" && 258 | !NativeModules.RNDeviceInfo.isTablet 259 | ) { 260 | dimension = responsiveFontSize(size); 261 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 262 | dimension = responsiveFontSize(size); 263 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 264 | dimension = responsiveFontSize(iPhoneX); 265 | } 266 | return dimension; 267 | }; 268 | 269 | // Note 8 - specific styling 270 | 271 | export const fontSizeN8 = (size, note8) => { 272 | if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 273 | return responsiveFontSize(note8); 274 | } else { 275 | return responsiveFontSize(size); 276 | } 277 | }; 278 | 279 | export const widthN8 = (size, note8) => { 280 | if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 281 | return responsiveWidth(note8); 282 | } else { 283 | return responsiveWidth(size); 284 | } 285 | }; 286 | 287 | export const heightN8 = (size, note8) => { 288 | if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 289 | return responsiveHeight(note8); 290 | } else { 291 | return responsiveHeight(size); 292 | } 293 | }; 294 | 295 | // cross platform 296 | 297 | export const crossHeightN8 = ( 298 | iosPhone, 299 | iosTablet, 300 | androidPhone, 301 | androidTablet, 302 | note8 303 | ) => { 304 | if (Platform.OS === "ios" && !NativeModules.RNDeviceInfo.isTablet) { 305 | dimension = responsiveHeight(iosPhone); 306 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 307 | dimension = responsiveHeight(iosTablet); 308 | } else if ( 309 | Platform.OS === "android" && 310 | !NativeModules.RNDeviceInfo.isTablet && 311 | NativeModules.RNDeviceInfo.deviceName !== "SM-N950U" 312 | ) { 313 | dimension = responsiveHeight(androidPhone); 314 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 315 | dimension = responsiveHeight(androidTablet); 316 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 317 | dimension = responsiveHeight(note8); 318 | } 319 | return dimension; 320 | }; 321 | 322 | export const crossWidthN8 = ( 323 | iosPhone, 324 | iosTablet, 325 | androidPhone, 326 | androidTablet, 327 | note8 328 | ) => { 329 | if (Platform.OS === "ios" && !NativeModules.RNDeviceInfo.isTablet) { 330 | dimension = responsiveWidth(iosPhone); 331 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 332 | dimension = responsiveWidth(iosTablet); 333 | } else if ( 334 | Platform.OS === "android" && 335 | !NativeModules.RNDeviceInfo.isTablet && 336 | NativeModules.RNDeviceInfo.deviceName !== "SM-N950U" 337 | ) { 338 | dimension = responsiveWidth(androidPhone); 339 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 340 | dimension = responsiveWidth(androidTablet); 341 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 342 | dimension = responsiveWidth(note8); 343 | } 344 | return dimension; 345 | }; 346 | 347 | export const crossFontSizeN8 = ( 348 | iosPhone, 349 | iosTablet, 350 | androidPhone, 351 | androidTablet, 352 | note8 353 | ) => { 354 | if (Platform.OS === "ios" && !NativeModules.RNDeviceInfo.isTablet) { 355 | dimension = responsiveFontSize(iosPhone); 356 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 357 | dimension = responsiveFontSize(iosTablet); 358 | } else if ( 359 | Platform.OS === "android" && 360 | !NativeModules.RNDeviceInfo.isTablet && 361 | NativeModules.RNDeviceInfo.deviceName !== "SM-N950U" 362 | ) { 363 | dimension = responsiveFontSize(androidPhone); 364 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 365 | dimension = responsiveFontSize(androidTablet); 366 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 367 | dimension = responsiveFontSize(note8); 368 | } 369 | return dimension; 370 | }; 371 | 372 | export const crossFontSizeXN8 = ( 373 | iosPhone, 374 | iosTablet, 375 | androidPhone, 376 | androidTablet, 377 | iPhoneX, 378 | note8 379 | ) => { 380 | if ( 381 | Platform.OS === "ios" && 382 | !NativeModules.RNDeviceInfo.isTablet && 383 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 384 | ) { 385 | dimension = responsiveFontSize(iosPhone); 386 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 387 | dimension = responsiveFontSize(iosTablet); 388 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 389 | dimension = responsiveFontSize(iPhoneX); 390 | } else if ( 391 | Platform.OS === "android" && 392 | !NativeModules.RNDeviceInfo.isTablet && 393 | NativeModules.RNDeviceInfo.deviceName !== "SM-N950U" 394 | ) { 395 | dimension = responsiveFontSize(androidPhone); 396 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 397 | dimension = responsiveFontSize(androidTablet); 398 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 399 | dimension = responsiveFontSize(note8); 400 | } 401 | return dimension; 402 | }; 403 | 404 | export const crossHeightXN8 = ( 405 | iosPhone, 406 | iosTablet, 407 | androidPhone, 408 | androidTablet, 409 | iPhoneX, 410 | note8 411 | ) => { 412 | if ( 413 | Platform.OS === "ios" && 414 | !NativeModules.RNDeviceInfo.isTablet && 415 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 416 | ) { 417 | dimension = responsiveHeight(iosPhone); 418 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 419 | dimension = responsiveHeight(iosTablet); 420 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 421 | dimension = responsiveHeight(iPhoneX); 422 | } else if ( 423 | Platform.OS === "android" && 424 | !NativeModules.RNDeviceInfo.isTablet && 425 | NativeModules.RNDeviceInfo.deviceName !== "SM-N950U" 426 | ) { 427 | dimension = responsiveHeight(androidPhone); 428 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 429 | dimension = responsiveHeight(androidTablet); 430 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 431 | dimension = responsiveHeight(note8); 432 | } 433 | return dimension; 434 | }; 435 | 436 | export const crossWidthXN8 = ( 437 | iosPhone, 438 | iosTablet, 439 | androidPhone, 440 | androidTablet, 441 | iPhoneX, 442 | note8 443 | ) => { 444 | if ( 445 | Platform.OS === "ios" && 446 | !NativeModules.RNDeviceInfo.isTablet && 447 | !NativeModules.RNDeviceInfo.deviceName.includes("iPhone X") 448 | ) { 449 | dimension = responsiveWidth(iosPhone); 450 | } else if (Platform.OS === "ios" && NativeModules.RNDeviceInfo.isTablet) { 451 | dimension = responsiveWidth(iosTablet); 452 | } else if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 453 | dimension = responsiveWidth(iPhoneX); 454 | } else if ( 455 | Platform.OS === "android" && 456 | !NativeModules.RNDeviceInfo.isTablet && 457 | NativeModules.RNDeviceInfo.deviceName !== "SM-N950U" 458 | ) { 459 | dimension = responsiveWidth(androidPhone); 460 | } else if (Platform.OS === "android" && NativeModules.RNDeviceInfo.isTablet) { 461 | dimension = responsiveWidth(androidTablet); 462 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 463 | dimension = responsiveWidth(note8); 464 | } 465 | return dimension; 466 | }; 467 | 468 | export const fontSizeXN8 = (size, iPhoneX, note8) => { 469 | if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 470 | dimension = responsiveFontSize(iPhoneX); 471 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 472 | dimension = responsiveFontSize(note8); 473 | } else { 474 | dimension = responsiveFontSize(size); 475 | } 476 | return dimension; 477 | }; 478 | 479 | export const widthXN8 = (size, iPhoneX, note8) => { 480 | if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 481 | dimension = responsiveWidth(iPhoneX); 482 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 483 | dimension = responsiveWidth(note8); 484 | } else { 485 | dimension = responsiveWidth(size); 486 | } 487 | return dimension; 488 | }; 489 | export const heightXN8 = (size, iPhoneX, note8) => { 490 | if (NativeModules.RNDeviceInfo.deviceName.includes("iPhone X")) { 491 | dimension = responsiveHeight(iPhoneX); 492 | } else if (NativeModules.RNDeviceInfo.deviceName === "SM-N950U") { 493 | dimension = responsiveHeight(note8); 494 | } else { 495 | dimension = responsiveHeight(size); 496 | } 497 | return dimension; 498 | }; 499 | 500 | export const deviceHeight = (phone, tablet) => { 501 | if (!NativeModules.RNDeviceInfo.isTablet) { 502 | dimension = responsiveHeight(phone); 503 | } else { 504 | dimension = responsiveHeight(tablet); 505 | } 506 | return dimension; 507 | }; 508 | export const deviceWidth = (phone, tablet) => { 509 | if (!NativeModules.RNDeviceInfo.isTablet) { 510 | dimension = responsiveWidth(phone); 511 | } else { 512 | dimension = responsiveWidth(tablet); 513 | } 514 | return dimension; 515 | }; 516 | export const deviceFontSize = (phone, tablet) => { 517 | if (!NativeModules.RNDeviceInfo.isTablet) { 518 | dimension = responsiveFontSize(phone); 519 | } else { 520 | dimension = responsiveFontSize(tablet); 521 | } 522 | return dimension; 523 | }; 524 | -------------------------------------------------------------------------------- /components/react-native-cross-platform-responsive-dimensions.d.ts: -------------------------------------------------------------------------------- 1 | declare module "react-native-cross-platform-responsive-dimensions" 2 | // to avoid typescript warnings 3 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true 5 | }, 6 | "exclude": [ 7 | "node_modules" 8 | ] 9 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-cross-platform-responsive-dimensions", 3 | "version": "0.9.1", 4 | "description": "Cross Platform resposive fontSize, height and width for your react-native components. Specify different values for iPhone, IOS Tablet, Android Phone, or Android Tablet. Based on responsive dimensions by DaniAkash: https://github.com/DaniAkash/react-native-responsive-dimensions/", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/drumnation/react-native-cross-platform-responsive-dimensions.git" 8 | }, 9 | "homepage": "https://github.com/drumnation/react-native-cross-platform-responsive-dimensions#readme", 10 | "license": "MIT", 11 | "author": "drumnation (davidmieloch.com)", 12 | "main": "components/index.js", 13 | "directories": { 14 | "example": "example" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/drumnation/react-native-cross-platform-responsive-dimensions/issues" 18 | }, 19 | "scripts": { 20 | "test": "jest", 21 | "renew-snap": "jest --updateSnapshot", 22 | "clean-test": "jest --no-cache" 23 | }, 24 | "files": [ 25 | "components/" 26 | ], 27 | "keywords": [ 28 | "react-native", 29 | "responsive", 30 | "responsive-height", 31 | "responsive-width", 32 | "responsive-font-size", 33 | "fontSize", 34 | "responsive-dimensions", 35 | "cross-platform", 36 | "android", 37 | "ios", 38 | "tablet" 39 | ], 40 | "peerDependencies": { 41 | "react": "*", 42 | "react-native": "*", 43 | "prop-types": "*" 44 | }, 45 | "devDependencies": { 46 | "babel-jest": "^20.0.3", 47 | "babel-preset-react-native": "^2.1.0", 48 | "jest": "^20.0.4", 49 | "jest-react-native": "^18.0.0", 50 | "react": "16.0.0-alpha.12", 51 | "react-native": "^0.46.4", 52 | "react-test-renderer": "^16.0.0-alpha.12" 53 | }, 54 | "jest": { 55 | "preset": "react-native", 56 | "modulePathIgnorePatterns": [ 57 | "/example/", 58 | "/__tests__/mocks/" 59 | ] 60 | }, 61 | "dependencies": {} 62 | } 63 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # react-native-cross-platform-responsive-dimensions 2 | 3 | [![npm](https://img.shields.io/npm/dt/react-native-cross-platform-responsive-dimensions.svg?style=flat-square)](https://www.npmjs.com/package/react-native-cross-platform-responsive-dimensions) 4 | 5 | ## UPDATE: 6 | 7 | Added ```crossPlatformImg(image)``` for trimming the extension off of native image file names on Android devices, and keeping them on IOS. 8 | 9 | ## Here's a little magic to make your cross-platform JSS pop... 10 | 11 | This package started as a fork of [react-native-responsive-dimensions](https://github.com/DaniAkash/react-native-responsive-dimensions) which allows developers to use percentages in their JSS to scale integer values based on the user's device dimensions. This worked great for me and was using it all the time, but when I started working on the tablet version of my app I quickly realized that tablets have a different [aspect ratio](https://material.io/devices/) than phones. And this meant I needed to set a different value for tablets that when scaled would look correctly on all other tablets. 12 | 13 | When I finished with my phone and tablet build for IOS, I shifted to Android and was disappointed to see that my app looked like it had been in a terrible car accident. 14 | 15 | ## Android and IOS won't interpret your codebase the same. 16 | 17 | Android and IOS will not always process the same style property in the same way, a perfect example is how [custom React-Native fonts work](https://medium.com/react-native-training/react-native-custom-fonts-ccc9aacf9e5e). On IOS you need to use the font's display name in the stylesheet while on Android you need to downcase the font, underscore, and add the font style ex. "myriadpro_regular". 18 | 19 | In this situation you are forced to list each in it's own distinct way because neither will understand the other. There are a whole host of tiny differences that pop up between platforms and my goal was to create an API with the tools to solve these problems as elegantly as possible. 20 | 21 | ## Workflow. 22 | 23 | Now that [multi-client support](https://github.com/facebook/react-native/commit/8b2975ad7b27ce34dcf56836685fd54ddd62086c) has been added for hot module reloading, one of the best ways to use this API is to get a huge USB splitter and connect at minimum an iPhone, IOS tablet, Android Phone, and Android Tablet... also connecting other unique devices such as the iPhone X or Samsung Note 8. When each device has finished booting into the debug version of your app, set each device to hot reload (and only 1 device for debugging if you need it, they will fight each other for it). 24 | 25 | It can take a few tries to get everything hot reloading at the same time, but now you'll be able to see any change you make to any of these different device types instantly. This npm makes it really easy to tweak everything at the same time so that you can style for all devices simulataneously. 26 | 27 | 28 | ![Working on Master A Million](./MaM.jpg) 29 | 30 | 31 | ## The Value of React-Native. 32 | 33 | As a React-Native developer our greatest value to our clients is the ability to produce products rapidly that work on as many devices as possible, with only one codebase. This is my best shot at it so far. I hope it helps you. 34 | 35 | ## Install 36 | ```bash 37 | $ npm install react-native-cross-platform-responsive-dimensions --save 38 | ``` 39 | 40 | ```bash 41 | $ npm install npm intall react-native-device-info --save //don't forget to link 42 | ``` 43 | 44 | # Available API Methods 45 | 46 | #### Add an import to the top of your file with the methods you need. 47 | 48 | ```js 49 | import { 50 | responsiveHeight, 51 | responsiveWidth, 52 | responsiveFontSize, 53 | heightX, 54 | widthX, 55 | fontSizeX, 56 | heightN8, 57 | widthN8, 58 | fontSizeN8, 59 | heightXN8, 60 | widthXN8, 61 | fontSizeXN8, 62 | crossResponsiveHeight, 63 | crossResponsiveWidth, 64 | crossResponsiveFontSize, 65 | crossPlatformOS, 66 | crossPlatformImg, 67 | crossPlatformDevice, 68 | crossWidthX, 69 | crossHeightX 70 | crossFontSizeX, 71 | crossWidthN8, 72 | crossHeightN8 73 | crossFontSizeN8, 74 | crossHeightXN8, 75 | crossWidthXN8, 76 | crossFontSizeXN8, 77 | } from "react-native-cross-platform-responsive-dimensions"; 78 | ``` 79 | 80 | # Positioning Methods 81 | 82 | Use these positioning methods in your **JSS** stylesheets: 83 | 84 | + ```crossResponsiveHeight``` 85 | + ```crossResponsiveWidth``` 86 | + ```crossResponsiveFontSize``` 87 | 88 | These allow you to set individual percentage based properties for tablets and phones on both operating systems. 89 | 90 | ## Inputs 91 | ```crossResponsiveHeight(IOS_Phone, IOS_Tablet, Android_Phone, Android_Tablet)``` 92 | 93 | *You won't always need a different value* for each **OS** or **Device** type, so make sure to use the method that allows you to only be as specific as you need. 94 | 95 | 96 | ## Example JSS StyleSheet 97 | 98 | 99 | ```js 100 | const styles = StyleSheet.create({ 101 | modal: { 102 | alignSelf: "center", 103 | backgroundColor: teal, 104 | borderRadius: responsiveHeight(5), 105 | display: "flex", 106 | justifyContent: "space-between", 107 | marginBottom: crossResponsiveHeight(31, 32, 31, 32), 108 | marginTop: crossResponsiveHeight(36, 32.5, 36, 32.5), 109 | width: crossResponsiveWidth(75, 55, 75, 55) 110 | }, 111 | modalItem: { 112 | alignContent: "center", 113 | alignSelf: "center", 114 | backgroundColor: transparent, 115 | textAlign: "center", 116 | width: responsiveWidth(55) 117 | }, 118 | modalBounceGoalText: { 119 | fontFamily: crossPlatformOS("Neuropolitical", "neuropolitical_regular"), 120 | fontSize: responsiveFontSize(3.5), 121 | marginTop: responsiveHeight(2), 122 | color: white 123 | }, 124 | modalBadgeNameText: { 125 | color: white, 126 | fontWeight: "400", 127 | fontFamily: crossPlatformOS("Myriad Pro", "myriadpro_regular"), 128 | fontSize: responsiveFontSize(2), 129 | marginTop: responsiveHeight(2) 130 | }, 131 | badgeImage: { 132 | display: "flex", 133 | justifyContent: "center", 134 | alignSelf: "center", 135 | height: crossResponsiveWidth(25, 20, 20, 15), 136 | marginLeft: responsiveWidth(1), 137 | marginRight: responsiveWidth(1), 138 | width: crossResponsiveWidth(25, 20, 20, 15) 139 | }, 140 | xImage: { 141 | height: responsiveHeight(4.5), 142 | width: responsiveHeight(4.5) 143 | }, 144 | xContainer: { 145 | alignSelf: "flex-end", 146 | display: "flex", 147 | top: crossResponsiveHeight(1.8, 1.5, 2, 2), 148 | marginRight: crossResponsiveWidth(8, 4.5, 12, 12), 149 | width: responsiveWidth(4) 150 | } 151 | }); 152 | ``` 153 | 154 | # Cross Platform/Device Switch Methods 155 | 156 | Use ```crossPlatformDevice(iosPhone, iosTablet, androidPhone, androidTablet)``` for the same cross platform ease, but without the responsive scaling. 157 | 158 | Put any type of element you need into it and use it like a **switch**. 159 | 160 | ```html 161 | 170 | ``` 171 | 172 | Use ```crossPlatformOS(ios, android)``` when you don't need to specify individual values for all devices, but only need to specify either Android or IOS. 173 | 174 | This is useful for fonts because each OS requires the font be declared differently. 175 | 176 | ```js 177 | crossPlatformOS("Neuropolitical", "neuropolitical_regular") 178 | 179 | ``` 180 | Use ```crossPlatformImg(image)``` when you are loading images from [Hybrid App Resources](https://facebook.github.io/react-native/docs/images.html), adding them into your IOS project, and adding them into your Android drawable folder. IOS wants to see the file with the file extension and Android wants it without. 181 | 182 | Android requires that you also start the file name with a letter and separate each word with an underscore. IOS won't care so might as well format your file names for Android. 183 | 184 | This function removes the file extension when the device is running Android ("button" instead of "button.png"), and keeps it for IOS. You must also use .png's for native images. The method trims off the last 4 characters so if you use this with an extension with a different number characters it won't work right. 185 | 186 | ```js 187 | crossPlatformImg("button.png") 188 | ``` 189 | 190 | # Responsive Dimensions Methods 191 | Use the original [react-native-responsive-dimensions](https://github.com/DaniAkash/react-native-responsive-dimensions) methods if you want to use a uniform value for all devices. Try to use this whenever you can and only use the above cross platform methods when it's necessary. 192 | 193 | ```js 194 | height: responsiveHeight(43), 195 | marginLeft: responsiveWidth(10), 196 | fontSize: responsiveFontSize(4) 197 | ``` 198 | 199 | You can also use these methods outside of JSS in creative ways anytime you'd like to create a device scaled value. 200 | 201 | Here I used it to create a device scaled circle: 202 | 203 | 204 | ```html 205 | 218 | ``` 219 | 220 | Here I used it to set positions in my app's animated intro: 221 | 222 | ```js 223 | Animated.timing(this.state.fade, { 224 | duration: 1500, 225 | toValue: 1, 226 | useNativeDriver: true 227 | }), 228 | Animated.timing(this.state.position, { 229 | duration: 200, 230 | toValue: responsiveHeight(-50), 231 | useNativeDriver: true 232 | }), 233 | Animated.parallel([ 234 | Animated.timing(this.state.position, { 235 | duration: 1000, 236 | easing: Easing.bounce, 237 | toValue: responsiveHeight(52), 238 | useNativeDriver: true 239 | }), 240 | Animated.spring(this.state.size, { 241 | bounciness: 0, 242 | speed: 1, 243 | toValue: 0.3, 244 | useNativeDriver: true 245 | }) 246 | ]) 247 | ``` 248 | # iPhone X 249 | 250 | I've added some new functions to deal with devices that don't quite fit the 16:9 aspect ratio of most phones. If you find you need to move something specifically for the notch on the iPhoneX and it's approximately [9:19.5 aspect ratio](https://medium.com/@hacknicity/how-ios-apps-adapt-to-the-iphone-x-screen-size-a00bd109bbb9), you can use these functions to do so. 251 | 252 | 253 | Keep your cross-platform styles but set a specific value for iPhoneX. 254 | 255 | ```js 256 | crossHeightX(iosPhone, iosTablet, androidPhone, androidTablet, iPhoneX) 257 | ``` 258 | 259 | ResponsiveHeight for all devices except a specific value for iPhoneX. 260 | 261 | ```js 262 | heightX(height, iPhoneX) 263 | ``` 264 | 265 | Keep your cross-platform styles but set a specific value for iPhoneX. 266 | 267 | ```js 268 | crossWidthX(iosPhone, iosTablet, androidPhone, androidTablet, iPhoneX) 269 | ``` 270 | ResponsiveWidth for all devices except a specific value for iPhoneX. 271 | 272 | ```js 273 | widthX(width, iPhoneX) 274 | ``` 275 | 276 | Keep your cross-platform styles but set a specific value for iPhoneX. 277 | 278 | ```js 279 | crossFontSizeX(iosPhone, iosTablet, androidPhone, androidTablet, iPhoneX) 280 | ``` 281 | 282 | ResponsiveFontSize for all devices except a specific value for iPhoneX. 283 | 284 | ```js 285 | fontSizeX(size, iPhoneX) 286 | ``` 287 | 288 | ## iPhone X Example 289 | 290 | flexContainer: { 291 | backgroundColor: white, 292 | borderColor: grey, 293 | borderRadius: responsiveHeight(100), 294 | borderWidth: 1, 295 | display: "flex", 296 | left: crossWidthX(72, 68.5, 72, 66.5, 78.5), 297 | padding: crossHeightX(1, 2.1), 298 | position: "absolute", 299 | top: crossResponsiveHeight(41, 39.5, 40, 39.5), 300 | zIndex: 1 301 | } 302 | 303 | # Note 8 304 | 305 | I personally own a **Note 8** as my main phone (and love it), so there was no way I going to let it's elongated [18.5:9 aspect ratio](https://www.forbes.com/sites/gordonkelly/2017/08/28/galaxy-note-8-vs-galaxy-s8-should-you-upgrade/#5928dc493608) mess up my sweet scaling layouts. I haven't needed to make too many tweaks for my Note since it doesn't have a notch, but decided that it was worth having these methods around because the long form way of writing these out is clutter that shouldn't be in the StyleSheet, not even once. 306 | 307 | Keep your cross-platform styles but set a specific value for note8. 308 | 309 | ```js 310 | crossHeightN8(iosPhone, iosTablet, androidPhone, androidTablet, note8) 311 | ``` 312 | 313 | ResponsiveHeight for all devices except a specific value for note8. 314 | 315 | ```js 316 | heightN8(height, note8) 317 | ``` 318 | 319 | Keep your cross-platform styles but set a specific value for note8. 320 | 321 | ```js 322 | crossWidthN8(iosPhone, iosTablet, androidPhone, androidTablet, note8) 323 | ``` 324 | 325 | ResponsiveWidth for all devices except a specific value for the Note8. 326 | 327 | ```js 328 | widthN8(width, note8) 329 | ``` 330 | 331 | Keep your cross-platform styles but set a specific value for the Note8. 332 | 333 | ```js 334 | crossFontSizeN8(iosPhone, iosTablet, androidPhone, androidTablet, note8) 335 | ``` 336 | 337 | ResponsiveFontSize for all devices except a specific value for the Note8. 338 | 339 | ```js 340 | fontSizeN8(size, note8) 341 | ``` 342 | 343 | ## Note 8 Example 344 | 345 | ```js 346 | flexContainer: { 347 | backgroundColor: white, 348 | borderColor: grey, 349 | borderRadius: responsiveHeight(100), 350 | borderWidth: 1, 351 | display: "flex", 352 | left: crossWidthN8(72, 68.5, 72, 66.5, 78.5), 353 | padding: heightN8(1, 2.1), 354 | position: "absolute", 355 | top: crossResponsiveHeight(41, 39.5, 40, 39.5), 356 | zIndex: 1 357 | } 358 | ``` 359 | 360 | # Hybrid iPhoneX + Note 8 361 | 362 | ResponsiveHeight for cross device and platform as well as both iPhoneX and Note8. 363 | 364 | ```js 365 | crossHeightXN8(iPhone, IOSTablet, AndroidPhone, AndroidTablet, iPhoneX, Note8) 366 | ``` 367 | 368 | ResponsiveHeight for cross device and platform as well as both iPhoneX and Note8. 369 | 370 | ```js 371 | crossFontSizeXN8(iPhone, IOSTablet, AndroidPhone, AndroidTablet, iPhoneX, Note8) 372 | ``` 373 | 374 | ResponsiveWidth for cross device and platform as well as both iPhoneX and Note8. 375 | 376 | ```js 377 | crossWidthXN8(iPhone, IOSTablet, AndroidPhone, AndroidTablet, iPhoneX, Note8) 378 | ``` 379 | 380 | ResponsiveWidth for all devices as well as specifically the iPhoneX and Note8. 381 | ```js 382 | widthXN8(size, iPhoneX, note8) 383 | ``` 384 | ResponsiveHeight for all devices as well as specifically the iPhoneX and Note8. 385 | 386 | ```js 387 | heightXN8(size, iPhoneX, note8) 388 | ``` 389 | 390 | ResponsiveFontSize for all devices as well as specifically the iPhoneX and Note8. 391 | 392 | ```js 393 | fontSizeXN8(size, iPhoneX, note8) 394 | ``` 395 | 396 | # Examples 397 | 398 | ```js 399 | modalSubText: { 400 | color: black, 401 | fontFamily: crossPlatformOS("Neuropolitical", "neuropolitical_regular"), 402 | fontSize: fontSizeXN8(3.5, 3.1, 2.95), 403 | marginTop: responsiveHeight(2) 404 | } 405 | ``` 406 | 407 | ```js 408 | flexContainer: { 409 | backgroundColor: white, 410 | borderColor: grey, 411 | borderRadius: responsiveHeight(100), 412 | borderWidth: 1, 413 | display: "flex", 414 | justifyContent: "space-between", 415 | left: crossWidthXN8(72, 68.5, 72, 66.5, 78.5, 75), 416 | padding: responsiveHeight(1), 417 | position: "absolute", 418 | top: crossResponsiveHeight(41, 39.5, 40, 39.5), 419 | zIndex: 1 420 | }, 421 | ``` 422 | 423 | ## License 424 | MIT © [drumnation](https://github.com/drumnation/react-native-cross-responsive-dimensions) --------------------------------------------------------------------------------