├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── node.js.yml ├── .gitignore ├── .prettierrc.js ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cli.js ├── cli.test.js ├── cliError.test.js ├── package-lock.json ├── package.json └── react-router ├── App.js ├── pages ├── Home.js ├── ReactRouter.js └── reactRouterLogo.js └── router ├── index.js ├── router.android.js ├── router.ios.js ├── router.js └── router.web.js /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [8.x, 10.x, 12.x, 14.x] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v1 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | - run: npm i 28 | - run: npm run build --if-present 29 | - run: npm test 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | 24 | # ========================================== 25 | # OSX 26 | # 27 | .DS_Store 28 | 29 | # Xcode 30 | # 31 | *.pbxuser 32 | !default.pbxuser 33 | *.mode1v3 34 | !default.mode1v3 35 | *.mode2v3 36 | !default.mode2v3 37 | *.perspectivev3 38 | !default.perspectivev3 39 | xcuserdata 40 | *.xccheckout 41 | *.moved-aside 42 | DerivedData 43 | *.hmap 44 | *.ipa 45 | *.xcuserstate 46 | project.xcworkspace 47 | 48 | # Android/IntelliJ 49 | # 50 | build/ 51 | .idea 52 | .gradle 53 | local.properties 54 | *.iml 55 | 56 | # node.js 57 | # 58 | node_modules/ 59 | npm-debug.log 60 | npm-debug.log* 61 | yarn-error.log 62 | 63 | # BUCK 64 | buck-out/ 65 | \.buckd/ 66 | *.keystore 67 | 68 | # fastlane 69 | # 70 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 71 | # screenshots whenever they are needed. 72 | # For more information about the recommended setup visit: 73 | # https://docs.fastlane.tools/best-practices/source-control/ 74 | 75 | */fastlane/report.xml 76 | */fastlane/Preview.html 77 | */fastlane/screenshots 78 | 79 | coverage/ 80 | coverageNative/ 81 | build/ 82 | temp.json 83 | android/app/app-release.apk 84 | .vscode 85 | ======= 86 | # Bundle artifact 87 | *.jsbundle 88 | 89 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 90 | 91 | # dependencies 92 | /node_modules 93 | /.pnp 94 | .pnp.js 95 | 96 | # testing 97 | /coverage 98 | 99 | # production 100 | /build 101 | 102 | # misc 103 | .DS_Store 104 | .env.local 105 | .env.development.local 106 | .env.test.local 107 | .env.production.local 108 | 109 | npm-debug.log* 110 | yarn-debug.log* 111 | yarn-error.log* 112 | 113 | # OSX 114 | # 115 | .DS_Store 116 | 117 | # Xcode 118 | # 119 | build/ 120 | *.pbxuser 121 | !default.pbxuser 122 | *.mode1v3 123 | !default.mode1v3 124 | *.mode2v3 125 | !default.mode2v3 126 | *.perspectivev3 127 | !default.perspectivev3 128 | xcuserdata 129 | *.xccheckout 130 | *.moved-aside 131 | DerivedData 132 | *.hmap 133 | *.ipa 134 | *.xcuserstate 135 | 136 | # Android/IntelliJ 137 | # 138 | build/ 139 | .idea 140 | .gradle 141 | local.properties 142 | *.iml 143 | 144 | # node.js 145 | # 146 | node_modules/ 147 | npm-debug.log 148 | yarn-error.log 149 | 150 | # BUCK 151 | buck-out/ 152 | \.buckd/ 153 | *.keystore 154 | !debug.keystore 155 | 156 | # fastlane 157 | # 158 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 159 | # screenshots whenever they are needed. 160 | # For more information about the recommended setup visit: 161 | # https://docs.fastlane.tools/best-practices/source-control/ 162 | 163 | */fastlane/report.xml 164 | */fastlane/Preview.html 165 | */fastlane/screenshots 166 | 167 | # Bundle artifact 168 | *.jsbundle 169 | 170 | # CocoaPods 171 | /template/ios/Pods/ 172 | 173 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Create an Issue and if the feature/bug is really needed and approved, create a PR :) 2 | 3 | more to come... 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Or Yoffe 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 | [![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) 2 | 3 | ## Warning: Project is not actively maintained 4 | # React Native Web CLI 5 | 6 | ### create-react-native-web-app 7 | 8 | [![NPM](https://nodei.co/npm/create-react-native-web-app.png)](https://npmjs.org/package/create-react-native-web-app) 9 | 10 | ![GitHub issues](https://img.shields.io/github/issues/orYoffe/create-react-native-web-app.svg) 11 | ![license](https://img.shields.io/github/license/orYoffe/create-react-native-web-app.svg) 12 | ![GitHub top language](https://img.shields.io/github/languages/top/orYoffe/create-react-native-web-app.svg) 13 | ![npm](https://img.shields.io/npm/v/create-react-native-web-app.svg) 14 | 15 | ### A simple CLI tool to start your React Native Web project to develop same app for IOS Android and Web 16 | 17 | **Compatibility: React Native >= 0.63**. 18 | 19 |

