├── examples ├── redux │ ├── .watchmanconfig │ ├── .gitattributes │ ├── android │ │ ├── settings.gradle │ │ ├── .settings │ │ │ └── org.eclipse.buildship.core.prefs │ │ ├── app │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── rnrfreduxsample │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── proguard-rules.pro │ │ │ └── BUCK │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── keystores │ │ │ ├── debug.keystore.properties │ │ │ └── BUCK │ │ ├── .project │ │ ├── gradle.properties │ │ ├── build.gradle │ │ └── gradlew.bat │ ├── app.json │ ├── ios │ │ ├── rnrfReduxSample │ │ │ ├── Images.xcassets │ │ │ │ ├── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ ├── AppDelegate.h │ │ │ ├── main.m │ │ │ ├── AppDelegate.m │ │ │ ├── Info.plist │ │ │ └── Base.lproj │ │ │ │ └── LaunchScreen.xib │ │ ├── rnrfReduxSampleTests │ │ │ ├── Info.plist │ │ │ └── rnrfReduxSampleTests.m │ │ ├── rnrfReduxSample-tvOSTests │ │ │ └── Info.plist │ │ └── rnrfReduxSample-tvOS │ │ │ └── Info.plist │ ├── .buckconfig │ ├── index.ios.js │ ├── index.android.js │ ├── babel.config.js │ ├── readme.md │ ├── src │ │ ├── a-reducer.js │ │ ├── home.js │ │ ├── app.js │ │ └── page.js │ ├── .gitignore │ ├── .flowconfig │ └── package.json ├── expo │ ├── .watchmanconfig │ ├── .gitignore │ ├── .eslintrc │ ├── assets │ │ ├── images │ │ │ ├── icon.png │ │ │ ├── splash.png │ │ │ ├── robot-dev.png │ │ │ └── robot-prod.png │ │ └── fonts │ │ │ └── SpaceMono-Regular.ttf │ ├── .prettierrc │ ├── .babelrc │ ├── constants │ │ ├── Layout.js │ │ └── Colors.js │ ├── components │ │ ├── MenuIcon.js │ │ ├── StyledText.js │ │ ├── __tests__ │ │ │ └── StyledText-test.js │ │ ├── TabBarIcon.js │ │ └── DrawerContent.js │ ├── screens │ │ ├── SettingsScreen.js │ │ └── LinksScreen.js │ ├── app.json │ ├── __tests__ │ │ └── App-test.js │ ├── package.json │ ├── App.js │ └── navigation │ │ └── AppNavigator.js └── react-native │ ├── .watchmanconfig │ ├── .gitattributes │ ├── app.json │ ├── .eslintrc.js │ ├── babel.config.js │ ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ └── AndroidManifest.xml │ │ │ └── debug │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── ReactNativeFlipper.java │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ ├── build_defs.bzl │ │ └── BUCK │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ ├── build.gradle │ ├── gradle.properties │ └── gradlew.bat │ ├── ios │ ├── Example │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── AppDelegate.h │ │ ├── main.m │ │ ├── Info.plist │ │ ├── AppDelegate.m │ │ └── Base.lproj │ │ │ └── LaunchScreen.xib │ ├── Example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── ExampleTests │ │ ├── Info.plist │ │ └── ExampleTests.m │ ├── Example-tvOSTests │ │ └── Info.plist │ ├── Podfile │ ├── Example-tvOS │ │ └── Info.plist │ └── Example.xcodeproj │ │ └── xcshareddata │ │ └── xcschemes │ │ ├── Example.xcscheme │ │ └── Example-tvOS.xcscheme │ ├── images │ ├── back_chevron.png │ └── menu_burger.png │ ├── .buckconfig │ ├── .prettierrc.js │ ├── index.js │ ├── __tests__ │ └── App-test.js │ ├── metro.config.js │ ├── .npmignore │ ├── components │ ├── lightbox │ │ ├── DemoLightbox.js │ │ └── BaseLightbox.js │ ├── TabIcon.js │ ├── MessageBar.js │ ├── modal │ │ ├── ErrorModal.js │ │ └── BaseModal.js │ ├── Register.js │ ├── Home.js │ ├── Login2.js │ ├── EchoView.js │ ├── CustomNavBar2.js │ ├── Login3.js │ ├── Login.js │ ├── Error.js │ ├── CustomNavBarView.js │ ├── Launch.js │ ├── drawer │ │ └── DrawerContent.js │ ├── CustomNavBar.js │ └── TabView.js │ ├── .gitignore │ ├── package.json │ └── .flowconfig ├── src ├── .watchmanconfig ├── defaultStore.js ├── Drawer.js ├── Lightbox.js ├── Modal.js ├── Overlay.js ├── Scene.js ├── Stack.js ├── Tabs.js ├── LegacyTabs.js ├── createTabNavigatorHOC.js ├── createStackNavigatorHOC.js ├── index.js ├── LightboxRenderer.js ├── ActionConst.js ├── OverlayRenderer.js ├── Util.js ├── Reducer.js ├── State.js └── pathParser.js ├── .babelrc.js ├── .npmignore ├── docs ├── assets │ └── css │ │ └── style.scss ├── v3 │ ├── super_simple.gif │ ├── MIGRATION.md │ ├── MINI_TUTORIAL.md │ └── DETAILED_EXAMPLE.md ├── _config.yml ├── CHANGELOG.md ├── MIGRATION.md ├── _layouts │ └── default.html └── index.md ├── packages └── react-native-router-flux-cli │ ├── README.md │ ├── package.json │ ├── index.js │ └── yarn.lock ├── images ├── menu_burger.png └── back_chevron.png ├── .github_changelog_generator ├── .codeclimate.yml ├── .prettierrc ├── babel.config.js ├── .editorconfig ├── .gitignore ├── .circleci └── config.yml ├── LICENSE ├── __tests__ └── scenes.test.js ├── .travis.yml ├── .eslintrc.js ├── .github └── ISSUE_TEMPLATE.md ├── test └── setup.js ├── package.json └── CONTRIBUTING.md /examples/redux/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /examples/expo/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/react-native/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/redux/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /examples/react-native/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /src/.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": [] 3 | } 4 | -------------------------------------------------------------------------------- /examples/expo/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/**/* 3 | -------------------------------------------------------------------------------- /examples/expo/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "universe/native" 3 | } 4 | -------------------------------------------------------------------------------- /.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "./babel.config.js" 3 | }; 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Example/ 2 | ReduxExample/ 3 | .idea/ 4 | examples/ 5 | .babelrc 6 | -------------------------------------------------------------------------------- /docs/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import "{{ site.theme }}"; 5 | -------------------------------------------------------------------------------- /packages/react-native-router-flux-cli/README.md: -------------------------------------------------------------------------------- 1 | # React Native Router Flux CLI tools 2 | -------------------------------------------------------------------------------- /examples/react-native/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example", 3 | "displayName": "Example" 4 | } 5 | -------------------------------------------------------------------------------- /examples/redux/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'rnrfReduxSample' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /examples/redux/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "displayName": "RNRF Redux Sample", 3 | "name": "rnrfReduxSample" 4 | } -------------------------------------------------------------------------------- /images/menu_burger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/images/menu_burger.png -------------------------------------------------------------------------------- /docs/v3/super_simple.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/docs/v3/super_simple.gif -------------------------------------------------------------------------------- /images/back_chevron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/images/back_chevron.png -------------------------------------------------------------------------------- /examples/react-native/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /examples/react-native/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/redux/android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /.github_changelog_generator: -------------------------------------------------------------------------------- 1 | unreleased=true 2 | since-tag=4.0.0-beta.23 3 | exclude-labels=for stack overflow,invalid,wontfix 4 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal 2 | title: React Native Router 3 | description: Simple, minimal routing for React Native 4 | -------------------------------------------------------------------------------- /examples/expo/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/expo/assets/images/icon.png -------------------------------------------------------------------------------- /examples/expo/assets/images/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/expo/assets/images/splash.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Example 3 | 4 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | eslint: 3 | enabled: true 4 | channel: "eslint-2" 5 | ratings: 6 | paths: 7 | - "**.js" 8 | exclude_paths: 9 | -------------------------------------------------------------------------------- /examples/expo/assets/images/robot-dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/expo/assets/images/robot-dev.png -------------------------------------------------------------------------------- /examples/expo/assets/images/robot-prod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/expo/assets/images/robot-prod.png -------------------------------------------------------------------------------- /examples/react-native/ios/Example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RNRF Redux Sample 3 | 4 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/defaultStore.js: -------------------------------------------------------------------------------- 1 | import NavigationStore from './Store'; 2 | 3 | const defaultStore = new NavigationStore(); 4 | 5 | export default defaultStore; 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 180, 3 | "singleQuote": true, 4 | "semi": true, 5 | "bracketSpacing": true, 6 | "trailingComma": "all" 7 | } 8 | -------------------------------------------------------------------------------- /examples/react-native/images/back_chevron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/images/back_chevron.png -------------------------------------------------------------------------------- /examples/react-native/images/menu_burger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/images/menu_burger.png -------------------------------------------------------------------------------- /examples/expo/assets/fonts/SpaceMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/expo/assets/fonts/SpaceMono-Regular.ttf -------------------------------------------------------------------------------- /examples/react-native/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/debug.keystore -------------------------------------------------------------------------------- /examples/redux/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /examples/expo/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "jsxBracketSameLine": true, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /examples/react-native/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /examples/redux/index.ios.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/app'; 3 | 4 | AppRegistry.registerComponent('rnrfReduxSample', () => App); -------------------------------------------------------------------------------- /examples/redux/index.android.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/app'; 3 | 4 | AppRegistry.registerComponent('rnrfReduxSample', () => App); -------------------------------------------------------------------------------- /examples/react-native/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /examples/redux/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/redux/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /examples/expo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["babel-preset-expo"], 3 | "env": { 4 | "development": { 5 | "plugins": ["transform-react-jsx-source"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/react-native/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "presets": [ 3 | "babel-preset-react-native" 4 | ], 5 | "plugins": [ 6 | ["@babel/plugin-proposal-decorators", { "legacy": true }] 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/redux/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | "babel-preset-react-native" 4 | ], 5 | plugins: [ 6 | ['@babel/plugin-proposal-decorators', { legacy: true }], 7 | ], 8 | }; 9 | -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/redux/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/redux/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aksonov/react-native-router-flux/HEAD/examples/react-native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/react-native/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Example' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | -------------------------------------------------------------------------------- /examples/react-native/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /examples/expo/constants/Layout.js: -------------------------------------------------------------------------------- 1 | import { Dimensions } from 'react-native'; 2 | 3 | const { width, height } = Dimensions.get('window'); 4 | 5 | export default { 6 | window: { 7 | width, 8 | height, 9 | }, 10 | isSmallDevice: width < 375, 11 | }; 12 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /examples/expo/components/MenuIcon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Icon } from 'expo'; 3 | 4 | export default class MenuIcon extends React.Component { 5 | render() { 6 | return ; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/redux/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.5.1-all.zip 6 | -------------------------------------------------------------------------------- /examples/react-native/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /examples/expo/components/StyledText.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Text } from 'react-native'; 3 | 4 | export class MonoText extends React.Component { 5 | render() { 6 | return ; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Drawer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /src/Lightbox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /src/Modal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /src/Overlay.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /src/Scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /src/Stack.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /src/Tabs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /src/LegacyTabs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Pavel Aksonov 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | */ 9 | export default () => null; 10 | -------------------------------------------------------------------------------- /examples/redux/readme.md: -------------------------------------------------------------------------------- 1 | # RNRF Sample project 2 | 3 | This project presents a bug in the current Redux integration of `react-native-router-flux` library. 4 | The project is *NOT* ment as a demonstration of the library's capabilities. 5 | 6 | [The library can be found here](https://github.com/aksonov/react-native-router-flux) 7 | 8 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/createTabNavigatorHOC.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { createNavigator, TabRouter } from 'react-navigation'; 4 | 5 | export default NavigationView => (routeConfigs, navigationConfig = {}) => { 6 | const router = TabRouter(routeConfigs, navigationConfig); 7 | return createNavigator(NavigationView, router, navigationConfig); 8 | }; 9 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/createStackNavigatorHOC.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { createNavigator, StackRouter } from 'react-navigation'; 4 | 5 | export default NavigationView => (routeConfigs, navigationConfig = {}) => { 6 | const router = StackRouter(routeConfigs, navigationConfig); 7 | return createNavigator(NavigationView, router, navigationConfig); 8 | }; 9 | -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/react-native/__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /examples/expo/components/__tests__/StyledText-test.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import { MonoText } from '../StyledText'; 4 | import renderer from 'react-test-renderer'; 5 | 6 | it('renders correctly', () => { 7 | const tree = renderer.create(Snapshot test!).toJSON(); 8 | 9 | expect(tree).toMatchSnapshot(); 10 | }); 11 | -------------------------------------------------------------------------------- /examples/expo/constants/Colors.js: -------------------------------------------------------------------------------- 1 | const tintColor = '#2f95dc'; 2 | 3 | export default { 4 | tintColor, 5 | tabIconDefault: '#ccc', 6 | tabIconSelected: tintColor, 7 | tabBar: '#fefefe', 8 | errorBackground: 'red', 9 | errorText: '#fff', 10 | warningBackground: '#EAEB5E', 11 | warningText: '#666804', 12 | noticeBackground: tintColor, 13 | noticeText: '#fff', 14 | }; 15 | -------------------------------------------------------------------------------- /examples/react-native/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /examples/react-native/.npmignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | @interface AppDelegate : UIResponder 11 | 12 | @property (nonatomic, strong) UIWindow *window; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /examples/react-native/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/react-native/components/lightbox/DemoLightbox.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Text} from 'react-native'; 3 | 4 | import Lightbox from './BaseLightbox'; 5 | 6 | const DemoLightbox = ({data, children}) => ( 7 | 8 | Demo Lightbox: {data} 9 | Allows transparency for background 10 | 11 | ); 12 | 13 | export default DemoLightbox; 14 | -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. This is used to schedule 9 | * rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "Example"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/expo/screens/SettingsScreen.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ExpoConfigView } from '@expo/samples'; 3 | 4 | export default class SettingsScreen extends React.Component { 5 | static navigationOptions = { 6 | title: 'app.json', 7 | }; 8 | 9 | render() { 10 | /* Go ahead and delete ExpoConfigView and replace it with your 11 | * content, we just wanted to give you a quick view of your config */ 12 | return ; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSample/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/expo/components/TabBarIcon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Icon } from 'expo'; 3 | 4 | import Colors from '../constants/Colors'; 5 | 6 | export default class TabBarIcon extends React.Component { 7 | render() { 8 | return ( 9 | 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/java/com/rnrfreduxsample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.rnrfreduxsample; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "rnrfReduxSample"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/react-native/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | .idea 28 | .gradle 29 | local.properties 30 | 31 | # node.js 32 | # 33 | node_modules/ 34 | *.log 35 | 36 | .vscode/ 37 | jsconfig.json -------------------------------------------------------------------------------- /examples/redux/android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android_ 4 | Project android_ created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/redux/src/a-reducer.js: -------------------------------------------------------------------------------- 1 | import { ActionConst } from 'react-native-router-flux'; 2 | 3 | const INITIAL_STATE = { data: null, currentScene: 'home' }; 4 | 5 | export default (state = INITIAL_STATE, { type, payload, routeName }) => { 6 | switch (type) { 7 | case ActionConst.FOCUS: 8 | console.log('FOCUS event fired with scene parameter: ', routeName); 9 | return { ...state, currentScene: routeName }; 10 | case 'data': 11 | return { ...state, data: payload }; 12 | 13 | default: 14 | return state; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /examples/react-native/components/TabIcon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {Text} from 'react-native'; 4 | 5 | const propTypes = { 6 | focused: PropTypes.bool, 7 | title: PropTypes.string, 8 | }; 9 | 10 | const defaultProps = { 11 | focused: false, 12 | title: '', 13 | }; 14 | 15 | const TabIcon = props => ( 16 | {props.title} 17 | ); 18 | 19 | TabIcon.propTypes = propTypes; 20 | TabIcon.defaultProps = defaultProps; 21 | 22 | export default TabIcon; 23 | -------------------------------------------------------------------------------- /packages/react-native-router-flux-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-router-flux-cli", 3 | "version": "0.0.1", 4 | "license": "MIT", 5 | "description": "The React Native Router Flux CLI tools", 6 | "main": "index.js", 7 | "engines": { 8 | "node": ">=4" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/aksonov/react-native-router-flux.git" 13 | }, 14 | "scripts": { 15 | "test": "mocha" 16 | }, 17 | "bin": { 18 | "rnrf": "index.js" 19 | }, 20 | "dependencies": { 21 | "rimraf": "^2.6.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import * as ActionConst from './ActionConst'; 2 | import Router from './Router'; 3 | import Reducer from './Reducer'; 4 | import Scene from './Scene'; 5 | import NavigationStore from './Store'; 6 | import defaultStore from './defaultStore'; 7 | import Modal from './Modal'; 8 | import Lightbox from './Lightbox'; 9 | import Stack from './Stack'; 10 | import Drawer from './Drawer'; 11 | import Tabs from './Tabs'; 12 | import Overlay from './Overlay'; 13 | import pathParser from './pathParser'; 14 | 15 | const Actions = defaultStore; 16 | 17 | export { 18 | Reducer, ActionConst, Router, Scene, NavigationStore, Actions, Modal, Lightbox, Stack, Drawer, Tabs, Overlay, pathParser, 19 | }; 20 | -------------------------------------------------------------------------------- /src/LightboxRenderer.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React from 'react'; 4 | import { View } from 'react-native'; 5 | 6 | export default ({ navigation, descriptors }) => { 7 | const { state } = navigation; 8 | const descriptor = descriptors[state.routes[0].key]; // base component to render 9 | const Component = descriptor.getComponent(); 10 | const popupDescriptor = descriptors[state.routes[state.index].key]; 11 | const Popup = state.index !== 0 ? popupDescriptor.getComponent() : null; 12 | return ( 13 | 14 | 15 | {Popup && } 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /examples/react-native/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /examples/expo/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "ExpoExample", 4 | "description": "A very interesting project.", 5 | "slug": "ExpoExample", 6 | "privacy": "public", 7 | "sdkVersion": "30.0.0", 8 | "platforms": ["ios", "android"], 9 | "version": "1.0.0", 10 | "orientation": "portrait", 11 | "icon": "./assets/images/icon.png", 12 | "splash": { 13 | "image": "./assets/images/splash.png", 14 | "resizeMode": "contain", 15 | "backgroundColor": "#ffffff" 16 | }, 17 | "updates": { 18 | "fallbackToCacheTimeout": 0 19 | }, 20 | "assetBundlePatterns": [ 21 | "**/*" 22 | ], 23 | "ios": { 24 | "supportsTablet": true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/react-native-router-flux-cli/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | const path = require('path'); 6 | const rimraf = require('rimraf'); 7 | 8 | const [,, command, ...args] = process.argv; 9 | 10 | const commands = { 11 | dedup: function () { 12 | const blacklisted = [ 13 | 'node_modules/react-native-router-flux/node_modules', 14 | 'node_modules/react-native-router-flux/examples' 15 | ]; 16 | 17 | blacklisted.map(function (part) { 18 | const current = path.join(process.env.PWD, part); 19 | rimraf(current, function (err) { 20 | if (err) throw err 21 | console.log(`${current} removed!`); 22 | }); 23 | }); 24 | } 25 | }; 26 | 27 | commands[command](...args); 28 | -------------------------------------------------------------------------------- /src/ActionConst.js: -------------------------------------------------------------------------------- 1 | export const JUMP = 'REACT_NATIVE_ROUTER_FLUX_JUMP'; 2 | export const PUSH = 'REACT_NATIVE_ROUTER_FLUX_PUSH'; 3 | export const PUSH_OR_POP = 'REACT_NATIVE_ROUTER_FLUX_PUSH_OR_POP'; 4 | export const REPLACE = 'REACT_NATIVE_ROUTER_FLUX_REPLACE'; 5 | export const BACK = 'REACT_NATIVE_ROUTER_FLUX_BACK'; 6 | export const BACK_ACTION = 'REACT_NATIVE_ROUTER_FLUX_BACK_ACTION'; 7 | export const POP_TO = 'REACT_NATIVE_ROUTER_FLUX_POP_TO'; 8 | export const REFRESH = 'REACT_NATIVE_ROUTER_FLUX_REFRESH'; 9 | export const RESET = 'REACT_NATIVE_ROUTER_FLUX_RESET'; 10 | export const FOCUS = 'REACT_NATIVE_ROUTER_FLUX_FOCUS'; 11 | export const BLUR = 'REACT_NATIVE_ROUTER_FLUX_BLUR'; 12 | export const ANDROID_BACK = 'REACT_NATIVE_ROUTER_FLUX_ANDROID_BACK'; 13 | -------------------------------------------------------------------------------- /examples/expo/__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import renderer from 'react-test-renderer'; 4 | import NavigationTestUtils from 'react-navigation/NavigationTestUtils'; 5 | import App from '../App'; 6 | 7 | describe('App snapshot', () => { 8 | jest.useFakeTimers(); 9 | beforeEach(() => { 10 | NavigationTestUtils.resetInternalState(); 11 | }); 12 | 13 | it('renders the loading screen', async () => { 14 | const tree = renderer.create().toJSON(); 15 | expect(tree).toMatchSnapshot(); 16 | }); 17 | 18 | it('renders the root without loading screen', async () => { 19 | const tree = renderer.create().toJSON(); 20 | expect(tree).toMatchSnapshot(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /examples/redux/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /examples/expo/screens/LinksScreen.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ScrollView, StyleSheet } from 'react-native'; 3 | import { ExpoLinksView } from '@expo/samples'; 4 | 5 | export default class LinksScreen extends React.Component { 6 | static navigationOptions = { 7 | title: 'Links', 8 | }; 9 | 10 | render() { 11 | return ( 12 | 13 | {/* Go ahead and delete ExpoLinksView and replace it with your 14 | * content, we just wanted to provide you with some helpful links */} 15 | 16 | 17 | ); 18 | } 19 | } 20 | 21 | const styles = StyleSheet.create({ 22 | container: { 23 | flex: 1, 24 | paddingTop: 15, 25 | backgroundColor: '#fff', 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /examples/react-native/components/MessageBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {MessageBar, MessageBarManager} from 'react-native-message-bar'; 3 | 4 | export default class extends React.Component { 5 | componentDidMount() { 6 | // Register the alert located on this master page 7 | // This MessageBar will be accessible from the current (same) component, and from its child component 8 | // The MessageBar is then declared only once, in your main component. 9 | MessageBarManager.registerMessageBar(this.refs.alert); 10 | } 11 | 12 | componentWillUnmount() { 13 | // Remove the alert located on this master page from the manager 14 | MessageBarManager.unregisterMessageBar(); 15 | } 16 | 17 | render() { 18 | return ; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/react-native/components/modal/ErrorModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Text, View, Button} from 'react-native'; 3 | import {Actions} from 'react-native-router-flux'; 4 | import Modal from './BaseModal'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | justifyContent: 'center', 9 | alignItems: 'center', 10 | marginHorizontal: 20, 11 | }, 12 | }); 13 | 14 | const ErrorModal = () => ( 15 | 16 | 17 | Error Modal 18 | 19 | Slides up from the bottom, and covers the entire screen with no 20 | transparency 21 | 22 | 19 | 22 | 23 | 24 | ); 25 | 26 | export default Register; 27 | -------------------------------------------------------------------------------- /examples/react-native/ios/ExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSample-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/react-native/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '10.0' 5 | 6 | target 'Example' do 7 | config = use_native_modules! 8 | 9 | use_react_native!(:path => config["reactNativePath"]) 10 | 11 | target 'ExampleTests' do 12 | inherit! :complete 13 | # Pods for testing 14 | end 15 | 16 | # Enables Flipper. 17 | # 18 | # Note that if you have use_frameworks! enabled, Flipper will not work and 19 | # you should disable these next few lines. 20 | use_flipper! 21 | post_install do |installer| 22 | flipper_post_install(installer) 23 | end 24 | end 25 | 26 | target 'Example-tvOS' do 27 | # Pods for Example-tvOS 28 | 29 | target 'Example-tvOSTests' do 30 | inherit! :search_paths 31 | # Pods for testing 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /src/OverlayRenderer.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import React from 'react'; 4 | import { View } from 'react-native'; 5 | 6 | export default ({ navigationConfig, descriptors }) => { 7 | const { initialRouteName, order, contentComponent } = navigationConfig; 8 | const ContentComponent = contentComponent || View; 9 | const descriptor = descriptors[initialRouteName]; 10 | const Component = descriptor.getComponent(); 11 | 12 | const overlays = []; 13 | for (let i = 0; i < order.length; i += 1) { 14 | const routeName = order[i]; 15 | if (initialRouteName !== routeName) { 16 | const Overlay = descriptors[routeName].getComponent(); 17 | overlays.push(); 18 | } 19 | } 20 | return ( 21 | 22 | 23 | {overlays} 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /examples/redux/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /examples/react-native/components/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, StyleSheet} from 'react-native'; 3 | import Button from 'react-native-button'; 4 | import {Actions} from 'react-native-router-flux'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | justifyContent: 'center', 10 | alignItems: 'center', 11 | backgroundColor: '#F5FCFF', 12 | }, 13 | welcome: { 14 | fontSize: 20, 15 | textAlign: 'center', 16 | margin: 10, 17 | }, 18 | instructions: { 19 | textAlign: 'center', 20 | color: '#333333', 21 | marginBottom: 5, 22 | }, 23 | }); 24 | 25 | class Home extends React.Component { 26 | render() { 27 | return ( 28 | 29 | Replace screen 30 | Prop from dynamic method: {this.props.homeProp} 31 | 32 | 33 | ); 34 | } 35 | } 36 | 37 | module.exports = Home; 38 | -------------------------------------------------------------------------------- /examples/react-native/components/Login2.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, StyleSheet} from 'react-native'; 3 | import Button from 'react-native-button'; 4 | import {Actions} from 'react-native-router-flux'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | justifyContent: 'center', 10 | alignItems: 'center', 11 | backgroundColor: '#F5FCFF', 12 | }, 13 | }); 14 | 15 | export default class extends React.Component { 16 | render() { 17 | const title = this.props.title || 'No Title'; 18 | const data = this.props.data || 'No Data'; 19 | return ( 20 | 21 | Login page 2 22 | Title: {title} 23 | Data: {data} 24 | 30 | 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/redux/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 50 | 51 | fastlane/report.xml 52 | fastlane/Preview.html 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /examples/react-native/components/EchoView.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, StyleSheet} from 'react-native'; 3 | import Button from 'react-native-button'; 4 | import {Actions} from 'react-native-router-flux'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | justifyContent: 'center', 10 | alignItems: 'center', 11 | backgroundColor: '#F5FCFF', 12 | borderWidth: 2, 13 | borderColor: 'red', 14 | }, 15 | instructions: { 16 | textAlign: 'center', 17 | color: '#333333', 18 | marginBottom: 5, 19 | }, 20 | smaller: { 21 | marginBottom: 5, 22 | fontSize: 12, 23 | }, 24 | }); 25 | 26 | export default class extends React.Component { 27 | onEnter() { 28 | console.log('EchoView onEnter'); 29 | } 30 | 31 | render() { 32 | return ( 33 | 34 | routeName: {this.props.name} 35 | 36 | 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: ~/react-native-router-flux 5 | docker: 6 | - image: circleci/node:10 7 | steps: 8 | - checkout 9 | - restore_cache: 10 | key: dependency-cache-{{ checksum "package.json" }} 11 | - run: 12 | name: install-dependencies 13 | command: yarn install --frozen-lockfile 14 | - save_cache: 15 | key: dependency-cache-{{ checksum "package.json" }} 16 | paths: 17 | - ~/.cache/yarn 18 | - run: 19 | name: test 20 | command: yarn test 21 | - run: 22 | name: linter 23 | command: yarn lint 24 | - run: 25 | name: install-dependencies react-native example 26 | command: yarn install --frozen-lockfile 27 | working_directory: ~/react-native-router-flux/examples/react-native 28 | - run: 29 | name: test react-native example 30 | command: yarn test 31 | working_directory: ~/react-native-router-flux/examples/react-native 32 | -------------------------------------------------------------------------------- /examples/react-native/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | yarn-error.log 37 | 38 | # BUCK 39 | buck-out/ 40 | \.buckd/ 41 | *.keystore 42 | !debug.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # CocoaPods 59 | /ios/Pods/ 60 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change log 2 | - 3.26.22 Pass DefaultRenderer props to underlying scene component 3 | - 3.26.21 Added onBack, hideBackImage properties 4 | - 3.26.20 Support for 'modifier' functions inside Refresh actions, like `Actions.refresh({ key: 'drawer', open: value=>!value })` 5 | - 3.26.0 Support for React Native 0.26 6 | - 3.22.20 fix more ESLint errors, fix passing leftButtonStyle property for back button 7 | - 3.22.18 fix some ESLint errors and ignore pop for root scene 8 | - 3.22.17 allow jump & push together - now you could call Actions.tab2_2() (`tab2_2` is next scene after `tab2`) even if `tab2` is not active 9 | - 3.22.16 simplified syntax for sub-states 10 | - 3.22.15 introduces support for different states inside the same screen. 11 | - 3.22.10 simplifies customization of own NavBar. From now you could import built-in NavBar from the component and customize it. You could set it globally to all scenes by setting `navBar` property for `Router` component. 12 | For all other scenes you may pass rightButton, leftButton for custom buttons or rightTitle & onRight, leftTitle & onLeft for text buttons. 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015-2017 aksonov 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 | -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 13 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/react-native/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/redux/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | maven { 7 | url 'https://maven.google.com/' 8 | name 'Google' 9 | } 10 | } 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:2.3.3' 13 | 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | mavenLocal() 22 | jcenter() 23 | maven { 24 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 25 | url "$rootDir/../node_modules/react-native/android" 26 | } 27 | maven { 28 | url 'https://maven.google.com/' 29 | name 'Google' 30 | } 31 | } 32 | } 33 | 34 | ext { 35 | buildToolsVersion = "26.0.3" 36 | minSdkVersion = 16 37 | compileSdkVersion = 26 38 | targetSdkVersion = 26 39 | supportLibVersion = "26.1.0" 40 | } 41 | -------------------------------------------------------------------------------- /examples/react-native/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "29.0.2" 6 | minSdkVersion = 16 7 | compileSdkVersion = 29 8 | targetSdkVersion = 29 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:3.5.3") 16 | // NOTE: Do not place your application dependencies here; they belong 17 | // in the individual module build.gradle files 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | mavenLocal() 24 | maven { 25 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 26 | url("$rootDir/../node_modules/react-native/android") 27 | } 28 | maven { 29 | // Android JSC is installed from npm 30 | url("$rootDir/../node_modules/jsc-android/dist") 31 | } 32 | 33 | google() 34 | jcenter() 35 | maven { url 'https://www.jitpack.io' } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/v3/MIGRATION.md: -------------------------------------------------------------------------------- 1 | # Migrating from 2.x 2 | 3 | ## Breaking changes comparing with 2.x version: 4 | - React Native 0.26 is required 5 | - `Router` is root container now and should not be nested. For nested scenes you should use `Scene` element 6 | - `Route` became `Scene`, now unique `key` attribute is required for each scene (it was `name` attribute before) 7 | - Define all your scenes on top-level, not within `Router` as before (see Example) 8 | - No `Schema` element is supported for now (for simplicity), maybe later it could be added 9 | - No ActionSheet support 10 | - Custom scene renderers are used instead of 'custom' types (like 'modal'), so 'modal' scenes are pushed as usual, but custom renderer will render them as popup. No `dismiss`, just usual `pop` to close such popups. 11 | - No old navigator.sceneConfig support (instead the component uses React Native NavigationAnimatedView for better transitions) 12 | - No onPush/onPop/etc handlers because they are not needed now. If navigation state is changed, container will be re-rendered with changed navigationState property, see `Modal` as Example. 13 | - No header/footer properties are supported for Scene currently - you may include them into Scene component. 14 | -------------------------------------------------------------------------------- /examples/react-native/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "react": "16.13.1", 14 | "react-native": "0.63.0", 15 | "react-native-button": "^3.0.1", 16 | "react-native-gesture-handler": "^1.6.1", 17 | "react-native-message-bar": "^2.0.10", 18 | "react-native-reanimated": "^1.9.0", 19 | "react-native-router-flux": "^4.3.0", 20 | "@react-native-community/masked-view": "^0.1.10", 21 | "react-native-safe-area-context": "^3.2.0", 22 | "react-native-screens": "^2.18.1" 23 | }, 24 | "devDependencies": { 25 | "@babel/core": "^7.10.4", 26 | "@babel/runtime": "^7.10.4", 27 | "@react-native-community/eslint-config": "^2.0.0", 28 | "babel-jest": "^26.1.0", 29 | "eslint": "^7.4.0", 30 | "jest": "^26.1.0", 31 | "metro-react-native-babel-preset": "^0.60.0", 32 | "react-test-renderer": "16.13.1" 33 | }, 34 | "jest": { 35 | "preset": "react-native" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/expo/components/DrawerContent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { StyleSheet, Text, View, ViewPropTypes } from 'react-native'; 4 | import Button from 'react-native-button'; 5 | import { Actions } from 'react-native-router-flux'; 6 | 7 | const styles = StyleSheet.create({ 8 | container: { 9 | flex: 1, 10 | justifyContent: 'center', 11 | alignItems: 'center', 12 | backgroundColor: 'transparent', 13 | borderWidth: 2, 14 | borderColor: 'red', 15 | }, 16 | }); 17 | 18 | class DrawerContent extends React.Component { 19 | static propTypes = { 20 | name: PropTypes.string, 21 | sceneStyle: ViewPropTypes.style, 22 | title: PropTypes.string, 23 | }; 24 | 25 | static contextTypes = { 26 | drawer: PropTypes.object, 27 | }; 28 | 29 | render() { 30 | return ( 31 | 32 | 33 | 34 | 35 | 36 | 37 | ); 38 | } 39 | } 40 | 41 | export default DrawerContent; 42 | -------------------------------------------------------------------------------- /src/Util.js: -------------------------------------------------------------------------------- 1 | // searches for the deepest explicitly set value for a key 2 | // in a navigationState tree. 3 | export function deepestExplicitValueForKey(navigationState, key) { 4 | let current; 5 | let selected = navigationState; 6 | 7 | while ({}.hasOwnProperty.call(selected, 'children')) { 8 | if (!selected.tabs) { 9 | // for pushed children, iterate through each, recording key value, 10 | // until reaching the selected child 11 | for (let i = 0; i < selected.index; i += 1) { 12 | if (typeof selected.children[i][key] !== 'undefined') { 13 | current = selected.children[i][key]; 14 | } 15 | } 16 | } 17 | // set the new selected child and check for a key value 18 | selected = selected.children[selected.index]; 19 | if (typeof selected[key] !== 'undefined') { 20 | current = selected[key]; 21 | } 22 | } 23 | 24 | // fallback to the root key value 25 | if (typeof current === 'undefined') { 26 | current = navigationState[key]; 27 | } 28 | 29 | return current; 30 | } 31 | 32 | export function assert(expr, failDescription) { 33 | if (!expr) { 34 | throw new Error(`[react-native-router-flux] ${failDescription}`); 35 | } 36 | } 37 | 38 | export const OnEnter = 'onEnter'; 39 | export const OnExit = 'onExit'; 40 | -------------------------------------------------------------------------------- /examples/redux/android/app/src/main/java/com/rnrfreduxsample/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.rnrfreduxsample; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.shell.MainReactPackage; 9 | import com.facebook.soloader.SoLoader; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class MainApplication extends Application implements ReactApplication { 15 | 16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | return Arrays.asList( 25 | new MainReactPackage() 26 | ); 27 | } 28 | 29 | @Override 30 | protected String getJSMainModuleName() { 31 | return "index"; 32 | } 33 | }; 34 | 35 | @Override 36 | public ReactNativeHost getReactNativeHost() { 37 | return mReactNativeHost; 38 | } 39 | 40 | @Override 41 | public void onCreate() { 42 | super.onCreate(); 43 | SoLoader.init(this, /* native exopackage */ false); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /__tests__/scenes.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Text } from 'react-native'; 3 | 4 | // Note: test renderer must be required after react-native. 5 | import renderer from 'react-test-renderer'; 6 | import Router from '../src/Router'; 7 | import Scene from '../src/Scene'; 8 | import NavigationStore from '../src/Store'; 9 | 10 | const B = () => Hello world!; 11 | const router = ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ); 21 | 22 | test('renders correctly', (done) => { 23 | // TODO: fix react-native-gesture-handler error 24 | // renderer.create(router); 25 | // console.log('STATE:', JSON.stringify(navigationStore.state)); 26 | // navigationStore.c({ data: 'abc' }); 27 | // navigationStore.refresh({ data: 'abcde' }); 28 | // console.log('STATE:', JSON.stringify(navigationStore.state)); 29 | // navigationStore.pop(); 30 | // console.log('STATE:', JSON.stringify(navigationStore.state)); 31 | // navigationStore.refresh({ a: 3 }); 32 | // console.log('STATE:', JSON.stringify(navigationStore.state)); 33 | // navigationStore.popTo('NOT_A_REAL_SCENE'); 34 | // console.log('STATE:', JSON.stringify(navigationStore.state)); 35 | done(); 36 | }); 37 | -------------------------------------------------------------------------------- /examples/react-native/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.37.0 29 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | 13 | @implementation AppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | NSURL *jsCodeLocation; 18 | 19 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 20 | 21 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 22 | moduleName:@"rnrfReduxSample" 23 | initialProperties:nil 24 | launchOptions:launchOptions]; 25 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 26 | 27 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 28 | UIViewController *rootViewController = [UIViewController new]; 29 | rootViewController.view = rootView; 30 | self.window.rootViewController = rootViewController; 31 | [self.window makeKeyAndVisible]; 32 | return YES; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /examples/react-native/components/CustomNavBar2.js: -------------------------------------------------------------------------------- 1 | import { 2 | Image, 3 | Platform, 4 | StyleSheet, 5 | Text, 6 | TouchableOpacity, 7 | View, 8 | } from 'react-native'; 9 | import React from 'react'; 10 | import {Actions} from 'react-native-router-flux'; 11 | 12 | const styles = StyleSheet.create({ 13 | container: { 14 | height: Platform.OS === 'ios' ? 64 : 54, 15 | flexDirection: 'row', 16 | paddingTop: 20, 17 | backgroundColor: 'green', 18 | }, 19 | navBarItem: { 20 | flex: 1, 21 | justifyContent: 'center', 22 | }, 23 | }); 24 | 25 | export default class CustomNavBar extends React.Component { 26 | // constructor(props) { 27 | // super(props) 28 | // } 29 | 30 | _renderLeft() { 31 | return ( 32 | 35 | 40 | 41 | ); 42 | } 43 | 44 | _renderMiddle() { 45 | return ( 46 | 47 | {this.props.title} 48 | 49 | ); 50 | } 51 | 52 | render() { 53 | return ( 54 | 55 | {this._renderLeft()} 56 | {this._renderMiddle()} 57 | 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /examples/react-native/components/Login3.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, StyleSheet} from 'react-native'; 3 | import Button from 'react-native-button'; 4 | import {Actions} from 'react-native-router-flux'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | justifyContent: 'center', 10 | alignItems: 'center', 11 | backgroundColor: '#F5FCFF', 12 | }, 13 | }); 14 | 15 | const popToRoot = () => { 16 | Actions.popTo('launch'); 17 | }; 18 | 19 | const popToLogin1 = () => { 20 | Actions.popTo('loginModal'); 21 | }; 22 | 23 | const popToLogin2 = () => { 24 | Actions.popTo('loginModal2'); 25 | }; 26 | 27 | const popAndRefresh = () => { 28 | Actions.pop({ 29 | refresh: {data: 'Data after pop', title: 'title after pop'}, 30 | key: null, 31 | }); 32 | }; 33 | 34 | export default class extends React.Component { 35 | render() { 36 | const title = this.props.title || 'No Title'; 37 | const data = this.props.data || 'No Data'; 38 | return ( 39 | 40 | Login page 3 41 | Title: {title} 42 | Data: {data} 43 | 44 | 45 | 46 | 47 | 48 | 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /examples/react-native/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.example", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.example", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /examples/redux/src/home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity } from 'react-native'; 3 | import { connect } from 'react-redux'; 4 | import { Actions } from 'react-native-router-flux'; 5 | 6 | class Home extends React.Component { 7 | render() { 8 | return ( 9 | 10 | 11 | Current scene: "{this.props.currentScene}" 12 | Welcome to the home scene. 13 | {this.props.data ? this.props.data : 'No data...'} 14 | 15 | { 18 | Actions.page(); 19 | }} 20 | > 21 | Go to "page" --> 22 | 23 | 24 | ); 25 | } 26 | } 27 | 28 | const styles = { 29 | fill: { 30 | flex: 1, 31 | }, 32 | header: { 33 | flex: 2, 34 | padding: 20, 35 | }, 36 | text: { 37 | fontSize: 20, 38 | textAlign: 'center', 39 | justifyContent: 'center', 40 | }, 41 | data: { 42 | marginTop: 100, 43 | fontSize: 30, 44 | textAlign: 'center', 45 | }, 46 | button: { 47 | flex: 1, 48 | backgroundColor: 'green', 49 | justifyContent: 'center', 50 | }, 51 | }; 52 | 53 | const mapStateToProps = ({ reducer }) => ({ data } = reducer); 54 | 55 | export default connect( 56 | mapStateToProps, 57 | {}, 58 | )(Home); 59 | -------------------------------------------------------------------------------- /examples/redux/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | .*/Libraries/react-native/ReactNative.js 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/Libraries/react-native/react-native-interface.js 21 | node_modules/react-native/flow 22 | flow/ 23 | 24 | [options] 25 | emoji=true 26 | 27 | module.system=haste 28 | 29 | munge_underscores=true 30 | 31 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 32 | 33 | suppress_type=$FlowIssue 34 | suppress_type=$FlowFixMe 35 | suppress_type=$FixMe 36 | 37 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-7]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 38 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-7]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 40 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 41 | 42 | unsafe.enable_getters_and_setters=true 43 | 44 | [version] 45 | ^0.47.0 46 | -------------------------------------------------------------------------------- /examples/redux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rnrfReduxSample", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "ios": "react-native run-ios", 8 | "android": "react-native run-android", 9 | "dev:ios": "yarn dev && yarn ios", 10 | "dev:android": "yarn dev && yarn android", 11 | "dev": "cp ../../src/* node_modules/react-native-router-flux/src/", 12 | "test": "jest", 13 | "postinstall": "./node_modules/.bin/rnrf dedup" 14 | }, 15 | "resolutions": { 16 | "*/@babel/cli": "7.0.0-beta.47", 17 | "*/@babel/core": "7.0.0-beta.47", 18 | "*/@babel/code-frame": "7.0.0-beta.47", 19 | "*/@babel/highlight": "7.0.0-beta.47" 20 | }, 21 | "dependencies": { 22 | "prop-types": "^15.6.2", 23 | "react": "16.4.1", 24 | "react-native": "0.56.0", 25 | "react-native-router-flux": "file:../../", 26 | "react-native-router-flux-cli": "file:../../packages/react-native-router-flux-cli", 27 | "react-navigation": "2.13.x", 28 | "react-navigation-redux-helpers": "^2.0.5", 29 | "react-redux": "^5.0.5", 30 | "redux": "4.0.x" 31 | }, 32 | "devDependencies": { 33 | "@babel/core": "7.0.0-beta.47", 34 | "@babel/plugin-proposal-decorators": "7.0.0-beta.47", 35 | "autobind-decorator": "^2.1.0", 36 | "babel-core": "^7.0.0-0", 37 | "babel-jest": "23.4.0", 38 | "babel-preset-react-native": "5.0.2", 39 | "jest": "^23.4.1", 40 | "react-test-renderer": "^16.4.1" 41 | }, 42 | "jest": { 43 | "preset": "react-native" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | os: 5 | - osx 6 | cache: 7 | - yarn 8 | - directories: 9 | - "$TRAVIS_BUILD_DIR/node_modules" 10 | - "$TRAVIS_BUILD_DIR/Example/node_modules" 11 | notifications: 12 | email: false 13 | branches: 14 | only: 15 | - master 16 | env: 17 | matrix: 18 | - TEST_SUITE=eslint CACHE_NAME=eslint 19 | - TEST_SUITE=lib-test CACHE_NAME=lib-test 20 | - TEST_SUITE=example-jest CACHE_NAME=example-jest 21 | before_install: 22 | - export YARN_GPG=no 23 | install: 24 | - curl -o- -L https://yarnpkg.com/install.sh | bash 25 | - export PATH=$HOME/.yarn/bin:$PATH 26 | - if [ $TEST_SUITE = example-jest ]; then cd Example && yarn && cd ..; fi 27 | - if [ $TEST_SUITE = eslint ] || [ $TEST_SUITE = lib-test ]; then yarn; fi 28 | before_script: 29 | - if [ $TEST_SUITE = example-jest ]; then rm -rf Example/node_modules/react-native-router-flux/node_modules; fi 30 | - if [ $TEST_SUITE = example-jest ]; then rm -rf Example/node_modules/react-native-router-flux/Example; fi 31 | - if [ $TEST_SUITE = example-jest ]; then cp -r src/ Example/node_modules/react-native-router-flux/src/; fi 32 | script: 33 | - if [ $TEST_SUITE = eslint ]; then node node_modules/.bin/eslint index.js src/ _tests__/; fi 34 | - if [ $TEST_SUITE = lib-test ]; then yarn test; fi 35 | - if [ $TEST_SUITE = example-jest ]; then cd Example && yarn run jest && cd ..; fi 36 | before_cache: 37 | - if [ $TEST_SUITE = example-jest ]; then rm -rf Example/node_modules/react-native-router-flux/src; fi 38 | addons: 39 | code_climate: 40 | repo_token: a2bf832968783c93c977e25624e038120a559ffda488f5c76ec1c304e80a9c6e 41 | -------------------------------------------------------------------------------- /examples/expo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-new-project", 3 | "main": "node_modules/expo/AppEntry.js", 4 | "private": true, 5 | "scripts": { 6 | "start": "expo start", 7 | "dev:start": "yarn dev && yarn start", 8 | "android": "expo start --android", 9 | "ios": "expo start --ios", 10 | "dev:ios": "yarn dev && yarn ios", 11 | "dev:android": "yarn dev && yarn android", 12 | "dev": "cp ../../src/* node_modules/react-native-router-flux/src/", 13 | "eject": "expo eject", 14 | "lint": "yarn run eslint **/*.js", 15 | "fix": "yarn run eslint **/*.js --fix", 16 | "test": "node ./node_modules/jest/bin/jest.js --watchAll", 17 | "postinstall": "./node_modules/.bin/rnrf dedup" 18 | }, 19 | "jest": { 20 | "preset": "jest-expo" 21 | }, 22 | "dependencies": { 23 | "@expo/samples": "2.1.1", 24 | "expo": "^30.0.1", 25 | "react": "16.3.1", 26 | "react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz", 27 | "react-native-button": "~2.3.0", 28 | "react-native-router-flux": "file:../..", 29 | "react-native-router-flux-cli": "file:../../packages/react-native-router-flux-cli", 30 | "react-navigation": "~2.14.2", 31 | "react-navigation-stack": "^0.4.0" 32 | }, 33 | "devDependencies": { 34 | "@babel/core": "7.1.0", 35 | "babel-core": "^7.0.0-0", 36 | "eslint": "^5.6.0", 37 | "eslint-config-universe": "^2.0.0-alpha.0", 38 | "jest-expo": "^30.0.0", 39 | "prettier": "^1.14.2", 40 | "react-native-debugger-open": "^0.3.17" 41 | }, 42 | "eslintConfig": { 43 | "extends": [ 44 | "universe/node", 45 | "universe/native" 46 | ] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'airbnb', 3 | plugins: ['react', 'jest'], 4 | env: { 5 | 'jest/globals': true, 6 | }, 7 | parser: 'babel-eslint', 8 | rules: { 9 | 'no-new-func': 'warn', 10 | 'jest/no-disabled-tests': 'warn', 11 | 'jest/no-focused-tests': 'error', 12 | 'jest/no-identical-title': 'error', 13 | 'jest/valid-expect': 'error', 14 | 15 | 'react/forbid-prop-types': 'warn', 16 | 'react/prop-types': 'off', 17 | 'react/require-default-props': 'off', 18 | 'react/no-unused-prop-types': 'off', 19 | 'no-param-reassign': 0, 20 | 'no-console': 0, 21 | 'new-cap': 0, 22 | 'no-underscore-dangle': 0, 23 | 'no-use-before-define': 0, 24 | 'max-len': ['error', 180], 25 | 'import/no-unresolved': [ 26 | 2, 27 | { 28 | ignore: ['^react$', '^react-native$', '^react-native/'], 29 | }, 30 | ], 31 | 'import/no-cycle': 'warn', 32 | 'import/no-self-import': 'warn', 33 | 'react/jsx-filename-extension': [ 34 | 1, 35 | { 36 | extensions: ['.js', '.jsx'], 37 | }, 38 | ], 39 | 'import/no-extraneous-dependencies': [ 40 | 'error', 41 | { 42 | devDependencies: true, 43 | }, 44 | ], 45 | 'no-bitwise': [ 46 | 'error', 47 | { 48 | allow: ['^'], 49 | }, 50 | ], 51 | 'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'], 52 | }, 53 | settings: { 54 | 'import/resolver': { 55 | node: { 56 | extensions: ['.js', '.android.js', '.ios.js'], 57 | }, 58 | }, 59 | node: true, 60 | react: { 61 | version: '16.4.2', 62 | }, 63 | }, 64 | }; 65 | -------------------------------------------------------------------------------- /examples/react-native/components/Login.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, StyleSheet} from 'react-native'; 3 | import Button from 'react-native-button'; 4 | import {Actions} from 'react-native-router-flux'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | justifyContent: 'center', 10 | alignItems: 'center', 11 | backgroundColor: '#F5FCFF', 12 | }, 13 | welcome: { 14 | fontSize: 20, 15 | textAlign: 'center', 16 | margin: 10, 17 | }, 18 | instructions: { 19 | textAlign: 'center', 20 | color: '#333333', 21 | marginBottom: 5, 22 | }, 23 | }); 24 | 25 | export default class extends React.Component { 26 | static onEnter = () => { 27 | Actions.refresh({ 28 | title: 'Login!', 29 | rightTitle: 'rightTitle', 30 | onRight: () => {}, 31 | }); 32 | }; 33 | 34 | render() { 35 | const title = this.props.title || 'No Title'; 36 | const data = this.props.data || 'No Data'; 37 | console.log('Login RENDER'); 38 | return ( 39 | 40 | Login page 1 41 | Title: {title} 42 | Data: {data} 43 | 49 | 55 | 56 | 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Reducer.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { NavigationActions, StackActions } from 'react-navigation'; 3 | import * as ActionConst from './ActionConst'; 4 | import { getActiveState, popPrevious } from './State'; 5 | 6 | export default function createReducer(store) { 7 | return (state, action) => { 8 | const NavigationStore = require('./Store').default; 9 | const navigationStore = store || new NavigationStore(); 10 | const { type, routeName } = action; 11 | if (type === ActionConst.POP_TO) { 12 | let nextScene = ''; 13 | let newState = state; 14 | let currentState = state; 15 | while (newState && nextScene !== routeName) { 16 | newState = navigationStore.getStateForAction(StackActions.pop(), currentState); 17 | if (newState) { 18 | nextScene = getActiveState(newState).routeName; 19 | if (nextScene !== routeName && _.isEqual(currentState, newState)) { 20 | console.warn(`popTo called with an unknown routeName: ${routeName}, current scene: ${nextScene}`); 21 | break; 22 | } 23 | if (nextScene !== routeName) { 24 | currentState = newState; 25 | } 26 | } 27 | } 28 | return nextScene === routeName ? newState : state; 29 | } 30 | if (type === ActionConst.REPLACE) { 31 | const newState = navigationStore.getStateForAction( 32 | NavigationActions.navigate({ 33 | routeName, 34 | params: action.params, 35 | }), 36 | state, 37 | ); 38 | const res = popPrevious(newState, routeName); 39 | return res; 40 | } 41 | return navigationStore.getStateForAction(action, state) || state; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /examples/redux/src/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStore, applyMiddleware, combineReducers } from 'redux'; 3 | import { Provider, connect } from 'react-redux'; 4 | import { Scene, Actions, Router } from 'react-native-router-flux'; 5 | import { reduxifyNavigator, createReactNavigationReduxMiddleware, createNavigationReducer } from 'react-navigation-redux-helpers'; 6 | 7 | import Home from './home'; 8 | import Page from './page'; 9 | import reducer from './a-reducer'; 10 | 11 | const AppNavigator = Actions.create( 12 | 13 | 14 | 15 | , 16 | ); 17 | 18 | // default nav reducer 19 | const initialState = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams('home')); 20 | const navReducer = (state = initialState, action) => { 21 | const nextState = AppNavigator.router.getStateForAction(action, state); 22 | // Simply return the original `state` if `nextState` is null or undefined. 23 | return nextState || state; 24 | }; 25 | 26 | const appReducer = combineReducers({ 27 | nav: navReducer, 28 | reducer, 29 | }); 30 | 31 | const middleware = createReactNavigationReduxMiddleware('root', state => state.nav); 32 | const ReduxNavigator = reduxifyNavigator(AppNavigator, 'root'); 33 | const mapStateToProps = state => ({ 34 | state: state.nav, 35 | }); 36 | const ReduxRouter = connect(mapStateToProps)(Router); 37 | const store = createStore(appReducer, applyMiddleware(middleware)); 38 | 39 | export default class App extends React.Component { 40 | render() { 41 | return ( 42 | 43 | 44 | 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/react-native/components/modal/BaseModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { 4 | View, 5 | Text, 6 | TouchableOpacity, 7 | StyleSheet, 8 | Dimensions, 9 | } from 'react-native'; 10 | import {Actions} from 'react-native-router-flux'; 11 | 12 | const {height: deviceHeight, width: deviceWidth} = Dimensions.get('window'); 13 | 14 | const BaseModal = ({ 15 | children, 16 | verticalPercent, 17 | horizontalPercent, 18 | hideClose, 19 | }) => { 20 | const height = verticalPercent 21 | ? deviceHeight * verticalPercent 22 | : deviceHeight; 23 | const width = horizontalPercent 24 | ? deviceHeight * horizontalPercent 25 | : deviceWidth; 26 | 27 | const renderClose = () => { 28 | if (hideClose) { 29 | return null; 30 | } 31 | return ( 32 | 33 | 34 | Close 35 | 36 | 37 | ); 38 | }; 39 | 40 | return ( 41 | 42 | {renderClose()} 43 | {children} 44 | 45 | ); 46 | }; 47 | 48 | BaseModal.propTypes = { 49 | children: PropTypes.any, 50 | verticalPercent: PropTypes.number, 51 | horizontalPercent: PropTypes.number, 52 | hideClose: PropTypes.bool, 53 | }; 54 | 55 | const styles = StyleSheet.create({ 56 | container: { 57 | position: 'absolute', 58 | top: 0, 59 | bottom: 0, 60 | left: 0, 61 | right: 0, 62 | backgroundColor: '#FFF', 63 | }, 64 | closeBtnContainer: { 65 | paddingTop: 20, 66 | flexDirection: 'row', 67 | justifyContent: 'flex-end', 68 | paddingHorizontal: 10, 69 | }, 70 | }); 71 | 72 | export default BaseModal; 73 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Version 2 | Tell us which versions you are using: 3 | 10 | - react-native-router-flux v4.?.? 11 | - react v16.?.? 12 | - react-native v0.?.? 13 | 14 | 30 | 31 | ### Expected behaviour 32 | 33 | 34 | 35 | ### Actual behaviour 36 | 37 | 38 | 39 | ### Steps to reproduce 40 | For non-obvious bugs, please fork this component, modify Example project to reproduce your issue and include link here. 41 | 1. 42 | 2. 43 | 3. 44 | 45 | ### Reproducible Demo 46 | 52 | Please provide a minimized reproducible demonstration of the problem you're reporting. 53 | 54 | Issues that come with minimal repro's are resolved much more quickly than issues where a maintainer has to reproduce themselves. 55 | 56 | 58 | -------------------------------------------------------------------------------- /examples/react-native/components/Error.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, StyleSheet, Animated, Dimensions} from 'react-native'; 3 | import Button from 'react-native-button'; 4 | import {Actions} from 'react-native-router-flux'; 5 | 6 | const {height: deviceHeight} = Dimensions.get('window'); 7 | 8 | const styles = StyleSheet.create({ 9 | container: { 10 | position: 'absolute', 11 | top: 0, 12 | bottom: 0, 13 | left: 0, 14 | right: 0, 15 | backgroundColor: 'transparent', 16 | justifyContent: 'center', 17 | alignItems: 'center', 18 | }, 19 | }); 20 | 21 | export default class extends React.Component { 22 | constructor(props) { 23 | super(props); 24 | 25 | this.state = { 26 | offset: new Animated.Value(-deviceHeight), 27 | }; 28 | } 29 | 30 | componentDidMount() { 31 | Animated.timing(this.state.offset, { 32 | duration: 150, 33 | toValue: 0, 34 | }).start(); 35 | } 36 | 37 | closeModal() { 38 | Animated.timing(this.state.offset, { 39 | duration: 150, 40 | toValue: -deviceHeight, 41 | }).start(Actions.pop); 42 | } 43 | 44 | render() { 45 | return ( 46 | 52 | 60 | {this.props.data} 61 | 62 | 63 | 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /examples/react-native/components/CustomNavBarView.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {StyleSheet, View, ViewPropTypes} from 'react-native'; 4 | import Button from 'react-native-button'; 5 | import {Actions} from 'react-native-router-flux'; 6 | 7 | const propTypes = { 8 | name: PropTypes.string, 9 | sceneStyle: ViewPropTypes.style, 10 | title: PropTypes.string, 11 | }; 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | flex: 1, 16 | justifyContent: 'center', 17 | alignItems: 'center', 18 | backgroundColor: 'transparent', 19 | borderWidth: 2, 20 | borderColor: 'red', 21 | }, 22 | }); 23 | 24 | class TabView extends React.Component { 25 | render() { 26 | return ( 27 | 28 | 29 | 30 | 36 | 42 | 48 | 54 | 55 | ); 56 | } 57 | } 58 | TabView.propTypes = propTypes; 59 | 60 | export default TabView; 61 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UIViewControllerBasedStatusBarAppearance 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSample-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /examples/redux/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | lib_deps = [] 12 | 13 | for jarfile in glob(['libs/*.jar']): 14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] 15 | lib_deps.append(':' + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | 21 | for aarfile in glob(['libs/*.aar']): 22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] 23 | lib_deps.append(':' + name) 24 | android_prebuilt_aar( 25 | name = name, 26 | aar = aarfile, 27 | ) 28 | 29 | android_library( 30 | name = "all-libs", 31 | exported_deps = lib_deps, 32 | ) 33 | 34 | android_library( 35 | name = "app-code", 36 | srcs = glob([ 37 | "src/main/java/**/*.java", 38 | ]), 39 | deps = [ 40 | ":all-libs", 41 | ":build_config", 42 | ":res", 43 | ], 44 | ) 45 | 46 | android_build_config( 47 | name = "build_config", 48 | package = "com.rnrfreduxsample", 49 | ) 50 | 51 | android_resource( 52 | name = "res", 53 | package = "com.rnrfreduxsample", 54 | res = "src/main/res", 55 | ) 56 | 57 | android_binary( 58 | name = "app", 59 | keystore = "//android/keystores:debug", 60 | manifest = "src/main/AndroidManifest.xml", 61 | package_type = "debug", 62 | deps = [ 63 | ":app-code", 64 | ], 65 | ) 66 | -------------------------------------------------------------------------------- /examples/react-native/components/Launch.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, StyleSheet, Button} from 'react-native'; 3 | import {Actions} from 'react-native-router-flux'; 4 | import {MessageBarManager} from 'react-native-message-bar'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | justifyContent: 'center', 10 | alignItems: 'center', 11 | backgroundColor: 'transparent', 12 | }, 13 | }); 14 | 15 | class Launch extends React.Component { 16 | render() { 17 | return ( 18 | 19 | Welcome 20 | */} 34 | Title: {this.props.title} 35 | {this.props.name === 'tab_1_1' && ( 36 | 37 | )} 38 | {this.props.name === 'tab_2_1' && ( 39 | 40 | )} 41 | 42 | 43 | 44 | 45 | 46 | 52 | 53 | 54 | 55 | ); 56 | } 57 | } 58 | 59 | export default DrawerContent; 60 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | import mocks from 'react-native-jest-mocks'; 2 | 3 | jest.mock('react-native-reanimated', () => { 4 | const View = require('react-native/Libraries/Components/View/View'); 5 | return { 6 | Value: jest.fn(), 7 | event: jest.fn(), 8 | add: jest.fn(), 9 | eq: jest.fn(), 10 | set: jest.fn(), 11 | cond: jest.fn(), 12 | interpolate: jest.fn(), 13 | View, 14 | Extrapolate: { CLAMP: jest.fn() }, 15 | Clock: jest.fn(), 16 | greaterThan: jest.fn(), 17 | lessThan: jest.fn(), 18 | startClock: jest.fn(), 19 | stopClock: jest.fn(), 20 | clockRunning: jest.fn(), 21 | not: jest.fn(), 22 | or: jest.fn(), 23 | and: jest.fn(), 24 | spring: jest.fn(), 25 | decay: jest.fn(), 26 | defined: jest.fn(), 27 | call: jest.fn(), 28 | Code: View, 29 | block: jest.fn(), 30 | abs: jest.fn(), 31 | greaterOrEq: jest.fn(), 32 | lessOrEq: jest.fn(), 33 | debug: jest.fn(), 34 | Easing: { 35 | in: jest.fn(), 36 | out: jest.fn(), 37 | }, 38 | Transition: { 39 | Out: 'Out', 40 | }, 41 | }; 42 | }); 43 | 44 | jest.mock('react-native-gesture-handler', () => { 45 | const View = require('react-native/Libraries/Components/View/View'); 46 | return { 47 | Swipeable: View, 48 | DrawerLayout: View, 49 | State: {}, 50 | ScrollView: View, 51 | Slider: View, 52 | Switch: View, 53 | TextInput: View, 54 | ToolbarAndroid: View, 55 | ViewPagerAndroid: View, 56 | DrawerLayoutAndroid: View, 57 | WebView: View, 58 | NativeViewGestureHandler: View, 59 | TapGestureHandler: View, 60 | FlingGestureHandler: View, 61 | ForceTouchGestureHandler: View, 62 | LongPressGestureHandler: View, 63 | PanGestureHandler: View, 64 | PinchGestureHandler: View, 65 | RotationGestureHandler: View, 66 | /* Buttons */ 67 | RawButton: View, 68 | BaseButton: View, 69 | RectButton: View, 70 | BorderlessButton: View, 71 | /* Other */ 72 | FlatList: View, 73 | gestureHandlerRootHOC: jest.fn(), 74 | Directions: {}, 75 | }; 76 | }); 77 | 78 | mocks.initAll(); 79 | -------------------------------------------------------------------------------- /examples/react-native/components/lightbox/BaseLightbox.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {View, StyleSheet, Animated, Dimensions, Button} from 'react-native'; 4 | import {Actions} from 'react-native-router-flux'; 5 | 6 | const {height: deviceHeight, width: deviceWidth} = Dimensions.get('window'); 7 | 8 | export default class BaseLightbox extends Component { 9 | static propTypes = { 10 | children: PropTypes.any, 11 | horizontalPercent: PropTypes.number, 12 | verticalPercent: PropTypes.number, 13 | }; 14 | 15 | constructor(props) { 16 | super(props); 17 | 18 | this.state = { 19 | opacity: new Animated.Value(0), 20 | }; 21 | } 22 | 23 | componentDidMount() { 24 | Animated.timing(this.state.opacity, { 25 | duration: 500, 26 | toValue: 1, 27 | }).start(); 28 | } 29 | 30 | closeModal = () => { 31 | Animated.timing(this.state.opacity, { 32 | duration: 500, 33 | toValue: 0, 34 | }).start(Actions.pop); 35 | }; 36 | 37 | _renderLightBox = () => { 38 | const {children, horizontalPercent = 1, verticalPercent = 1} = this.props; 39 | const height = verticalPercent 40 | ? deviceHeight * verticalPercent 41 | : deviceHeight; 42 | const width = horizontalPercent 43 | ? deviceWidth * horizontalPercent 44 | : deviceWidth; 45 | return ( 46 | 54 | {children} 55 | 66 | )} 67 | {this.props.name === 'tab_2_1' && ( 68 | 71 | )} 72 | 73 | 79 | 85 | 91 | 97 | 103 | 109 | 115 | 121 | {this.props.name === 'tab_2_1' && ( 122 | 123 | )} 124 | 125 | ); 126 | } 127 | } 128 | TabView.propTypes = propTypes; 129 | TabView.defaultProps = defaultProps; 130 | 131 | export default TabView; 132 | -------------------------------------------------------------------------------- /examples/react-native/ios/Example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/redux/ios/rnrfReduxSample/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/pathParser.js: -------------------------------------------------------------------------------- 1 | import pathToRegexp from 'path-to-regexp'; 2 | 3 | /** 4 | * 5 | * This set of functions are used to match a url with a uri path. 6 | * This functionality is based on the internals of React-Router's matchPath. 7 | * - https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/matchPath.md 8 | * 9 | */ 10 | 11 | /** 12 | * This function accepts a uri path and returns a regex to match that path 13 | * against a url and an array of the keys extracted from that uri path 14 | * 15 | * @param {String} path - a uri path in standard template (https://tools.ietf.org/html/rfc6570) 16 | * 17 | * Sample Input: "/user/:id/" 18 | * 19 | * Sample Output: 20 | * { 21 | * re: /^\/user\/([^\/]+?)\/(?:\/(?=$))?/i, 22 | * keys: [ 23 | * name: "id" 24 | * delimiter: "/" 25 | * optional: false 26 | * partial: false 27 | * path: "[^\/]+?" 28 | * prefix: "/" 29 | * repeat: false, 30 | * ] 31 | * } 32 | */ 33 | const compilePathToRegex = (path) => { 34 | const keys = []; 35 | const re = pathToRegexp(path, keys); 36 | // Returns the regex path to match a uri path to an actual url 37 | // and the keys that can be used to pull values from the url. 38 | return { re, keys }; 39 | }; 40 | 41 | /** 42 | * This function accepts a uri path and an actual url. It determines whether 43 | * or not they match one another. If they do not match, the funtion returns null. 44 | * If they do match, then the function returns the path and the params parsed 45 | * from the url. 46 | * 47 | * @param {String} path - a uri path in standard template (https://tools.ietf.org/html/rfc6570) 48 | * @param {String} url - a url that may or may not match the given path 49 | * 50 | * Case 1 - path Does Not Match Url: 51 | * Sample Input: (path: "/edit/organization/(:id)", url: "/user/300002/") 52 | * 53 | * Sample Output: null 54 | * 55 | * Case 2 - path Does Match Url: 56 | * Sample Input: (path: "/user/:id/", url: "/user/300002/") 57 | * 58 | * Sample Output: 59 | * { 60 | * path: "/user/:id/", 61 | * params: { 62 | * id: "300002", 63 | * } 64 | * } 65 | * 66 | */ 67 | export const matchPath = (path, url) => { 68 | // Remove possible query fragments, which are not supported by iOS and some 69 | // versions of Anroid. 70 | const [urlCleaned] = url.split('?'); 71 | 72 | // Append trailing slash for compatibility with pathToRegexp 73 | const urlToMatch = !urlCleaned.endsWith('/') ? `${urlCleaned}/` : urlCleaned; 74 | 75 | // Return the regex and the keys that can be parsed from a uri path. 76 | const { re, keys } = compilePathToRegex(path); 77 | 78 | // Check if the given url matches the uri path. 79 | const match = re.exec(urlToMatch); 80 | 81 | // If there is no match, then return null. 82 | if (!match) { 83 | return null; 84 | } 85 | 86 | // Destructure to return the compiled url (aka the reconstructed url based 87 | // on the regex and the url parameters. 88 | const [compiledUrl, ...values] = match; 89 | 90 | // If there is an inexact match (aka the compiled path does not match the 91 | // given url, then return null) 92 | if (urlToMatch !== compiledUrl) { 93 | return null; 94 | } 95 | 96 | const params = keys.reduce((acc, key, index) => Object.assign({}, acc, { [key.name]: values[index] }), {}); 97 | 98 | return { path, params }; 99 | }; 100 | 101 | /** 102 | * This function accepts an array of uri paths and a url. If there are no paths 103 | * in the array that match the given url, then the function will return null. 104 | * If there is at least one matching uri path, it will return the first 105 | * matching path and the parsed url parameters (the output from matchPath()). 106 | * 107 | * @param {Array} possibleMatchingpaths - an array of uri paths in standard template (https://tools.ietf.org/html/rfc6570) 108 | * @param {String} url - a url that may or may not match a given path 109 | * 110 | */ 111 | const pathParser = (url, possibleMatchingpaths = []) => possibleMatchingpaths.map(path => matchPath(path, url)).find(obj => obj); 112 | 113 | export default pathParser; 114 | -------------------------------------------------------------------------------- /examples/expo/navigation/AppNavigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Platform, StyleSheet, Text, View } from 'react-native'; 3 | import { StackViewStyleInterpolator } from 'react-navigation-stack'; 4 | import { 5 | Scene, 6 | Router, 7 | Actions, 8 | Reducer, 9 | ActionConst, 10 | Overlay, 11 | Tabs, 12 | Modal, 13 | Drawer, 14 | Stack, 15 | Lightbox, 16 | } from 'react-native-router-flux'; 17 | import TabBarIcon from '../components/TabBarIcon'; 18 | import MenuIcon from '../components/MenuIcon'; 19 | import DrawerContent from '../components/DrawerContent'; 20 | import HomeScreen from '../screens/HomeScreen'; 21 | import LinksScreen from '../screens/LinksScreen'; 22 | import SettingsScreen from '../screens/SettingsScreen'; 23 | 24 | const styles = StyleSheet.create({ 25 | container: { 26 | flex: 1, 27 | backgroundColor: 'transparent', 28 | justifyContent: 'center', 29 | alignItems: 'center', 30 | }, 31 | tabBarStyle: { 32 | backgroundColor: '#eee', 33 | }, 34 | tabBarSelectedItemStyle: { 35 | backgroundColor: '#ddd', 36 | }, 37 | }); 38 | 39 | const reducerCreate = params => { 40 | const defaultReducer = new Reducer(params); 41 | return (state, action) => { 42 | console.log('reducer: ACTION:', action); 43 | return defaultReducer(state, action); 44 | }; 45 | }; 46 | 47 | const stateHandler = (prevState, newState, action) => { 48 | console.log('onStateChange: ACTION:', action); 49 | }; 50 | 51 | const getSceneStyle = () => ({ 52 | backgroundColor: '#F5FCFF', 53 | shadowOpacity: 1, 54 | shadowRadius: 3, 55 | }); 56 | 57 | // on Android, the URI prefix typically contains a host in addition to scheme 58 | const prefix = Platform.OS === 'android' ? 'mychat://mychat/' : 'mychat://'; 59 | 60 | const transitionConfig = () => ({ 61 | screenInterpolator: 62 | StackViewStyleInterpolator.forFadeFromBottomAndroid, 63 | }); 64 | 65 | const AppNavigator = () => ( 66 | 71 | 72 | 73 | 74 | 75 | 76 | { 80 | console.log('Drawer closed'); 81 | }} 82 | onEnter={() => { 83 | console.log('Drawer opened'); 84 | }} 85 | contentComponent={DrawerContent} 86 | drawerIcon={MenuIcon} 87 | drawerWidth={300}> 88 | 89 | { 93 | console.log('Back to initial and also print this'); 94 | }} 95 | swipeEnabled 96 | tabBarStyle={styles.tabBarStyle} 97 | activeBackgroundColor="white" 98 | inactiveBackgroundColor="rgba(255, 0, 0, 0.5)"> 99 | 106 | 113 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | ); 129 | 130 | export default AppNavigator; 131 | -------------------------------------------------------------------------------- /docs/v3/MINI_TUTORIAL.md: -------------------------------------------------------------------------------- 1 | # Mini-Tutorial 2 | 3 | ![super_simple.gif](super_simple.gif) 4 | 5 | In this super simple example, we will just have three files: 6 | 7 | 1. Your root index file: `index.js` 8 | 2. The first page that is loaded automatically: `PageOne.js` 9 | 3. A second page you can navigate to: `PageTwo.js` 10 | 11 | ### index.js 12 | ```jsx 13 | import React, { Component } from 'react'; 14 | import { Router, Scene } from 'react-native-router-flux'; 15 | 16 | import PageOne from './PageOne'; 17 | import PageTwo from './PageTwo'; 18 | 19 | export default class App extends Component { 20 | render() { 21 | return ( 22 | 23 | 24 | 25 | 26 | 27 | 28 | ) 29 | } 30 | } 31 | ``` 32 | 33 | In `react-native-router-flux`, each route (or page) is called a ``. Conventionally, your Scenes should be wrapped inside a root Scene before being finally wrapped inside a `` component that is returned in the `render()` function. 34 | 35 | At the very minimum, each `` component should have the following props: 36 | 37 | - **key**: A unique string that can be used to refer to the particular scene. 38 | - **component**: The component to be rendered for that `Scene` or page. 39 | - **title**: The string to be displayed in the nav bar at the top of the screen. 40 | 41 | Note that the first scene we wish to load has the prop `initial={true}` to indicate that it's the scene that should be initially rendered. 42 | 43 | ## From Page to Page 44 | 45 | ### PageOne.js 46 | ```jsx 47 | import React, { Component } from 'react'; 48 | import { View, Text } from 'react-native'; 49 | import { Actions } from 'react-native-router-flux'; 50 | 51 | export default class PageOne extends Component { 52 | render() { 53 | return ( 54 | 55 | This is PageOne! 56 | 57 | ) 58 | } 59 | } 60 | ``` 61 | 62 | To navigate from one route to another, an `Action` must be called. This takes the form of: 63 | 64 | ``` 65 | Actions.SCENE_KEY(PARAMS) 66 | ``` 67 | 68 | Where `SCENE_KEY` must match the `key` prop defined in one of the Scenes of the `Router` component in the root file. And `PARAMS` refers to a javascript object that will be passed into the resulting scene as props (more on this later). 69 | 70 | Since the PageTwo component has the key of `pageTwo`, all we need to do is to pass in the function `Actions.pageTwo` into the `` component so that it executes the page transition when the text is pressed. 71 | 72 | ## Passing Information 73 | 74 | Now let's try to extend our example so that we can pass data from `PageOne` to `PageTwo`. 75 | 76 | In `PageOne.js`, instead of simply passing in `Actions.pageTwo`, we can replace it with `Actions.pageTwo({text: 'Hello World!'})`. In this case, we need to wrap the Action call inside a function to prevent it from executing when this component is rendered. As a result, the render function inside `PageOne.js` should look like this: 77 | 78 | ```jsx 79 | render() { 80 | const goToPageTwo = () => Actions.pageTwo({text: 'Hello World!'}); 81 | return ( 82 | 83 | This is PageOne! 84 | 85 | ) 86 | } 87 | ``` 88 | 89 | And in `PageTwo.js`, we can use the data being passed in by adding an additional `` component below the existing one like so: 90 | 91 | ```jsx 92 | render() { 93 | return ( 94 | 95 | This is PageTwo! 96 | {this.props.text} 97 | 98 | ) 99 | } 100 | ``` 101 | 102 | Now, if we navigate to the PageTwo Scene as before, we should see: 103 | 104 | ``` 105 | This is PageTwo! 106 | Hello World! 107 | ``` 108 | 109 | ## Going Forward (or backwards?) 110 | 111 | That pretty much concludes this mini-tutorial, we've covered most of the basics here. There are a lot of things you can do to customize `react-native-router-flux`, this is only the beginning. 112 | 113 | For example, you may want to programmatically go back to the previous Scene. The included navbar already allows you to do this by pressing on the arrow icon at the upper left corner. But you can also call this function at any point in your app for the same effect: 114 | 115 | ```js 116 | Actions.pop() 117 | ``` 118 | 119 | And should you ever want to refresh the same Scene with new props, you can use: 120 | 121 | ```js 122 | Actions.refresh(PARAMS) 123 | ``` 124 | 125 | Don't be afraid to explore the docs, you'll be surprised at how much you're able to customize with `react-native-router-flux`! 126 | -------------------------------------------------------------------------------- /docs/v3/DETAILED_EXAMPLE.md: -------------------------------------------------------------------------------- 1 | ## Detailed Example 2 | 3 | for latest example code, please see [Example](https://github.com/aksonov/react-native-router-flux/blob/master/Example/Example.js) 4 | 5 | ![launch](https://cloud.githubusercontent.com/assets/1321329/11692367/7337cfe2-9e9f-11e5-8515-e8b7a9f230ec.gif) 6 | 7 | ```jsx 8 | import React, {AppRegistry, Navigator, StyleSheet, Text, View} from 'react-native' 9 | import Launch from './components/Launch' 10 | import Register from './components/Register' 11 | import Login from './components/Login' 12 | import Login2 from './components/Login2' 13 | import { Scene, Router, TabBar, Modal, Schema, Actions, Reducer, ActionConst } from 'react-native-router-flux' 14 | import Error from './components/Error' 15 | import Home from './components/Home' 16 | import TabView from './components/TabView' 17 | 18 | class TabIcon extends React.Component { 19 | render(){ 20 | return ( 21 | {this.props.title} 22 | ); 23 | } 24 | } 25 | 26 | const reducerCreate = params=>{ 27 | const defaultReducer = Reducer(params); 28 | return (state, action)=>{ 29 | console.log("ACTION:", action); 30 | return defaultReducer(state, action); 31 | } 32 | }; 33 | 34 | export default class Example extends React.Component { 35 | render() { 36 | return 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | alert("Right button")} rightTitle="Right" /> 50 | 51 | 52 | 53 | alert("Left button!")} leftTitle="Left"/> 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | ; 64 | } 65 | } 66 | 67 | ``` 68 | 69 | components/Launch.js (initial screen) 70 | 71 | ```jsx 72 | import React, {View, Text, StyleSheet, TouchableHighlight} from 'react-native' 73 | import Button from 'react-native-button' 74 | import {Actions} from 'react-native-router-flux' 75 | 76 | class Launch extends React.Component { 77 | render(){ 78 | return ( 79 | 80 | Launch page 81 | 82 | 83 | 84 | 85 | 86 | 87 | ); 88 | } 89 | } 90 | 91 | var styles = StyleSheet.create({ 92 | container: { 93 | flex: 1, 94 | justifyContent: 'center', 95 | alignItems: 'center', 96 | backgroundColor: 'transparent', 97 | } 98 | }); 99 | 100 | module.exports = Launch; 101 | ``` 102 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribute 2 | 3 | ## Introduction 4 | 5 | First, thank you for considering contributing to react-native-router-flux! It's people like you that make the open source community such a great community! 😊 6 | 7 | We welcome any type of contribution, not only code. You can help with 8 | - **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open) 9 | - **Marketing**: writing blog posts, howto's, printing stickers, ... 10 | - **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ... 11 | - **Code**: take a look at the [open issues](https://github.com/aksonov/react-native-router-flux/issues?q=is%3Aopen+is%3Aissue). Even if you can't write code, commenting on them, showing that you care about a given issue matters. It helps us triage them. To get started you can also [sign up to triage react-native-router-flux issues on CodeTriage](https://www.codetriage.com/aksonov/react-native-router-flux). 12 | - **Money**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/react-native-router-flux). 13 | 14 | ## Your First Contribution 15 | 16 | Working on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). 17 | 18 | ## Submitting code 19 | 20 | Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. The pull request should also contain tests. 21 | 22 | ## Code review process 23 | 24 | The bigger the pull request, the longer it will take to review and merge. Try to break down large pull requests in smaller chunks that are easier to review and merge. 25 | It is also always helpful to have some context for your pull request. What was the purpose? Why does it matter to you? 26 | 27 | ## Financial contributions 28 | 29 | We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/react-native-router-flux). 30 | Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed. 31 | 32 | ## Questions 33 | 34 | If you have any questions, create an [issue](issue) (protip: do a quick search first to see if someone else didn't ask the same question before!). 35 | You can also reach us at hello@react-native-router-flux.opencollective.com. 36 | 37 | ## Credits 38 | 39 | ### Contributors 40 | 41 | Thank you to all the people who have already contributed to react-native-router-flux! 42 | 43 | 44 | 45 | ### Backers 46 | 47 | Thank you to all our backers! [[Become a backer](https://opencollective.com/react-native-router-flux#backer)] 48 | 49 | 50 | 51 | 52 | ### Sponsors 53 | 54 | Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/react-native-router-flux#sponsor)) 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | --------------------------------------------------------------------------------