├── .prettierignore ├── src ├── assets │ ├── icon.png │ └── splash.png ├── constants │ ├── index.js │ ├── colors.js │ ├── device.js │ └── globalStyles.js ├── context │ └── ColorContext.js ├── navigation │ ├── RootStack.js │ └── MainStack.js ├── screens │ ├── SelectColor.js │ └── Home.js ├── icons │ └── Svg.Droplet.js └── components │ ├── LineItemColor.js │ └── NeuButton.js ├── screenshots └── screenshare-3.jpg ├── babel.config.js ├── .gitignore ├── .eslintrc ├── app.json ├── App.js ├── package.json └── README.md /.prettierignore: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /src/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebnance/expo-neumorphism/HEAD/src/assets/icon.png -------------------------------------------------------------------------------- /src/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebnance/expo-neumorphism/HEAD/src/assets/splash.png -------------------------------------------------------------------------------- /screenshots/screenshare-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebnance/expo-neumorphism/HEAD/screenshots/screenshare-3.jpg -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | 4 | return { 5 | presets: ['babel-preset-expo'] 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | .expo-shared/* 4 | npm-debug.* 5 | *.orig.* 6 | web-build/* 7 | web-report/ 8 | 9 | # macOS 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /src/constants/index.js: -------------------------------------------------------------------------------- 1 | import colors from './colors'; 2 | import device from './device'; 3 | import gStyle from './globalStyles'; 4 | 5 | export { colors, device, gStyle }; 6 | -------------------------------------------------------------------------------- /src/constants/colors.js: -------------------------------------------------------------------------------- 1 | export default { 2 | black: '#000', 3 | black20: 'rgba(0, 0, 0, 0.2)', 4 | black40: 'rgba(0, 0, 0, 0.4)', 5 | black50: 'rgba(0, 0, 0, 0.5)', 6 | black70: 'rgba(0, 0, 0, 0.7)', 7 | white: '#fff' 8 | }; 9 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb", "prettier"], 3 | "parser": "babel-eslint", 4 | "plugins": ["prettier", "eslint-plugin-import-helpers"], 5 | "rules": { 6 | "prettier/prettier": ["error"], 7 | "no-use-before-define": 0, 8 | "react/forbid-prop-types": 0, 9 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 10 | "react/jsx-fragments": 0 11 | }, 12 | "globals": { 13 | "__DEV__": "readonly", 14 | "describe": "readonly", 15 | "expect": "readonly", 16 | "it": "readonly", 17 | "jest": "readonly" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "Expo Neumorphism", 4 | "description": "neumorphism with expo", 5 | "scheme": "exponeumorphism", 6 | "slug": "exponeumorphism", 7 | "privacy": "public", 8 | "version": "0.0.1", 9 | "platforms": ["android", "ios", "web"], 10 | "githubUrl": "https://github.com/calebnance/expo-neumorphism", 11 | "orientation": "portrait", 12 | "primaryColor": "#55b9f3", 13 | "icon": "src/assets/icon.png", 14 | "splash": { 15 | "backgroundColor": "#55b9f3", 16 | "image": "src/assets/splash.png", 17 | "resizeMode": "contain" 18 | }, 19 | "assetBundlePatterns": ["**/*"], 20 | "android": { 21 | "versionCode": 1 22 | }, 23 | "ios": { 24 | "buildNumber": "0.0.1", 25 | "supportsTablet": true 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/constants/device.js: -------------------------------------------------------------------------------- 1 | import { Dimensions, Platform } from 'react-native'; 2 | 3 | // android 4 | const android = Platform.OS === 'android'; 5 | 6 | const iOS = Platform.OS === 'ios'; 7 | const web = Platform.OS === 'web'; 8 | const windowInfo = Dimensions.get('window'); 9 | const { height, width } = windowInfo; 10 | const aspectRatio = height / width; 11 | 12 | // is iPad 13 | const { isPad } = Platform; 14 | 15 | // is iPhone with Notch? 16 | // iPhoneX, iPhoneXs, iPhoneXr, iPhoneXs Max, iPhone 11 & 12 17 | let iPhoneNotch = false; 18 | if (iOS) { 19 | // iphone screen breakdown 20 | // https://blog.calebnance.com/development/iphone-ipad-pixel-sizes-guide-complete-list.html 21 | if (height === 812 || height === 844 || height === 896 || height === 926) { 22 | iPhoneNotch = true; 23 | } 24 | } 25 | 26 | export default { 27 | android, 28 | aspectRatio, 29 | height, 30 | iOS, 31 | iPhoneNotch, 32 | isPad, 33 | web, 34 | width 35 | }; 36 | -------------------------------------------------------------------------------- /src/context/ColorContext.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const colorOptions = { 4 | pictonBlue: { 5 | base: '#55b9f3', 6 | lighter: '#62d5ff', 7 | darker: '#489dcf', 8 | name: 'Picton Blue' 9 | }, 10 | 11 | manhattan: { 12 | base: '#f3cc91', 13 | lighter: '#ffeba7', 14 | darker: '#cfad7b', 15 | name: 'Manhattan' 16 | }, 17 | 18 | saharaSand: { 19 | base: '#e9f391', 20 | lighter: '#ffffa7', 21 | darker: '#c6cf7b', 22 | name: 'Sahara Sand' 23 | }, 24 | 25 | sulu: { 26 | base: '#b8f391', 27 | lighter: '#d4ffa7', 28 | darker: '#9ccf7b', 29 | name: 'Sulu' 30 | }, 31 | 32 | mauvelous: { 33 | base: '#f391b8', 34 | lighter: '#ffa7d4', 35 | darker: '#cf7b9c', 36 | name: 'Mauvelous' 37 | } 38 | }; 39 | 40 | export const ColorContext = React.createContext({ 41 | // default value 42 | color: colorOptions.pictonBlue, 43 | 44 | // update context function 45 | setColor: () => {} 46 | }); 47 | -------------------------------------------------------------------------------- /src/navigation/RootStack.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { NavigationContainer } from '@react-navigation/native'; 3 | import { createStackNavigator } from '@react-navigation/stack'; 4 | 5 | // grab main navigation stack 6 | import MainStackScreen from './MainStack'; 7 | 8 | // screens 9 | import SelectColor from '../screens/SelectColor'; 10 | 11 | // create navigation stack 12 | const RootStack = createStackNavigator(); 13 | 14 | const RootStackScreen = () => ( 15 | 16 | 17 | 22 | 29 | 30 | 31 | ); 32 | 33 | export default RootStackScreen; 34 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { StatusBar } from 'react-native'; 3 | 4 | // grab navigation root stack 5 | import RootStack from './src/navigation/RootStack'; 6 | 7 | // context 8 | import { colorOptions, ColorContext } from './src/context/ColorContext'; 9 | 10 | class App extends React.Component { 11 | constructor() { 12 | super(); 13 | 14 | const defaultColor = 'pictonBlue'; 15 | 16 | this.state = { 17 | color: defaultColor, 18 | colorObj: colorOptions[defaultColor] 19 | }; 20 | 21 | this.setColor = this.setColor.bind(this); 22 | } 23 | 24 | setColor(color) { 25 | this.setState({ color, colorObj: colorOptions[color] }); 26 | } 27 | 28 | render() { 29 | const { color, colorObj } = this.state; 30 | 31 | return ( 32 | 35 | 36 | 37 | 38 | 39 | ); 40 | } 41 | } 42 | 43 | export default App; 44 | -------------------------------------------------------------------------------- /src/navigation/MainStack.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { TouchableOpacity } from 'react-native'; 3 | import { createStackNavigator } from '@react-navigation/stack'; 4 | import { gStyle } from '../constants'; 5 | 6 | // screens 7 | import Home from '../screens/Home'; 8 | 9 | // icons 10 | import SvgDroplet from '../icons/Svg.Droplet'; 11 | 12 | // create navigation stack 13 | const MainStack = createStackNavigator(); 14 | 15 | const MainStackScreen = () => ( 16 | 17 | ({ 21 | title: 'Neumorphism', 22 | headerRight: () => ( 23 | navigation.navigate('SelectColor')} 26 | style={gStyle.pR2} 27 | > 28 | 29 | 30 | ) 31 | })} 32 | /> 33 | 34 | ); 35 | 36 | export default MainStackScreen; 37 | -------------------------------------------------------------------------------- /src/screens/SelectColor.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { StyleSheet, View } from 'react-native'; 4 | import { colors } from '../constants'; 5 | 6 | // components 7 | import LineItemColor from '../components/LineItemColor'; 8 | 9 | // context 10 | import { colorOptions, ColorContext } from '../context/ColorContext'; 11 | 12 | const SelectColor = ({ navigation }) => ( 13 | 14 | {({ color }) => ( 15 | 16 | 17 | {Object.keys(colorOptions).map((key) => ( 18 | 24 | ))} 25 | 26 | 27 | )} 28 | 29 | ); 30 | 31 | SelectColor.propTypes = { 32 | // required 33 | navigation: PropTypes.object.isRequired 34 | }; 35 | 36 | const styles = StyleSheet.create({ 37 | container: { 38 | alignItems: 'center', 39 | backgroundColor: colors.white, 40 | flex: 1 41 | }, 42 | containerSelect: { 43 | maxWidth: 400, 44 | width: '100%' 45 | } 46 | }); 47 | 48 | export default SelectColor; 49 | -------------------------------------------------------------------------------- /src/icons/Svg.Droplet.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Svg, { Path } from 'react-native-svg'; 4 | import { colors } from '../constants'; 5 | 6 | const SvgDroplet = ({ size }) => ( 7 | 8 | 12 | 13 | ); 14 | 15 | SvgDroplet.defaultProps = { 16 | size: 28 17 | }; 18 | 19 | SvgDroplet.propTypes = { 20 | // optional 21 | size: PropTypes.number 22 | }; 23 | 24 | export default React.memo(SvgDroplet); 25 | -------------------------------------------------------------------------------- /src/components/LineItemColor.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; 4 | import { colors, gStyle } from '../constants'; 5 | 6 | // context 7 | import { colorOptions, ColorContext } from '../context/ColorContext'; 8 | 9 | const LineItemColor = ({ active, navigation, value }) => { 10 | const { setColor } = React.useContext(ColorContext); 11 | const { base, name } = colorOptions[value]; 12 | 13 | const borderColor = active ? colors.black : 'transparent'; 14 | const colorCircleExt = { backgroundColor: base, borderColor }; 15 | 16 | return ( 17 | { 20 | setColor(value); 21 | navigation.goBack(); 22 | }} 23 | style={styles.container} 24 | > 25 | 26 | {name} 27 | 28 | ); 29 | }; 30 | 31 | LineItemColor.propTypes = { 32 | // required 33 | active: PropTypes.bool.isRequired, 34 | navigation: PropTypes.object.isRequired, 35 | value: PropTypes.string.isRequired 36 | }; 37 | 38 | const styles = StyleSheet.create({ 39 | container: { 40 | ...gStyle.flexRowCenterAlign, 41 | ...gStyle.p2, 42 | backgroundColor: colors.white, 43 | width: '100%' 44 | }, 45 | colorCircle: { 46 | ...gStyle.mR2, 47 | borderRadius: 20, 48 | borderWidth: 2, 49 | height: 40, 50 | width: 40 51 | }, 52 | text: { 53 | fontSize: 18 54 | } 55 | }); 56 | 57 | export default LineItemColor; 58 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-neumorphism", 3 | "version": "0.0.1", 4 | "description": "neumorphism with expo", 5 | "author": "Caleb Nance", 6 | "license": "MIT", 7 | "keywords": [ 8 | "expo", 9 | "react native", 10 | "neumorphism" 11 | ], 12 | "main": "node_modules/expo/AppEntry.js", 13 | "scripts": { 14 | "dev": "expo start", 15 | "start": "expo start", 16 | "lint": "eslint ./src", 17 | "android": "expo start --android", 18 | "ios": "expo start --ios", 19 | "web": "expo start --web", 20 | "web-build": "expo build:web", 21 | "eject": "expo eject" 22 | }, 23 | "dependencies": { 24 | "@react-native-community/masked-view": "0.1.10", 25 | "@react-navigation/native": "^6.0.6", 26 | "@react-navigation/stack": "^6.0.11", 27 | "expo": "^44.0.0", 28 | "expo-linear-gradient": "~11.0.0", 29 | "prop-types": "^15.7.2", 30 | "react": "17.0.1", 31 | "react-dom": "17.0.1", 32 | "react-native": "0.64.3", 33 | "react-native-gesture-handler": "~2.1.0", 34 | "react-native-reanimated": "~2.3.1", 35 | "react-native-safe-area-context": "3.3.2", 36 | "react-native-screens": "~3.10.1", 37 | "react-native-svg": "12.1.1", 38 | "react-native-web": "0.17.1" 39 | }, 40 | "devDependencies": { 41 | "@babel/core": "^7.12.9", 42 | "babel-eslint": "^10.1.0", 43 | "babel-preset-expo": "9.0.1", 44 | "eslint": "^7.8.1", 45 | "eslint-config-airbnb": "^18.2.0", 46 | "eslint-config-prettier": "^6.11.0", 47 | "eslint-plugin-import": "^2.22.0", 48 | "eslint-plugin-import-helpers": "^1.1.0", 49 | "eslint-plugin-jsx-a11y": "^6.3.1", 50 | "eslint-plugin-prettier": "^3.1.4", 51 | "eslint-plugin-react": "^7.20.6", 52 | "eslint-plugin-react-hooks": "^4.2.0", 53 | "prettier": "^2.1.1" 54 | }, 55 | "prettier": { 56 | "singleQuote": true, 57 | "trailingComma": "none" 58 | }, 59 | "eslintIgnore": [ 60 | "babel.config.js" 61 | ], 62 | "private": true 63 | } 64 | -------------------------------------------------------------------------------- /src/components/NeuButton.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { StyleSheet, View } from 'react-native'; 4 | import { LinearGradient } from 'expo-linear-gradient'; 5 | 6 | // context 7 | import { ColorContext } from '../context/ColorContext'; 8 | 9 | // idk... 10 | const SQUARE = 200; // 200 11 | const SQUARE_RADIUS = SQUARE / 5; // 40 12 | const OFFSET = SQUARE_RADIUS / 2; // 20 13 | const SHADOW_RADIUS = OFFSET; // 6 14 | 15 | const NeuButton = ({ gradArray, showLinear }) => ( 16 | 17 | {({ colorObj }) => { 18 | const { base: backgroundColor, darker, lighter } = colorObj; 19 | const topLeft = { backgroundColor, shadowColor: lighter }; 20 | const bottomRight = { backgroundColor, shadowColor: darker }; 21 | 22 | return ( 23 | 24 | 25 | 26 | 27 | {showLinear && ( 28 | 33 | )} 34 | 35 | ); 36 | }} 37 | 38 | ); 39 | 40 | NeuButton.defaultProps = { 41 | showLinear: false 42 | }; 43 | 44 | NeuButton.propTypes = { 45 | // required 46 | gradArray: PropTypes.array.isRequired, 47 | 48 | // optional 49 | showLinear: PropTypes.bool 50 | }; 51 | 52 | const styles = StyleSheet.create({ 53 | box: { 54 | borderRadius: SQUARE_RADIUS, 55 | height: SQUARE, 56 | overflow: 'visible', 57 | width: SQUARE 58 | }, 59 | dropShadowTL: { 60 | borderRadius: SQUARE_RADIUS, 61 | height: SQUARE, 62 | width: SQUARE, 63 | shadowOffset: { width: -OFFSET, height: -OFFSET }, 64 | shadowOpacity: 1, 65 | shadowRadius: SHADOW_RADIUS 66 | }, 67 | dropShadowBR: { 68 | borderRadius: SQUARE_RADIUS, 69 | position: 'absolute', 70 | height: SQUARE, 71 | width: SQUARE, 72 | shadowOffset: { width: OFFSET, height: OFFSET }, 73 | shadowOpacity: 1, 74 | shadowRadius: SHADOW_RADIUS 75 | }, 76 | linear: { 77 | borderRadius: SQUARE_RADIUS, 78 | height: SQUARE, 79 | position: 'absolute', 80 | width: SQUARE 81 | } 82 | }); 83 | 84 | export default NeuButton; 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Neumorphism with Expo 2 | 3 | web demo: [Expo Neumorphism](https://expo-neumorphism.vercel.app) 4 | 5 | 6 | [![follow @calebnance](https://img.shields.io/twitter/follow/calebnance.svg?style=for-the-badge&logo=TWITTER&logoColor=FFFFFF&labelColor=00aced&logoWidth=20&color=lightgray)](https://twitter.com/calebnance) 7 | 8 |