20 | 21 |

22 | 23 | ## Installation 24 | 25 | ```sh 26 | # Run create-react-native-web-app 27 | $ npx crnwa myApp 28 | # or 29 | $ npx create-react-native-web-app myApp 30 | 31 | # if you previously installed this package globaly run this command first to uninstall the previous version: 32 | # npm uninstall -g create-react-native-web-app 33 | 34 | # cd into your 35 | $ cd myApp 36 | 37 | # Run Web/Ios/Android development 38 | # Web 39 | $ npm run web 40 | 41 | # IOS 42 | $ npm run ios 43 | 44 | # Android 45 | $ npm run android 46 | 47 | ``` 48 | 49 | - To work with IOS and Android - Install Xcode and Android studio and follow the react native instructions [under the "React Native CLI Quickstart" tab](https://reactnative.dev/docs/environment-setup) 50 | 51 | ## Folder structure 52 | 53 | ``` 54 | myApp 55 | ├── android (When opening with Android studio, open this folder) 56 | │ └── android project files 57 | ├── ios (When opening with Xcode, open this folder) 58 | │ └── ios project files 59 | ├── public 60 | │ ├── favicon.ico 61 | │ ├── index.html 62 | │ └── manifest.json 63 | └── src 64 | └── project code 65 | ``` 66 | 67 | ## Testing 68 | 69 | ```sh 70 | # Web and Native 71 | $ npm run test 72 | 73 | # Web 74 | $ npm run test:web 75 | 76 | # Native 77 | $ npm run test:native 78 | ``` 79 | 80 | ## Debugging 81 | 82 | Open dev menu: 83 | 84 | 1. CMD+D (IOS) / CMD+M (Android) 85 | 2. Press "Enable Live-Reload" 86 | 87 | [React native docs - debugging real devices guide](http://facebook.github.io/react-native/releases/0.49/docs/running-on-device.html) 88 | 89 | [React native docs - debugging guide](http://facebook.github.io/react-native/docs/debugging.html) 90 | 91 | [Network calls in the devtools](http://www.preslav.me/2017/03/26/debugging-network-calls-in-react-native-using-the-chrome-debugger/) 92 | 93 | ## Build 94 | 95 | ```sh 96 | # Web 97 | $ npm run build 98 | 99 | # Android - upgrade the current build version in `android/app/build.gradle` file (both the `versionCode` and the `versionName`) 100 | Example: 101 | versionCode 2 102 | versionName "1.1" 103 | 104 | # And then run the build 105 | $ cd android && ./gradlew assembleRelease 106 | 107 | # Open apk folder to find the release apk 108 | $ open ./android/app/build/outputs/apk 109 | ``` 110 | 111 | [React native docs - Android signed apk](http://facebook.github.io/react-native/releases/0.49/docs/signed-apk-android.html) 112 | 113 | [React native docs for IOS](http://facebook.github.io/react-native/releases/0.49/docs/running-on-device.html#building-your-app-for-production) 114 | 115 | ## Resources 116 | 117 | - [React Native for Web (react-native-web)](https://github.com/necolas/react-native-web) 118 | - [React](https://reactjs.org/) 119 | - [React Native](http://facebook.github.io/react-native/) 120 | - [Create React App](https://github.com/facebook/create-react-app) 121 | - [Create React Native App](https://github.com/react-community/create-react-native-app) 122 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const chalk = require('chalk'); 4 | const commander = require('commander'); 5 | // const fs = require('fs-extra'); 6 | // const path = require('path'); 7 | const execSync = require('child_process').execSync; 8 | const packageJson = require('./package.json'); 9 | // const copyFiles = require('./copyFiles'); 10 | 11 | const nodeVersion = process.versions.node; 12 | const nodeVersionSplitted = nodeVersion.split('.'); 13 | const nodeMajorVersion = nodeVersionSplitted[0]; 14 | 15 | if (nodeMajorVersion < 8) { 16 | console.error( 17 | chalk.red(` 18 | You are running Node ${nodeVersion} 19 | Create React Native Web App requires Node 8 or higher. 20 | Please update your version of Node. 21 | `), 22 | ); 23 | process.exit(1); 24 | } 25 | 26 | const printCyan = (text) => console.log(` ${chalk.cyan(text)}`); 27 | // const printGreen = (text) => console.log(` ${chalk.green(text)}`); 28 | 29 | let appName; 30 | const program = new commander.Command(packageJson.name) 31 | .version(packageJson.version) 32 | .arguments('') 33 | .option('-r, --router') 34 | .usage(`${chalk.green('')}`) 35 | .action((name) => { 36 | appName = name; 37 | }) 38 | .on('--help', () => { 39 | console.log(` ${chalk.green('')} is required.`); 40 | console.log(); 41 | console.log( 42 | ` If you have any problems, do not hesitate to file an issue:`, 43 | ); 44 | printCyan( 45 | 'https://github.com/orYoffe/create-react-native-web-app/issues/new', 46 | ); 47 | console.log(); 48 | }) 49 | .parse(process.argv); 50 | 51 | async function run() { 52 | if (appName) { 53 | printCyan(`⏳ Creating React Native Web App by the name of ${appName}`); 54 | console.log(); 55 | 56 | execSync( 57 | `npx react-native init ${appName} --template react-native-template-react-native-web`, 58 | {stdio: [0, 1, 2]}, 59 | ); 60 | 61 | let isYarnAvailable; 62 | try { 63 | execSync('yarnpkg --version', {stdio: 'ignore'}); 64 | isYarnAvailable = true; 65 | } catch (e) { 66 | isYarnAvailable = false; 67 | } 68 | 69 | try { 70 | execSync(`cd ${appName} && git init`); 71 | } catch (error) {} 72 | 73 | const packageManagerRunCommand = isYarnAvailable ? 'yarn' : 'npm run'; 74 | console.log(` 75 | ${chalk.magenta('*')} ${chalk.magenta( 76 | 'change directory to your new project', 77 | )} 78 | $ ${chalk.cyan(`cd ${appName}`)} 79 | 80 | $ ${chalk.cyan('Then run the these commands to get started:')} 81 | 82 | ${chalk.magenta('*')} ${chalk.magenta('To run development Web server')} 83 | $ ${chalk.cyan(packageManagerRunCommand + ' web')} 84 | 85 | ${chalk.magenta('*')} ${chalk.magenta( 86 | 'To run Android on connected device (after installing Android Debug Bridge "adb" - https://developer.android.com/studio/releases/platform-tools)', 87 | )} 88 | $ ${chalk.cyan(packageManagerRunCommand + ' android')} 89 | 90 | ${chalk.magenta('*')} ${chalk.magenta( 91 | 'To run ios simulator (after installing Xcode - only on Apple devices)', 92 | )} 93 | $ ${chalk.cyan(packageManagerRunCommand + ' ios')} 94 | 95 | ${chalk.magenta('*')} ${chalk.magenta( 96 | 'To run tests for Native and Web', 97 | )} 98 | $ ${chalk.cyan(packageManagerRunCommand + ' test')} 99 | 100 | ${chalk.magenta('*')} ${chalk.magenta('To run build for Web')} 101 | $ ${chalk.cyan(packageManagerRunCommand + ' build')} 102 | `); 103 | } else { 104 | console.error( 105 | chalk.red( 106 | 'In order to create a new project you must give a name as an argument. ', 107 | ), 108 | chalk.cyan('Example: create-react-native-web-app AppName'), 109 | ); 110 | process.exit(1); 111 | } 112 | } 113 | 114 | try { 115 | run(); 116 | } catch (error) { 117 | console.error(error); 118 | } 119 | -------------------------------------------------------------------------------- /cli.test.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | const execSync = require('child_process').execSync; 3 | 4 | const originalConsoleLog = console.log; 5 | console.log = jest.fn(() => true); 6 | 7 | const originalConsoleError = console.error; 8 | console.error = jest.fn(); 9 | 10 | jest.mock('child_process', () => { 11 | const execSync = jest.fn(); 12 | 13 | return {execSync}; 14 | }); 15 | 16 | jest.mock('chalk', () => { 17 | const red = jest.fn((text) => text); 18 | const cyan = jest.fn((text) => text); 19 | const green = jest.fn((text) => text); 20 | const magenta = jest.fn((text) => text); 21 | 22 | return { 23 | red, 24 | cyan, 25 | green, 26 | magenta, 27 | }; 28 | }); 29 | 30 | describe('cli runs properly', () => { 31 | it('cli runs with argument and logs info', (done) => { 32 | process.argv[2] = 'myFakeName'; 33 | jest.requireActual('./cli'); 34 | 35 | let isYarnAvailable; 36 | try { 37 | execSync('yarnpkg --version', {stdio: 'ignore'}); 38 | isYarnAvailable = true; 39 | } catch (e) { 40 | isYarnAvailable = false; 41 | } 42 | 43 | const packageManagerRunCommand = isYarnAvailable ? 'yarn' : 'npm run'; 44 | process.nextTick(() => { 45 | expect(chalk.red.mock.calls).toEqual([]); 46 | expect(chalk.cyan.mock.calls).toEqual([ 47 | ['⏳ Creating React Native Web App by the name of myFakeName'], 48 | ['cd myFakeName'], 49 | ['Then run the these commands to get started:'], 50 | [`${packageManagerRunCommand} web`], 51 | [`${packageManagerRunCommand} android`], 52 | [`${packageManagerRunCommand} ios`], 53 | [`${packageManagerRunCommand} test`], 54 | [`${packageManagerRunCommand} build`], 55 | ]); 56 | expect(chalk.green.mock.calls).toEqual([['']]); 57 | expect(chalk.magenta.mock.calls).toEqual([ 58 | ['*'], 59 | ['change directory to your new project'], 60 | ['*'], 61 | ['To run development Web server'], 62 | ['*'], 63 | [ 64 | 'To run Android on connected device (after installing Android Debug Bridge "adb" - https://developer.android.com/studio/releases/platform-tools)', 65 | ], 66 | ['*'], 67 | [ 68 | 'To run ios simulator (after installing Xcode - only on Apple devices)', 69 | ], 70 | ['*'], 71 | ['To run tests for Native and Web'], 72 | ['*'], 73 | ['To run build for Web'], 74 | ]); 75 | 76 | expect(execSync.mock.calls).toEqual([ 77 | [ 78 | 'npx react-native init myFakeName --template react-native-template-react-native-web', 79 | {stdio: [0, 1, 2]}, 80 | ], 81 | ['yarnpkg --version', {stdio: 'ignore'}], 82 | ['cd myFakeName && git init'], 83 | ['yarnpkg --version', {stdio: 'ignore'}], 84 | ]); 85 | }); 86 | done(); 87 | }); 88 | }); 89 | -------------------------------------------------------------------------------- /cliError.test.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | const commander = require('commander'); 3 | const path = require('path'); 4 | const execSync = require('child_process').execSync; 5 | const packageJson = require('./package.json'); 6 | 7 | const originalConsoleLog = console.log; 8 | console.log = jest.fn(); 9 | 10 | const originalConsoleError = console.error; 11 | console.error = jest.fn(); 12 | 13 | jest.mock('child_process', () => { 14 | const execSync = jest.fn(); 15 | 16 | return { execSync }; 17 | }); 18 | 19 | jest.mock('chalk', () => { 20 | const red = jest.fn(text => text); 21 | const cyan = jest.fn(text => text); 22 | const green = jest.fn(text => text); 23 | const magenta = jest.fn(text => text); 24 | 25 | return { 26 | red, 27 | cyan, 28 | green, 29 | magenta, 30 | }; 31 | }); 32 | 33 | describe('cli shows error', () => { 34 | it('cli runs without arguments', () => { 35 | const originalProcessExit = process.exit; 36 | process.exit = jest.fn(); 37 | process.argv[2] = ''; 38 | require('./cli'); 39 | 40 | 41 | expect(console.error.mock.calls).toEqual([['In order to create a new project you must give a name as an argument. ', 'Example: create-react-native-web-app AppName']]); 42 | expect(process.exit.mock.calls).toEqual([[1]]); 43 | process.exit = originalProcessExit; 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-native-web-app", 3 | "version": "0.16.4", 4 | "description": "React Native Web CLI", 5 | "main": "cli.js", 6 | "scripts": { 7 | "start": "node cli.js", 8 | "test": "jest", 9 | "test-watch": "jest --watch", 10 | "precommit": "npm run test" 11 | }, 12 | "engines": { 13 | "node": ">=8" 14 | }, 15 | "bin": { 16 | "create-react-native-web-app": "cli.js" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/orYoffe/create-react-native-web-app.git" 21 | }, 22 | "keywords": [ 23 | "react", 24 | "native", 25 | "web", 26 | "ios", 27 | "android", 28 | "react-native", 29 | "react-native-web", 30 | "CLI" 31 | ], 32 | "author": { 33 | "name": "Or Yoffe", 34 | "url": "https://github.com/orYoffe" 35 | }, 36 | "license": "MIT", 37 | "bugs": { 38 | "url": "https://github.com/orYoffe/create-react-native-web-app/issues" 39 | }, 40 | "homepage": "https://github.com/orYoffe/create-react-native-web-app#readme", 41 | "devDependencies": { 42 | "husky": "^0.14.3", 43 | "jest": "^23.1.0" 44 | }, 45 | "dependencies": { 46 | "chalk": "^3.0.0", 47 | "commander": "^2.15.1", 48 | "react-native-template-react-native-web": "*" 49 | }, 50 | "jest": { 51 | "testEnvironment": "node", 52 | "testPathIgnorePatterns": [ 53 | "./node_modules/" 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /react-router/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Home from './pages/Home'; 3 | import ReactRouter from './pages/ReactRouter'; 4 | import {Router, Route, Switch} from './router'; 5 | 6 | const App = () => { 7 | return ( 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /react-router/pages/Home.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { 3 | StyleSheet, 4 | Text, 5 | View, 6 | Platform, 7 | TouchableHighlight, 8 | Animated, 9 | Easing, 10 | } from 'react-native'; 11 | import {Link} from '../router'; 12 | import logo from '../logo.png'; 13 | 14 | class Home extends Component { 15 | state = { 16 | spinValue: new Animated.Value(0), 17 | }; 18 | 19 | onClick = () => { 20 | const wasRotated = this.state.spinValue._value === 1; 21 | Animated.timing(this.state.spinValue, { 22 | toValue: wasRotated ? 0 : 1, 23 | duration: 250, 24 | easing: Easing.linear, 25 | }).start(); 26 | }; 27 | 28 | render() { 29 | const spin = this.state.spinValue.interpolate({ 30 | inputRange: [0, 1], 31 | outputRange: ['0deg', '360deg'], 32 | }); 33 | 34 | return ( 35 | 36 | 37 | 38 | To router route 39 | 40 | 41 | 45 | Create React Native Web App 46 | 47 | Open up src/App.js to start working on your app! 48 | 49 | 50 | Changes you make will automatically reload. 51 | 52 | {Platform.OS !== 'web' && ( 53 | 54 | Shake your phone to open the developer menu. 55 | 56 | )} 57 | 61 | Rotate Logo 62 | 63 | 64 | ); 65 | } 66 | } 67 | 68 | const styles = StyleSheet.create({ 69 | container: { 70 | flex: 1, 71 | backgroundColor: '#282c34', 72 | alignItems: 'center', 73 | justifyContent: 'center', 74 | }, 75 | logo: { 76 | width: 300, 77 | height: 300, 78 | }, 79 | title: { 80 | color: '#fff', 81 | fontWeight: 'bold', 82 | fontSize: 16, 83 | }, 84 | text: { 85 | color: '#fff', 86 | }, 87 | button: { 88 | borderRadius: 3, 89 | padding: 20, 90 | marginVertical: 10, 91 | marginTop: 10, 92 | backgroundColor: '#1B95E0', 93 | }, 94 | buttonText: { 95 | color: '#fff', 96 | fontWeight: 'bold', 97 | fontSize: 16, 98 | }, 99 | }); 100 | 101 | export default Home; 102 | -------------------------------------------------------------------------------- /react-router/pages/ReactRouter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Text, View, Image, Platform, Linking} from 'react-native'; 3 | import {Link} from '../router'; 4 | import logo from './reactRouterLogo'; 5 | 6 | const url = 'https://reacttraining.com/react-router/native/guides/quick-start'; 7 | const openLink = () => 8 | Linking.canOpenURL(url).then((supported) => { 9 | return Linking.openURL(url); 10 | }); 11 | 12 | const linkProps = 13 | Platform.OS === 'web' 14 | ? { 15 | accessibilityRole: 'link', 16 | target: '_blank', 17 | href: url, 18 | } 19 | : {onPress: openLink}; 20 | 21 | const ReactRouter = () => { 22 | return ( 23 | 24 | 25 | To to main page 26 | 27 | 33 | 34 | Go to react-router docs 35 | 36 | 37 | ); 38 | }; 39 | 40 | const styles = StyleSheet.create({ 41 | container: { 42 | flex: 1, 43 | backgroundColor: '#282c34', 44 | alignItems: 'center', 45 | justifyContent: 'center', 46 | }, 47 | title: { 48 | color: '#fff', 49 | fontWeight: 'bold', 50 | fontSize: 16, 51 | }, 52 | logo: { 53 | width: 300, 54 | height: 300, 55 | }, 56 | button: { 57 | borderRadius: 3, 58 | padding: 20, 59 | marginVertical: 10, 60 | marginTop: 10, 61 | backgroundColor: '#1B95E0', 62 | }, 63 | buttonText: { 64 | color: '#fff', 65 | fontWeight: 'bold', 66 | fontSize: 16, 67 | }, 68 | }); 69 | 70 | export default ReactRouter; 71 | -------------------------------------------------------------------------------- /react-router/pages/reactRouterLogo.js: -------------------------------------------------------------------------------- 1 | const logo = 2 | 'data:image/png;base64,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'; 3 | 4 | export default logo; 5 | -------------------------------------------------------------------------------- /react-router/router/index.js: -------------------------------------------------------------------------------- 1 | export { 2 | Router, 3 | Switch, 4 | Route, 5 | Link, 6 | Redirect 7 | } from './router'; 8 | -------------------------------------------------------------------------------- /react-router/router/router.android.js: -------------------------------------------------------------------------------- 1 | export { 2 | NativeRouter as Router, 3 | Switch, 4 | Route, 5 | Link, 6 | Redirect 7 | } from "react-router-native"; 8 | -------------------------------------------------------------------------------- /react-router/router/router.ios.js: -------------------------------------------------------------------------------- 1 | export { 2 | NativeRouter as Router, 3 | Switch, 4 | Route, 5 | Link, 6 | Redirect 7 | } from "react-router-native"; -------------------------------------------------------------------------------- /react-router/router/router.js: -------------------------------------------------------------------------------- 1 | export { 2 | BrowserRouter as Router, 3 | Switch, 4 | Route, 5 | Link, 6 | Redirect 7 | } from "react-router-dom"; -------------------------------------------------------------------------------- /react-router/router/router.web.js: -------------------------------------------------------------------------------- 1 | export { 2 | BrowserRouter as Router, 3 | Switch, 4 | Route, 5 | Link, 6 | Redirect 7 | } from "react-router-dom"; --------------------------------------------------------------------------------