├── .gitignore ├── LICENSE ├── README.md ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | node_modules 4 | *.log 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native Flex Helper 2 | 3 | A compilation of useful style helpers and shorthands in React Native 4 | 5 | ## Installation 6 | 7 | ```sh 8 | yarn add react-native-flex-helper 9 | or 10 | npm i -S react-native-flex-helper 11 | ``` 12 | 13 | ## How it works 14 | 15 | ```FlexHelpers.create``` uses ReactNative's ```StyleSheet.create``` to build for you a new stylesheet containing your style rules and the helper rules. 16 | 17 | Overlapping names will be overwritten by the styles helpers, be careful. 18 | 19 | ## Usage 20 | 21 | Simply import the package 22 | ```jsx 23 | import FlexHelpers from 'react-native-flex-helper'; 24 | or 25 | const FlexHelpers = require('react-native-flex-helper'); 26 | ``` 27 | Find your stylesheet declaration, for example 28 | ```jsx 29 | const styles = StyleSheet.create({ 30 | box: { backgroundColor: 'red' }, 31 | text: { color: '#000' }, 32 | }); 33 | ``` 34 | And just replace 35 | ```StyleSheet.create``` with ```FlexHelpers.create``` 36 | Like this 37 | ```jsx 38 | const styles = FlexHelpers.create({ 39 | box: { backgroundColor: 'red' }, 40 | text: { color: '#000' }, 41 | }); 42 | ``` 43 | You are ready to use it ! 44 | ```jsx 45 | 46 | 47 | Hello 48 | World! 49 | 50 | 51 | ``` 52 | 53 | ### Additional (compatibility with older versions) 54 | 55 | You can also use FlexHelpers as a static stylesheet and merge your styles with an array (it may not work with a spread operator). 56 | ```jsx 57 | const styles = StyleSheet.create({ 58 | text: { color: '#000' }, 59 | }); 60 | ... 61 | const HelloWorld = () => ( 62 | Hello World! 63 | ); 64 | ``` 65 | 66 | ## Quick guide to Flexbox 67 | 68 | [Flexbox tutorial](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) 69 | 70 | 71 | ## Translation 72 | 73 | #### Layout 74 | - **```fill```** : ```{ flex: 1 }``` 75 | - **```center```** : ```{ alignItems: 'center', justifyContent: 'center' }``` 76 | 77 | #### Orientation 78 | - **```row```** : ```{ flexDirection: 'row' }``` 79 | - **```rowReverse```** : ```{ flexDirection: 'row-reverse' }``` 80 | - **```column```** or **```col```** : ```{ flexDirection: 'column' }``` 81 | - **```columnReverse```** or **```colReverse```** : ```{ flexDirection: 'column-reverse' }``` 82 | 83 | #### Main axis 84 | - **```mainStart```** : ```{ justifyContent: 'flex-start' }``` 85 | - **```mainCenter```** : ```{ justifyContent: 'center' }``` 86 | - **```mainEnd```** : ```{ justifyContent: 'flex-end' }``` 87 | - **```mainSpaceBetween```** : ```{ justifyContent: 'space-between' }``` 88 | - **```mainSpaceAround```** : ```{ justifyContent: 'space-around' }``` 89 | 90 | #### Cross axis 91 | - **```crossStart```** : ```{ alignItems: 'flex-start' }``` 92 | - **```crossCenter```** : ```{ alignItems: 'center' }``` 93 | - **```crossEnd```** : ```{ alignItems: 'flex-end' }``` 94 | - **```crossStretch```** : ```{ alignItems: 'stretch' }``` 95 | 96 | #### Shorthands 97 | - **```rowMain```** : ```{ flexDirection: 'row', justifyContent: 'center' }``` 98 | - **```rowCross```** : ```{ flexDirection: 'row', alignItems: 'center' }``` 99 | - **```rowCenter```** : ```{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }``` 100 | - **```colMain```** : ```{ flexDirection: 'column', justifyContent: 'center' }``` 101 | - **```colCross```** : ```{ flexDirection: 'column', alignItems: 'center' }``` 102 | - **```colCenter```** : ```{ flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }``` 103 | - **```fillCenter```** : ```{ flex: 1, alignItems: 'center', justifyContent: 'center' }``` 104 | - **```fillRow```** : ```{ flex: 1, flexDirection: 'row' }``` 105 | - **```fillRowReverse```** : ```{ flex: 1, flexDirection: 'row-reverse' }``` 106 | - **```fillRowMain```** : ```{ flex: 1, flexDirection: 'row', justifyContent: 'center' }``` 107 | - **```fillRowCross```** : ```{ flex: 1, flexDirection: 'row', alignItems: 'center' }``` 108 | - **```fillRowCenter```** : ```{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }``` 109 | - **```fillCol```** : ```{ flex: 1, flexDirection: 'column' }``` 110 | - **```fillColReverse```** : ```{ flex: 1, flexDirection: 'column-reverse' }``` 111 | - **```fillColMain```** : ```{ flex: 1, flexDirection: 'column', justifyContent: 'center' }``` 112 | - **```fillColCross```** : ```{ flex: 1, flexDirection: 'column', alignItems: 'center' }``` 113 | - **```fillColCenter```** : ```{ flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }``` 114 | 115 | #### Position helpers 116 | - **```relative```** : ```{ position: 'relative' }``` 117 | - **```absolute```** : ```{ position: 'absolute' }``` 118 | - **```absoluteFill```** : ```{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }``` 119 | - **```absoluteTop```** : ```{ position: 'absolute', top: 0, left: 0, right: 0 }``` 120 | - **```absoluteLeft```** : ```{ position: 'absolute', top: 0, left: 0, bottom: 0 }``` 121 | - **```absoluteRight```** : ```{ position: 'absolute', top: 0, right: 0, bottom: 0 }``` 122 | - **```absoluteBottom```** : ```{ position: 'absolute', left: 0, right: 0, bottom: 0 }``` 123 | - **```absoluteTopLeft```** : ```{ position: 'absolute', top: 0, left: 0 }``` 124 | - **```absoluteTopRight```** : ```{ position: 'absolute', top: 0, right: 0 }``` 125 | - **```absoluteBottomLeft```** : ```{ position: 'absolute', bottom: 0, left: 0 }``` 126 | - **```absoluteBottomRight```** : ```{ position: 'absolute', bottom: 0, right: 0 }``` 127 | 128 | #### Additional features 129 | - **```overflow```** : ```{ overflow: 'hidden' }``` 130 | - **```shadow(level)```** : ```Uses the correct way to display a shadow in the platform (Android, iOS, Web)``` 131 | - **```circle(size)```** : ```Sets width and height to the mentioned size and borderRadius to half of the size``` 132 | - **```textCenter```** : ```{ textAlign: 'center' }``` 133 | - **```textJustify```** : ```{ textAlign: 'justify' }``` 134 | - **```textLeft```** : ```{ textAlign: 'left' }``` 135 | - **```textRight```** : ```{ textAlign: 'right' }``` 136 | - **```backgroundReset```** : ```{ backgroundColor: 'transparent' }``` is a fix for a common iOS issue where the backgroundColor of some tags is transferred to children and need to be reset 137 | 138 | ## License 139 | 140 | MIT Licensed 141 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * index.js 3 | * https://github.com/VinceBT/react-native-flex-helper 4 | */ 5 | 6 | import { StyleSheet, Platform } from 'react-native'; 7 | 8 | const emptyStyle = {}; 9 | 10 | const flexHelperStyles = { 11 | fill: { 12 | flex: 1, 13 | }, 14 | center: { 15 | alignItems: 'center', 16 | justifyContent: 'center', 17 | }, 18 | fillCenter: { 19 | flex: 1, 20 | alignItems: 'center', 21 | justifyContent: 'center', 22 | }, 23 | row: { 24 | flexDirection: 'row', 25 | }, 26 | rowReverse: { 27 | flexDirection: 'row-reverse', 28 | }, 29 | column: { 30 | flexDirection: 'column', 31 | }, 32 | col: { 33 | flexDirection: 'column', 34 | }, 35 | columnReverse: { 36 | flexDirection: 'column-reverse', 37 | }, 38 | colReverse: { 39 | flexDirection: 'column-reverse', 40 | }, 41 | mainStart: { 42 | justifyContent: 'flex-start', 43 | }, 44 | mainCenter: { 45 | justifyContent: 'center', 46 | }, 47 | mainEnd: { 48 | justifyContent: 'flex-end', 49 | }, 50 | mainSpaceBetween: { 51 | justifyContent: 'space-between', 52 | }, 53 | mainSpaceAround: { 54 | justifyContent: 'space-around', 55 | }, 56 | crossStart: { 57 | alignItems: 'flex-start', 58 | }, 59 | crossCenter: { 60 | alignItems: 'center', 61 | }, 62 | crossEnd: { 63 | alignItems: 'flex-end', 64 | }, 65 | crossStretch: { 66 | alignItems: 'stretch', 67 | }, 68 | rowMain: { 69 | flexDirection: 'row', 70 | justifyContent: 'center', 71 | }, 72 | rowCross: { 73 | flexDirection: 'row', 74 | alignItems: 'center', 75 | }, 76 | rowCenter: { 77 | flexDirection: 'row', 78 | alignItems: 'center', 79 | justifyContent: 'center', 80 | }, 81 | colMain: { 82 | flexDirection: 'column', 83 | justifyContent: 'center', 84 | }, 85 | colCross: { 86 | flexDirection: 'column', 87 | alignItems: 'center', 88 | }, 89 | colCenter: { 90 | flexDirection: 'column', 91 | alignItems: 'center', 92 | justifyContent: 'center', 93 | }, 94 | fillRow: { 95 | flex: 1, 96 | flexDirection: 'row', 97 | }, 98 | fillRowReverse: { 99 | flex: 1, 100 | flexDirection: 'row-reverse', 101 | }, 102 | fillRowMain: { 103 | flex: 1, 104 | flexDirection: 'row', 105 | justifyContent: 'center', 106 | }, 107 | fillRowCross: { 108 | flex: 1, 109 | flexDirection: 'row', 110 | alignItems: 'center', 111 | }, 112 | fillRowCenter: { 113 | flex: 1, 114 | flexDirection: 'row', 115 | alignItems: 'center', 116 | justifyContent: 'center', 117 | }, 118 | fillCol: { 119 | flex: 1, 120 | flexDirection: 'column', 121 | }, 122 | fillColReverse: { 123 | flex: 1, 124 | flexDirection: 'column-reverse', 125 | }, 126 | fillColMain: { 127 | flex: 1, 128 | flexDirection: 'column', 129 | justifyContent: 'center', 130 | }, 131 | fillColCross: { 132 | flex: 1, 133 | flexDirection: 'column', 134 | alignItems: 'center', 135 | }, 136 | fillColCenter: { 137 | flex: 1, 138 | flexDirection: 'column', 139 | alignItems: 'center', 140 | justifyContent: 'center', 141 | }, 142 | relative: { 143 | position: 'relative', 144 | }, 145 | absolute: { 146 | position: 'absolute', 147 | }, 148 | absoluteFill: { 149 | position: 'absolute', 150 | top: 0, 151 | left: 0, 152 | right: 0, 153 | bottom: 0, 154 | }, 155 | absoluteTop: { 156 | position: 'absolute', 157 | top: 0, 158 | left: 0, 159 | right: 0, 160 | }, 161 | absoluteLeft: { 162 | position: 'absolute', 163 | top: 0, 164 | left: 0, 165 | bottom: 0, 166 | }, 167 | absoluteRight: { 168 | position: 'absolute', 169 | top: 0, 170 | right: 0, 171 | bottom: 0, 172 | }, 173 | absoluteBottom: { 174 | position: 'absolute', 175 | left: 0, 176 | right: 0, 177 | bottom: 0, 178 | }, 179 | absoluteTopLeft: { 180 | position: 'absolute', 181 | top: 0, 182 | left: 0, 183 | }, 184 | absoluteTopRight: { 185 | position: 'absolute', 186 | top: 0, 187 | right: 0, 188 | }, 189 | absoluteBottomLeft: { 190 | position: 'absolute', 191 | bottom: 0, 192 | left: 0, 193 | }, 194 | absoluteBottomRight: { 195 | position: 'absolute', 196 | bottom: 0, 197 | right: 0, 198 | }, 199 | overflow: { 200 | overflow: 'hidden', 201 | }, 202 | textCenter: { 203 | textAlign: 'center', 204 | }, 205 | textJustify: { 206 | textAlign: 'justify', 207 | }, 208 | textLeft: { 209 | textAlign: 'left', 210 | }, 211 | textRight: { 212 | textAlign: 'right', 213 | }, 214 | backgroundReset: { 215 | backgroundColor: 'transparent', 216 | }, 217 | }; 218 | 219 | const computeShadowStyle = (level) => { 220 | if (typeof level === 'undefined' || isNaN(level)) 221 | return emptyStyle; 222 | const safeLevel = Number(level); 223 | if (safeLevel <= 0) 224 | return emptyStyle; 225 | if (Platform.OS === 'android') 226 | return { elevation: safeLevel }; 227 | if (Platform.OS === 'ios') { 228 | return { 229 | shadowOpacity: 0.0015 * safeLevel + 0.18, 230 | shadowRadius: 0.54 * safeLevel, 231 | shadowOffset: { 232 | height: 0.6 * safeLevel, 233 | }, 234 | }; 235 | } 236 | return { 237 | boxShadow: 'rgba(0, 0, 0, ' + (0.07 + (safeLevel * 0.045)).toFixed(2) + ') 0px 0px '+ ((safeLevel * 13.6) - 9.6).toFixed(2) + 'px', 238 | }; 239 | }; 240 | 241 | const computeCircleStyle = (sizeOrWidth, height) => { 242 | if (typeof sizeOrWidth === 'undefined' || isNaN(sizeOrWidth)) 243 | return emptyStyle; 244 | const safeSizeOrWidth = Number(sizeOrWidth); 245 | if (safeSizeOrWidth < 0) 246 | return emptyStyle; 247 | if (typeof height !== 'undefined' && !isNaN(height)) { 248 | const safeHeight = Number(height); 249 | if (safeHeight < 0) 250 | return emptyStyle; 251 | return { 252 | width: safeSizeOrWidth, 253 | height: safeHeight, 254 | borderRadius: Math.min(safeSizeOrWidth, safeHeight) /2, 255 | }; 256 | } 257 | return { 258 | width: safeSizeOrWidth, 259 | height: safeSizeOrWidth, 260 | borderRadius: safeSizeOrWidth /2, 261 | }; 262 | }; 263 | 264 | const createStyleSheet = function(extStyles) { 265 | const mergedStyles = Object.assign({}, extStyles, flexHelperStyles); 266 | const styleSheet = StyleSheet.create(mergedStyles); 267 | styleSheet.shadow = computeShadowStyle; 268 | styleSheet.circle = computeCircleStyle; 269 | return styleSheet; 270 | }; 271 | 272 | const FlexHelpers = createStyleSheet(flexHelperStyles); 273 | FlexHelpers.create = createStyleSheet; 274 | 275 | export const styles = flexHelperStyles; // May miss computation functions 276 | export const create = createStyleSheet; 277 | 278 | export default FlexHelpers; 279 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-flex-helper", 3 | "version": "3.2.0", 4 | "description": "A compilation of style helpers in React Native", 5 | "keywords": [ 6 | "react", 7 | "native", 8 | "reactnative", 9 | "react-native", 10 | "react-native-flex", 11 | "flex", 12 | "box", 13 | "flexbox", 14 | "flex-box", 15 | "style", 16 | "styles", 17 | "helper", 18 | "helpers" 19 | ], 20 | "main": "index.js", 21 | "scripts": { 22 | "test": "echo \"Error: no test specified\" && exit 1" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/VinceBT/react-native-flex-helper.git" 27 | }, 28 | "author": "VinceBT", 29 | "license": "MIT", 30 | "bugs": { 31 | "url": "https://github.com/VinceBT/react-native-flex-helper/issues" 32 | }, 33 | "homepage": "https://github.com/VinceBT/react-native-flex-helper#readme", 34 | "peerDependencies": { 35 | "react-native": ">=0.15.0" 36 | } 37 | } 38 | --------------------------------------------------------------------------------