9 | 10 |

11 | 12 | ## Table of Contents 13 | 14 | - [Install & Build](#install--build) 15 | - [Features](#features) 16 | - [Linting](#linting) 17 | - [Deploy to Zeit](#deploy-to-zeit) 18 | - [Release Notes](#release-notes) 19 | 20 | ## Install & Build 21 | 22 | First, make sure you have Expo CLI installed: `npm install -g expo-cli` 23 | 24 | Install: `yarn` or `yarn install` 25 | 26 | Run Project Locally: `yarn dev` or `yarn start` 27 | 28 | ## Features 29 | 30 | - Expo SDK 44 31 | - iOS, Android and PWA (Web App) 32 | - React Navigation v6 33 | - React Context 34 | - PropTypes 35 | 36 | ## Linting 37 | 38 | - run: `yarn lint` for a list of linting warnings/error in cli 39 | - prettier and airbnb config 40 | - make sure you have [prettier package](https://atom.io/packages/prettier-atom) installed on your atom/vscode editor 41 | - then make sure to enable these options (packages → prettier): 42 | - eslint integration 43 | - stylelint integration 44 | - automatic format on save (toggle format on save) 45 | - be aware of the `.prettierignore` file 46 | 47 | ## Deploy to Zeit 48 | 49 | - to create a web build run: `yarn web-build` or `expo build:web` 50 | - this will create a `/web-build` directory 51 | - then cd into that directory and run: `now` 52 | - i named my deploy by running: `now --name expo-neumorphism` 53 | - which produced this url: https://expo-neumorphism.calebnance.now.sh 54 | 55 | ## Release Notes 56 | 57 | ### version 0.0.1 (current) 58 | 59 | - upgraded to [Expo SDK 44](https://blog.expo.dev/expo-sdk-44-4c4b8306584a) 60 | - upgraded to [Expo SDK 43](https://blog.expo.dev/expo-sdk-43-aa9b3c7d5541) 61 | - upgraded to [React Navigation v6](https://reactnavigation.org/docs/getting-started) 62 | - upgraded to [Expo SDK 42](https://blog.expo.io/expo-sdk-42-579aee2348b6) 63 | - upgraded to [Expo SDK 41](https://blog.expo.io/expo-sdk-41-12cc5232f2ef) 64 | - upgraded to [Expo SDK 40](https://blog.expo.io/expo-sdk-40-is-now-available-d4d73e67da33) 65 | - upgraded to [Expo SDK 39](https://blog.expo.io/expo-sdk-39-is-now-available-4c10aa825e3f) 66 | - upgraded to [Expo SDK 38](https://blog.expo.io/expo-sdk-38-is-now-available-ab6cd30ca2ee) 67 | - upgraded to [Expo SDK 37](https://blog.expo.io/expo-sdk-37-is-now-available-dd5770f066a6) 68 | - started on [Expo SDK 36](https://blog.expo.io/expo-sdk-36-is-now-available-b91897b437fe) 69 | - started with [React Navigation v5](https://reactnavigation.org/docs/5.x/getting-started) 70 | - using [expo-linear-gradient](https://docs.expo.io/versions/latest/sdk/linear-gradient/) 71 | 72 | ### Inspiration / Tools 73 | 74 | - [Alexander Plyuto's dribbble](https://dribbble.com/shots/7994421-Skeuomorph-Mobile-Banking) 75 | - [Neumorphism in user interfaces](https://uxdesign.cc/neumorphism-in-user-interfaces-b47cef3bf3a6) 76 | - [Neumorphism.io](https://neumorphism.io/#55b9f3) -------------------------------------------------------------------------------- /src/screens/Home.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; 3 | import { colors, gStyle } from '../constants'; 4 | 5 | // components 6 | import NeuButton from '../components/NeuButton'; 7 | 8 | // context 9 | import { ColorContext } from '../context/ColorContext'; 10 | 11 | class Home extends React.Component { 12 | constructor(props, context) { 13 | super(props); 14 | 15 | const { colorObj } = context; 16 | 17 | const gradArray = [colorObj.lighter, colorObj.darker]; 18 | 19 | this.state = { 20 | showLinear: false, 21 | gradArray 22 | }; 23 | 24 | this.simple = this.simple.bind(this); 25 | this.pressedOn = this.pressedOn.bind(this); 26 | this.pressedOff = this.pressedOff.bind(this); 27 | } 28 | 29 | componentDidUpdate(prevProps, prevState) { 30 | if (prevState.showLinear === true) { 31 | this.setState({ 32 | showLinear: false 33 | }); 34 | } 35 | } 36 | 37 | simple() { 38 | this.setState({ 39 | showLinear: false 40 | }); 41 | } 42 | 43 | pressedOn() { 44 | const { colorObj } = this.context; 45 | const gradArray = [colorObj.darker, colorObj.lighter]; 46 | 47 | this.setState({ 48 | showLinear: true, 49 | gradArray 50 | }); 51 | } 52 | 53 | pressedOff() { 54 | const { colorObj } = this.context; 55 | const gradArray = [colorObj.lighter, colorObj.darker]; 56 | 57 | this.setState({ 58 | showLinear: true, 59 | gradArray 60 | }); 61 | } 62 | 63 | render() { 64 | const { gradArray, showLinear } = this.state; 65 | const { colorObj } = this.context; 66 | const { base: backgroundColor } = colorObj; 67 | 68 | return ( 69 | 70 | 75 | 76 | 77 | 82 | Simple 83 | 84 | 85 | 90 | On 91 | 92 | 93 | 98 | Off 99 | 100 | 101 | 102 | ); 103 | } 104 | } 105 | 106 | Home.contextType = ColorContext; 107 | 108 | const styles = StyleSheet.create({ 109 | container: { 110 | ...gStyle.flexCenter, 111 | flex: 1 112 | }, 113 | containerBtns: { 114 | bottom: 100, 115 | borderRadius: 3, 116 | flex: 1, 117 | flexDirection: 'row', 118 | overflow: 'hidden', 119 | position: 'absolute' 120 | }, 121 | btn: { 122 | ...gStyle.pH2, 123 | ...gStyle.pV1, 124 | backgroundColor: colors.black 125 | }, 126 | btnText: { 127 | color: colors.white 128 | } 129 | }); 130 | 131 | export default Home; 132 | -------------------------------------------------------------------------------- /src/constants/globalStyles.js: -------------------------------------------------------------------------------- 1 | import colors from './colors'; 2 | 3 | // space grid, some use 8pt grid, some 5pt, this is setting one place then done 4 | const spaceGrid = 8; 5 | 6 | export default { 7 | activeOpacity: 0.7, 8 | container: { 9 | backgroundColor: colors.black, 10 | flex: 1 11 | }, 12 | 13 | // flex 14 | // /////////////////////////////////////////////////////////////////////////// 15 | flexCenter: { 16 | alignItems: 'center', 17 | justifyContent: 'center' 18 | }, 19 | flexRow: { 20 | flexDirection: 'row' 21 | }, 22 | flexRowCenterAlign: { 23 | alignItems: 'center', 24 | flexDirection: 'row' 25 | }, 26 | flexRowCenter: { 27 | alignItems: 'center', 28 | flexDirection: 'row', 29 | justifyContent: 'center' 30 | }, 31 | flexRowSpace: { 32 | alignItems: 'center', 33 | flexDirection: 'row', 34 | justifyContent: 'space-between' 35 | }, 36 | flex1: { flex: 1 }, 37 | flex2: { flex: 2 }, 38 | flex3: { flex: 3 }, 39 | flex4: { flex: 4 }, 40 | flex5: { flex: 5 }, 41 | 42 | // navigation styles 43 | // /////////////////////////////////////////////////////////////////////////// 44 | navHeaderStyle: { 45 | backgroundColor: colors.black, 46 | borderBottomWidth: 0, 47 | elevation: 0 48 | }, 49 | 50 | // spacers 51 | // /////////////////////////////////////////////////////////////////////////// 52 | spacer1: { height: spaceGrid * 1 }, 53 | spacer2: { height: spaceGrid * 2 }, 54 | spacer3: { height: spaceGrid * 3 }, 55 | spacer4: { height: spaceGrid * 3 }, 56 | spacer6: { height: spaceGrid * 6 }, 57 | spacer8: { height: spaceGrid * 8 }, 58 | spacer11: { height: spaceGrid * 11 }, 59 | spacer16: { height: spaceGrid * 16 }, 60 | spacer24: { height: spaceGrid * 24 }, 61 | spacer48: { height: spaceGrid * 48 }, 62 | spacer64: { height: spaceGrid * 64 }, 63 | spacer88: { height: spaceGrid * 88 }, 64 | spacer128: { height: spaceGrid * 128 }, 65 | 66 | // margins 67 | // /////////////////////////////////////////////////////////////////////////// 68 | 69 | mB1: { marginBottom: spaceGrid }, 70 | mB2: { marginBottom: spaceGrid * 2 }, 71 | mB3: { marginBottom: spaceGrid * 3 }, 72 | mB4: { marginBottom: spaceGrid * 4 }, 73 | mB8: { marginBottom: spaceGrid * 8 }, 74 | mB22: { marginBottom: spaceGrid * 24 }, 75 | 76 | mL1: { marginLeft: spaceGrid }, 77 | mL2: { marginLeft: spaceGrid * 2 }, 78 | mL3: { marginLeft: spaceGrid * 3 }, 79 | mL4: { marginLeft: spaceGrid * 4 }, 80 | 81 | mR1: { marginRight: spaceGrid }, 82 | mR2: { marginRight: spaceGrid * 2 }, 83 | mR3: { marginRight: spaceGrid * 3 }, 84 | mR4: { marginRight: spaceGrid * 4 }, 85 | mR8: { marginRight: spaceGrid * 8 }, 86 | mR16: { marginRight: spaceGrid * 16 }, 87 | mR24: { marginRight: spaceGrid * 24 }, 88 | mR48: { marginRight: spaceGrid * 48 }, 89 | mR64: { marginRight: spaceGrid * 64 }, 90 | 91 | mTHalf: { marginTop: spaceGrid / 2 }, 92 | mT1: { marginTop: spaceGrid }, 93 | mT2: { marginTop: spaceGrid * 2 }, 94 | mT3: { marginTop: spaceGrid * 3 }, 95 | mT4: { marginTop: spaceGrid * 4 }, 96 | mT8: { marginTop: spaceGrid * 8 }, 97 | mT16: { marginTop: spaceGrid * 16 }, 98 | 99 | mH1: { marginHorizontal: spaceGrid * 1 }, 100 | mH2: { marginHorizontal: spaceGrid * 2 }, 101 | mH3: { marginHorizontal: spaceGrid * 3 }, 102 | mH4: { marginHorizontal: spaceGrid * 4 }, 103 | mH24: { marginHorizontal: spaceGrid * 24 }, 104 | 105 | mV1: { marginVertical: spaceGrid * 1 }, 106 | mV2: { marginVertical: spaceGrid * 2 }, 107 | mV3: { marginVertical: spaceGrid * 3 }, 108 | mV4: { marginVertical: spaceGrid * 4 }, 109 | mV16: { marginVertical: spaceGrid * 16 }, 110 | mV24: { marginVertical: spaceGrid * 24 }, 111 | mV32: { marginVertical: spaceGrid * 32 }, 112 | 113 | // paddings 114 | // /////////////////////////////////////////////////////////////////////////// 115 | pHalf: { padding: spaceGrid / 2 }, 116 | p1: { padding: spaceGrid }, 117 | p2: { padding: spaceGrid * 2 }, 118 | p3: { padding: spaceGrid * 3 }, 119 | 120 | pB1: { paddingBottom: spaceGrid }, 121 | pB2: { paddingBottom: spaceGrid * 2 }, 122 | pB3: { paddingBottom: spaceGrid * 3 }, 123 | 124 | pL1: { paddingLeft: spaceGrid }, 125 | pL2: { paddingLeft: spaceGrid * 2 }, 126 | pL3: { paddingLeft: spaceGrid * 3 }, 127 | 128 | pR1: { paddingRight: spaceGrid }, 129 | pR2: { paddingRight: spaceGrid * 2 }, 130 | pR3: { paddingRight: spaceGrid * 3 }, 131 | 132 | pT1: { paddingTop: spaceGrid }, 133 | pT2: { paddingTop: spaceGrid * 2 }, 134 | pT3: { paddingTop: spaceGrid * 3 }, 135 | 136 | pHHalf: { paddingHorizontal: spaceGrid / 2 }, 137 | pH1: { paddingHorizontal: spaceGrid }, 138 | pH2: { paddingHorizontal: spaceGrid * 2 }, 139 | pH3: { paddingHorizontal: spaceGrid * 3 }, 140 | 141 | pV1: { paddingVertical: spaceGrid } 142 | }; 143 | --------------------------------------------------------------------------------