├── Example
├── .watchmanconfig
├── .gitattributes
├── .babelrc
├── app.json
├── android
│ ├── app
│ │ ├── src
│ │ │ └── main
│ │ │ │ ├── res
│ │ │ │ ├── values
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ └── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── assets
│ │ │ │ └── fonts
│ │ │ │ │ ├── Entypo.ttf
│ │ │ │ │ ├── Zocial.ttf
│ │ │ │ │ ├── Feather.ttf
│ │ │ │ │ ├── Ionicons.ttf
│ │ │ │ │ ├── Octicons.ttf
│ │ │ │ │ ├── EvilIcons.ttf
│ │ │ │ │ ├── FontAwesome.ttf
│ │ │ │ │ ├── Foundation.ttf
│ │ │ │ │ ├── MaterialIcons.ttf
│ │ │ │ │ ├── SimpleLineIcons.ttf
│ │ │ │ │ └── MaterialCommunityIcons.ttf
│ │ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ └── MainApplication.java
│ │ │ │ └── AndroidManifest.xml
│ │ ├── BUCK
│ │ ├── proguard-rules.pro
│ │ └── build.gradle
│ ├── keystores
│ │ ├── debug.keystore.properties
│ │ └── BUCK
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── settings.gradle
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradlew.bat
│ └── gradlew
├── .buckconfig
├── index.ios.js
├── index.android.js
├── __tests__
│ ├── index.ios.js
│ └── index.android.js
├── SimpleExample.js
├── ios
│ ├── Example
│ │ ├── AppDelegate.h
│ │ ├── main.m
│ │ ├── Images.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── AppDelegate.m
│ │ ├── Info.plist
│ │ └── Base.lproj
│ │ │ └── LaunchScreen.xib
│ ├── ExampleTests
│ │ ├── Info.plist
│ │ └── ExampleTests.m
│ ├── Example-tvOSTests
│ │ └── Info.plist
│ ├── Example-tvOS
│ │ └── Info.plist
│ └── Example.xcodeproj
│ │ └── xcshareddata
│ │ └── xcschemes
│ │ ├── Example.xcscheme
│ │ └── Example-tvOS.xcscheme
├── ScrollableTabsExample.js
├── package.json
├── .gitignore
├── .flowconfig
├── OverlayExample.js
├── FacebookExample.js
├── DynamicExample.js
├── FacebookTabBar.js
└── index.js
├── .npmignore
├── .gitignore
├── Button.ios.js
├── StaticContainer.js
├── Button.android.js
├── SceneComponent.js
├── .github
└── ISSUE_TEMPLATE.md
├── package.json
├── DefaultTabBar.js
├── README.md
├── .eslintrc
├── ScrollableTabBar.js
├── index.js
└── yarn.lock
/Example/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | Example
2 | .github/
--------------------------------------------------------------------------------
/Example/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/Example/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react-native"]
3 | }
4 |
--------------------------------------------------------------------------------
/Example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Example",
3 | "displayName": "Example"
4 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .project
2 | npm-debug.log
3 | node_modules/
4 | .idea/
5 | .reploy
6 | .DS_Store
7 |
--------------------------------------------------------------------------------
/Example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Example
3 |
4 |
--------------------------------------------------------------------------------
/Example/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/Example/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 |
--------------------------------------------------------------------------------
/Example/index.ios.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry, } from 'react-native';
2 | import Example from './index.js';
3 |
4 | AppRegistry.registerComponent('Example', () => Example);
5 |
--------------------------------------------------------------------------------
/Example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/Example/index.android.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry, } from 'react-native';
2 | import Example from './index.js';
3 |
4 | AppRegistry.registerComponent('Example', () => Example);
5 |
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/Entypo.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/Zocial.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/Feather.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/Feather.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/Ionicons.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/Octicons.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/EvilIcons.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/FontAwesome.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/Foundation.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/MaterialIcons.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/SimpleLineIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/SimpleLineIcons.ttf
--------------------------------------------------------------------------------
/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Example/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ptomasroos/react-native-scrollable-tab-view/HEAD/Example/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf
--------------------------------------------------------------------------------
/Example/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = "debug",
3 | properties = "debug.keystore.properties",
4 | store = "debug.keystore",
5 | visibility = [
6 | "PUBLIC",
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/Example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'Example'
2 | include ':react-native-vector-icons'
3 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
4 |
5 | include ':app'
6 |
--------------------------------------------------------------------------------
/Example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/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-2.14.1-all.zip
6 |
--------------------------------------------------------------------------------
/Button.ios.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactNative = require('react-native');
3 | const {
4 | TouchableOpacity,
5 | View,
6 | } = ReactNative;
7 |
8 | const Button = (props) => {
9 | return
10 | {props.children}
11 | ;
12 | };
13 |
14 | module.exports = Button;
15 |
--------------------------------------------------------------------------------
/Example/__tests__/index.ios.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react';
3 | import Index from '../index.ios.js';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create(
10 |
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/Example/__tests__/index.android.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react';
3 | import Index from '../index.android.js';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create(
10 |
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/Example/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.
9 | * This is used to schedule rendering of the component.
10 | */
11 | @Override
12 | protected String getMainComponentName() {
13 | return "Example";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/StaticContainer.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 |
3 | class StaticContainer extends React.Component {
4 |
5 | shouldComponentUpdate(nextProps: Object): boolean {
6 | return !!nextProps.shouldUpdate;
7 | }
8 |
9 | render(): ?ReactElement {
10 | var child = this.props.children;
11 | if (child === null || child === false) {
12 | return null;
13 | }
14 | return React.Children.only(child);
15 | }
16 |
17 | }
18 |
19 | module.exports = StaticContainer;
20 |
--------------------------------------------------------------------------------
/Button.android.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactNative = require('react-native');
3 | const {
4 | TouchableNativeFeedback,
5 | View,
6 | } = ReactNative;
7 |
8 | const Button = (props) => {
9 | return
14 | {props.children}
15 | ;
16 | };
17 |
18 | module.exports = Button;
19 |
--------------------------------------------------------------------------------
/Example/SimpleExample.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Text,
4 | } from 'react-native';
5 |
6 | import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
7 |
8 | export default () => {
9 | return }
13 | >
14 | My
15 | favorite
16 | project
17 | ;
18 | }
19 |
--------------------------------------------------------------------------------
/Example/ios/Example/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
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. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/SceneComponent.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactNative = require('react-native');
3 | const { Component } = React;
4 | const { View, StyleSheet } = ReactNative;
5 |
6 | const StaticContainer = require('./StaticContainer');
7 |
8 | const SceneComponent = (Props) => {
9 | const { shouldUpdated, ...props } = Props;
10 | return
11 |
12 | {props.children}
13 |
14 | ;
15 | };
16 |
17 | module.exports = SceneComponent;
18 |
--------------------------------------------------------------------------------
/Example/ios/Example/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
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. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Example/ScrollableTabsExample.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Text,
4 | View,
5 | } from 'react-native';
6 |
7 | import ScrollableTabView, { ScrollableTabBar } from 'react-native-scrollable-tab-view';
8 |
9 | export default () => {
10 | return }
14 | >
15 | My
16 | favorite
17 | project
18 | favorite
19 | project
20 | ;
21 | }
22 |
--------------------------------------------------------------------------------
/Example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Example",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node node_modules/react-native/local-cli/cli.js start",
7 | "test": "jest"
8 | },
9 | "dependencies": {
10 | "create-react-class": "^15.6.2",
11 | "react": "16.0.0",
12 | "react-native": "0.48.4",
13 | "react-native-scrollable-tab-view": "file:../",
14 | "react-native-vector-icons": "^4.4.0",
15 | "react-navigation": "^1.0.0-beta.13"
16 | },
17 | "devDependencies": {
18 | "babel-jest": "21.2.0",
19 | "babel-preset-react-native": "4.0.0",
20 | "jest": "21.2.1",
21 | "react-test-renderer": "16.0.0"
22 | },
23 | "jest": {
24 | "preset": "react-native"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Example/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 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenLocal()
18 | jcenter()
19 | maven {
20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 | url "$rootDir/../node_modules/react-native/android"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Example/ios/Example/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/Example/ios/ExampleTests/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 |
--------------------------------------------------------------------------------
/Example/ios/Example-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 |
--------------------------------------------------------------------------------
/Example/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 |
--------------------------------------------------------------------------------
/Example/.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 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
9 |
10 | - [ ] I have searched [existing issues](https://github.com/happypancake/react-native-scrollable-tab-view/issues)
11 | - [ ] I am using the [latest scrollable tab view version](https://www.npmjs.com/package/react-native-scrollable-tab-view)
12 |
13 |
16 |
17 | ## Steps to Reproduce
18 |
21 |
22 | ## Expected Behavior
23 |
26 |
27 | ## Actual Behavior
28 |
31 |
--------------------------------------------------------------------------------
/Example/android/app/src/main/java/com/example/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.react.ReactApplication;
6 | import com.oblador.vectoricons.VectorIconsPackage;
7 | import com.facebook.react.ReactNativeHost;
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.shell.MainReactPackage;
10 | import com.facebook.soloader.SoLoader;
11 |
12 | import java.util.Arrays;
13 | import java.util.List;
14 |
15 | public class MainApplication extends Application implements ReactApplication {
16 |
17 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
18 | @Override
19 | public boolean getUseDeveloperSupport() {
20 | return BuildConfig.DEBUG;
21 | }
22 |
23 | @Override
24 | protected List getPackages() {
25 | return Arrays.asList(
26 | new MainReactPackage(),
27 | new VectorIconsPackage()
28 | );
29 | }
30 | };
31 |
32 | @Override
33 | public ReactNativeHost getReactNativeHost() {
34 | return mReactNativeHost;
35 | }
36 |
37 | @Override
38 | public void onCreate() {
39 | super.onCreate();
40 | SoLoader.init(this, /* native exopackage */ false);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-scrollable-tab-view",
3 | "version": "1.1.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "lint": "eslint -c .eslintrc . --ignore-path .gitignore",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/brentvatne/react-native-scrollable-tab-view.git"
13 | },
14 | "keywords": [
15 | "react-native-component",
16 | "react-component",
17 | "react-native",
18 | "ios",
19 | "tab",
20 | "scrollable"
21 | ],
22 | "author": "Brent Vatne",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/brentvatne/react-native-scrollable-tab-view/issues"
26 | },
27 | "peerDependencies": {
28 | "react-native": ">=0.20.0"
29 | },
30 | "homepage": "https://github.com/brentvatne/react-native-scrollable-tab-view#readme",
31 | "dependencies": {
32 | "@react-native-community/viewpager": "3.3.0",
33 | "create-react-class": "^15.6.2",
34 | "deprecated-react-native-prop-types": "^2.3.0",
35 | "prop-types": "^15.6.0",
36 | "react-timer-mixin": "^0.13.3"
37 | },
38 | "devDependencies": {
39 | "babel-eslint": "^6.1.2",
40 | "eslint": "^3.1.1"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Example/ios/Example/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
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. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "AppDelegate.h"
11 |
12 | #import
13 | #import
14 |
15 | @implementation AppDelegate
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
18 | {
19 | NSURL *jsCodeLocation;
20 |
21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
22 |
23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
24 | moduleName:@"Example"
25 | initialProperties:nil
26 | launchOptions:launchOptions];
27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
28 |
29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
30 | UIViewController *rootViewController = [UIViewController new];
31 | rootViewController.view = rootView;
32 | self.window.rootViewController = rootViewController;
33 | [self.window makeKeyAndVisible];
34 | return YES;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/Example/.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-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
38 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[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.49.1
46 |
--------------------------------------------------------------------------------
/Example/OverlayExample.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | ScrollView,
5 | } from 'react-native';
6 |
7 | import ScrollableTabView, { DefaultTabBar, } from 'react-native-scrollable-tab-view';
8 | import Icon from 'react-native-vector-icons/Ionicons';
9 |
10 | // Using tabBarPosition='overlayTop' or 'overlayBottom' lets the content show through a
11 | // semitransparent tab bar. Note that if you build a custom tab bar component, its outer container
12 | // must consume a 'style' prop (e.g. {
14 | return }
17 | tabBarPosition='overlayTop'
18 | >
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ;
31 | }
32 |
33 | const styles = StyleSheet.create({
34 | container: {
35 | marginTop: 30,
36 | },
37 | icon: {
38 | width: 300,
39 | height: 300,
40 | alignSelf: 'center',
41 | },
42 | });
43 |
--------------------------------------------------------------------------------
/Example/ios/Example-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 |
--------------------------------------------------------------------------------
/Example/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.example",
49 | )
50 |
51 | android_resource(
52 | name = "res",
53 | package = "com.example",
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 |
--------------------------------------------------------------------------------
/Example/FacebookExample.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | Text,
5 | View,
6 | ScrollView,
7 | } from 'react-native';
8 |
9 | import FacebookTabBar from './FacebookTabBar';
10 | import ScrollableTabView from 'react-native-scrollable-tab-view';
11 |
12 | export default () => {
13 | return }
17 | >
18 |
19 |
20 | News
21 |
22 |
23 |
24 |
25 | Friends
26 |
27 |
28 |
29 |
30 | Messenger
31 |
32 |
33 |
34 |
35 | Notifications
36 |
37 |
38 |
39 |
40 | Other nav
41 |
42 |
43 | ;
44 | }
45 |
46 | const styles = StyleSheet.create({
47 | tabView: {
48 | flex: 1,
49 | padding: 10,
50 | backgroundColor: 'rgba(0,0,0,0.01)',
51 | },
52 | card: {
53 | borderWidth: 1,
54 | backgroundColor: '#fff',
55 | borderColor: 'rgba(0,0,0,0.1)',
56 | margin: 5,
57 | height: 150,
58 | padding: 15,
59 | shadowColor: '#ccc',
60 | shadowOffset: { width: 2, height: 2, },
61 | shadowOpacity: 0.5,
62 | shadowRadius: 3,
63 | },
64 | });
65 |
--------------------------------------------------------------------------------
/Example/DynamicExample.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Text,
4 | TouchableHighlight,
5 | } from 'react-native';
6 | import TimerMixin from 'react-timer-mixin';
7 | import ScrollableTabView, { ScrollableTabBar, } from 'react-native-scrollable-tab-view';
8 | import createReactClass from 'create-react-class';
9 |
10 | const Child = createReactClass({
11 | onEnter() {
12 | console.log('enter: ' + this.props.i); // eslint-disable-line no-console
13 | },
14 |
15 | onLeave() {
16 | console.log('leave: ' + this.props.i); // eslint-disable-line no-console
17 | },
18 |
19 | render() {
20 | const i = this.props.i;
21 | return {`tab${i}`};
22 | },
23 | });
24 |
25 | export default createReactClass({
26 | mixins: [TimerMixin, ],
27 | children: [],
28 |
29 | getInitialState() {
30 | return {
31 | tabs: [1, 2],
32 | };
33 | },
34 |
35 | componentDidMount() {
36 | this.setTimeout(
37 | () => { this.setState({ tabs: [1, 2, 3, 4, 5, 6, ], }); },
38 | 100
39 | );
40 | },
41 |
42 | handleChangeTab({i, ref, from, }) {
43 | this.children[i].onEnter();
44 | this.children[from].onLeave();
45 | },
46 |
47 | renderTab(name, page, isTabActive, onPressHandler, onLayoutHandler) {
48 | return onPressHandler(page)}
51 | onLayout={onLayoutHandler}
52 | style={{flex: 1, width: 100, }}
53 | underlayColor="#aaaaaa"
54 | >
55 | {name}
56 | ;
57 | },
58 |
59 | render() {
60 | return }
63 | onChangeTab={this.handleChangeTab}
64 | >
65 | {this.state.tabs.map((tab, i) => {
66 | return (this.children[i] = ref)}
68 | tabLabel={`tab${i}`}
69 | i={i}
70 | key={i}
71 | />;
72 | })}
73 | ;
74 | },
75 | });
76 |
--------------------------------------------------------------------------------
/Example/FacebookTabBar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | Text,
5 | View,
6 | TouchableOpacity,
7 | } from 'react-native';
8 | import Icon from 'react-native-vector-icons/Ionicons';
9 |
10 | class FacebookTabBar extends React.Component {
11 | icons = [];
12 |
13 | constructor(props) {
14 | super(props);
15 | this.icons = [];
16 | }
17 |
18 | componentDidMount() {
19 | this._listener = this.props.scrollValue.addListener(this.setAnimationValue.bind(this));
20 | }
21 |
22 | setAnimationValue({ value, }) {
23 | this.icons.forEach((icon, i) => {
24 | const progress = (value - i >= 0 && value - i <= 1) ? value - i : 1;
25 | icon.setNativeProps({
26 | style: {
27 | color: this.iconColor(progress),
28 | },
29 | });
30 | });
31 | }
32 |
33 | //color between rgb(59,89,152) and rgb(204,204,204)
34 | iconColor(progress) {
35 | const red = 59 + (204 - 59) * progress;
36 | const green = 89 + (204 - 89) * progress;
37 | const blue = 152 + (204 - 152) * progress;
38 | return `rgb(${red}, ${green}, ${blue})`;
39 | }
40 |
41 | render() {
42 | return
43 | {this.props.tabs.map((tab, i) => {
44 | return this.props.goToPage(i)} style={styles.tab}>
45 | { this.icons[i] = icon; }}
50 | />
51 | ;
52 | })}
53 | ;
54 | }
55 | }
56 |
57 | const styles = StyleSheet.create({
58 | tab: {
59 | flex: 1,
60 | alignItems: 'center',
61 | justifyContent: 'center',
62 | paddingBottom: 10,
63 | },
64 | tabs: {
65 | height: 45,
66 | flexDirection: 'row',
67 | paddingTop: 5,
68 | borderWidth: 1,
69 | borderTopWidth: 0,
70 | borderLeftWidth: 0,
71 | borderRightWidth: 0,
72 | borderBottomColor: 'rgba(0,0,0,0.05)',
73 | },
74 | });
75 |
76 | export default FacebookTabBar;
77 |
--------------------------------------------------------------------------------
/Example/ios/Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
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 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UIViewControllerBasedStatusBarAppearance
40 |
41 | NSLocationWhenInUseUsageDescription
42 |
43 | NSAppTransportSecurity
44 |
45 | NSExceptionDomains
46 |
47 | localhost
48 |
49 | NSExceptionAllowsInsecureHTTPLoads
50 |
51 |
52 |
53 |
54 | UIAppFonts
55 |
56 | Entypo.ttf
57 | EvilIcons.ttf
58 | Feather.ttf
59 | FontAwesome.ttf
60 | Foundation.ttf
61 | Ionicons.ttf
62 | MaterialCommunityIcons.ttf
63 | MaterialIcons.ttf
64 | Octicons.ttf
65 | SimpleLineIcons.ttf
66 | Zocial.ttf
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Example/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | Text,
5 | View,
6 | ScrollView,
7 | TouchableOpacity,
8 | } from 'react-native';
9 | import createReactClass from 'create-react-class';
10 | import { StackNavigator } from 'react-navigation';
11 | import SimpleExample from './SimpleExample';
12 | import ScrollableTabsExample from './ScrollableTabsExample';
13 | import OverlayExample from './OverlayExample';
14 | import FacebookExample from './FacebookExample';
15 | import DynamicExample from './DynamicExample';
16 |
17 | const HomeScreen = createReactClass({
18 | navigationOptions: {
19 | title: 'Welcome',
20 | },
21 |
22 | render() {
23 | const { navigate } = this.props.navigation;
24 |
25 | return
26 | navigate('Simple')}
29 | >
30 | Simple example
31 |
32 |
33 | navigate('Scrollable')}
36 | >
37 | Scrollable tabs example
38 |
39 |
40 | navigate('Overlay')}
43 | >
44 | Overlay example
45 |
46 |
47 | navigate('Facebook')}
50 | >
51 | Facebook tabs example
52 |
53 |
54 | navigate('Dynamic')}
57 | >
58 | Dynamic tabs example
59 |
60 | ;
61 | },
62 | });
63 |
64 | const App = StackNavigator({
65 | Home: { screen: HomeScreen },
66 | Simple: { screen: SimpleExample },
67 | Scrollable: { screen: ScrollableTabsExample },
68 | Overlay: { screen: OverlayExample },
69 | Facebook: { screen: FacebookExample },
70 | Dynamic: { screen: DynamicExample },
71 | });
72 |
73 | export default App;
74 |
75 | const styles = StyleSheet.create({
76 | container: {
77 | flex: 1,
78 | marginTop: 30,
79 | alignItems: 'center',
80 | },
81 | button: {
82 | padding: 10,
83 | },
84 | });
85 |
--------------------------------------------------------------------------------
/Example/ios/ExampleTests/ExampleTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
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. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 | #import
12 |
13 | #import
14 | #import
15 |
16 | #define TIMEOUT_SECONDS 600
17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18 |
19 | @interface ExampleTests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation ExampleTests
24 |
25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
26 | {
27 | if (test(view)) {
28 | return YES;
29 | }
30 | for (UIView *subview in [view subviews]) {
31 | if ([self findSubviewInView:subview matching:test]) {
32 | return YES;
33 | }
34 | }
35 | return NO;
36 | }
37 |
38 | - (void)testRendersWelcomeScreen
39 | {
40 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
42 | BOOL foundElement = NO;
43 |
44 | __block NSString *redboxError = nil;
45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
46 | if (level >= RCTLogLevelError) {
47 | redboxError = message;
48 | }
49 | });
50 |
51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
54 |
55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
57 | return YES;
58 | }
59 | return NO;
60 | }];
61 | }
62 |
63 | RCTSetLogFunction(RCTDefaultLogFunction);
64 |
65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/Example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/Example/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 |
19 | # Disabling obfuscation is useful if you collect stack traces from production crashes
20 | # (unless you are using a system that supports de-obfuscate the stack traces).
21 | -dontobfuscate
22 |
23 | # React Native
24 |
25 | # Keep our interfaces so they can be used by other ProGuard rules.
26 | # See http://sourceforge.net/p/proguard/bugs/466/
27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
30 |
31 | # Do not strip any method/class that is annotated with @DoNotStrip
32 | -keep @com.facebook.proguard.annotations.DoNotStrip class *
33 | -keep @com.facebook.common.internal.DoNotStrip class *
34 | -keepclassmembers class * {
35 | @com.facebook.proguard.annotations.DoNotStrip *;
36 | @com.facebook.common.internal.DoNotStrip *;
37 | }
38 |
39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
40 | void set*(***);
41 | *** get*();
42 | }
43 |
44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; }
46 | -keepclassmembers,includedescriptorclasses class * { native ; }
47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; }
48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; }
49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; }
50 |
51 | -dontwarn com.facebook.react.**
52 |
53 | # TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
54 | # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
55 | -dontwarn android.text.StaticLayout
56 |
57 | # okhttp
58 |
59 | -keepattributes Signature
60 | -keepattributes *Annotation*
61 | -keep class okhttp3.** { *; }
62 | -keep interface okhttp3.** { *; }
63 | -dontwarn okhttp3.**
64 |
65 | # okio
66 |
67 | -keep class sun.misc.Unsafe { *; }
68 | -dontwarn java.nio.file.*
69 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
70 | -dontwarn okio.**
71 |
--------------------------------------------------------------------------------
/DefaultTabBar.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactNative = require('react-native');
3 | const DeprecatedPropTypes = require('deprecated-react-native-prop-types');
4 | const PropTypes = require('prop-types');
5 | const createReactClass = require('create-react-class');
6 | const {
7 | StyleSheet,
8 | Text,
9 | View,
10 | Animated,
11 | } = ReactNative;
12 | const Button = require('./Button');
13 |
14 | const DefaultTabBar = createReactClass({
15 | propTypes: {
16 | goToPage: PropTypes.func,
17 | activeTab: PropTypes.number,
18 | tabs: PropTypes.array,
19 | backgroundColor: PropTypes.string,
20 | activeTextColor: PropTypes.string,
21 | inactiveTextColor: PropTypes.string,
22 | textStyle: DeprecatedPropTypes.TextPropTypes.style,
23 | tabStyle: DeprecatedPropTypes.ViewPropTypes.style,
24 | renderTab: PropTypes.func,
25 | underlineStyle: DeprecatedPropTypes.ViewPropTypes.style,
26 | },
27 |
28 | getDefaultProps() {
29 | return {
30 | activeTextColor: 'navy',
31 | inactiveTextColor: 'black',
32 | backgroundColor: null,
33 | };
34 | },
35 |
36 | renderTabOption(name, page) {
37 | },
38 |
39 | renderTab(name, page, isTabActive, onPressHandler) {
40 | const { activeTextColor, inactiveTextColor, textStyle, } = this.props;
41 | const textColor = isTabActive ? activeTextColor : inactiveTextColor;
42 | const fontWeight = isTabActive ? 'bold' : 'normal';
43 |
44 | return ;
58 | },
59 |
60 | render() {
61 | const containerWidth = this.props.containerWidth;
62 | const numberOfTabs = this.props.tabs.length;
63 | const tabUnderlineStyle = {
64 | position: 'absolute',
65 | width: containerWidth / numberOfTabs,
66 | height: 4,
67 | backgroundColor: 'navy',
68 | bottom: 0,
69 | };
70 |
71 | const translateX = this.props.scrollValue.interpolate({
72 | inputRange: [0, 1],
73 | outputRange: [0, containerWidth / numberOfTabs],
74 | });
75 | return (
76 |
77 | {this.props.tabs.map((name, page) => {
78 | const isTabActive = this.props.activeTab === page;
79 | const renderTab = this.props.renderTab || this.renderTab;
80 | return renderTab(name, page, isTabActive, this.props.goToPage);
81 | })}
82 |
93 |
94 | );
95 | },
96 | });
97 |
98 | const styles = StyleSheet.create({
99 | tab: {
100 | flex: 1,
101 | alignItems: 'center',
102 | justifyContent: 'center',
103 | paddingBottom: 10,
104 | },
105 | tabs: {
106 | height: 50,
107 | flexDirection: 'row',
108 | justifyContent: 'space-around',
109 | borderWidth: 1,
110 | borderTopWidth: 0,
111 | borderLeftWidth: 0,
112 | borderRightWidth: 0,
113 | borderColor: '#ccc',
114 | },
115 | });
116 |
117 | module.exports = DefaultTabBar;
118 |
--------------------------------------------------------------------------------
/Example/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 |
--------------------------------------------------------------------------------
/Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
61 |
67 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
111 |
113 |
119 |
120 |
121 |
122 |
124 |
125 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
61 |
67 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
111 |
113 |
119 |
120 |
121 |
122 |
124 |
125 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/Example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/Example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 |
3 | import com.android.build.OutputFile
4 |
5 | /**
6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
7 | * and bundleReleaseJsAndAssets).
8 | * These basically call `react-native bundle` with the correct arguments during the Android build
9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
10 | * bundle directly from the development server. Below you can see all the possible configurations
11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the
12 | * `apply from: "../../node_modules/react-native/react.gradle"` line.
13 | *
14 | * project.ext.react = [
15 | * // the name of the generated asset file containing your JS bundle
16 | * bundleAssetName: "index.android.bundle",
17 | *
18 | * // the entry file for bundle generation
19 | * entryFile: "index.android.js",
20 | *
21 | * // whether to bundle JS and assets in debug mode
22 | * bundleInDebug: false,
23 | *
24 | * // whether to bundle JS and assets in release mode
25 | * bundleInRelease: true,
26 | *
27 | * // whether to bundle JS and assets in another build variant (if configured).
28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
29 | * // The configuration property can be in the following formats
30 | * // 'bundleIn${productFlavor}${buildType}'
31 | * // 'bundleIn${buildType}'
32 | * // bundleInFreeDebug: true,
33 | * // bundleInPaidRelease: true,
34 | * // bundleInBeta: true,
35 | *
36 | * // whether to disable dev mode in custom build variants (by default only disabled in release)
37 | * // for example: to disable dev mode in the staging build type (if configured)
38 | * devDisabledInStaging: true,
39 | * // The configuration property can be in the following formats
40 | * // 'devDisabledIn${productFlavor}${buildType}'
41 | * // 'devDisabledIn${buildType}'
42 | *
43 | * // the root of your project, i.e. where "package.json" lives
44 | * root: "../../",
45 | *
46 | * // where to put the JS bundle asset in debug mode
47 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
48 | *
49 | * // where to put the JS bundle asset in release mode
50 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
51 | *
52 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
53 | * // require('./image.png')), in debug mode
54 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
55 | *
56 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
57 | * // require('./image.png')), in release mode
58 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
59 | *
60 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
61 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
62 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
63 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
64 | * // for example, you might want to remove it from here.
65 | * inputExcludes: ["android/**", "ios/**"],
66 | *
67 | * // override which node gets called and with what additional arguments
68 | * nodeExecutableAndArgs: ["node"],
69 | *
70 | * // supply additional arguments to the packager
71 | * extraPackagerArgs: []
72 | * ]
73 | */
74 |
75 | apply from: "../../node_modules/react-native/react.gradle"
76 |
77 | /**
78 | * Set this to true to create two separate APKs instead of one:
79 | * - An APK that only works on ARM devices
80 | * - An APK that only works on x86 devices
81 | * The advantage is the size of the APK is reduced by about 4MB.
82 | * Upload all the APKs to the Play Store and people will download
83 | * the correct one based on the CPU architecture of their device.
84 | */
85 | def enableSeparateBuildPerCPUArchitecture = false
86 |
87 | /**
88 | * Run Proguard to shrink the Java bytecode in release builds.
89 | */
90 | def enableProguardInReleaseBuilds = false
91 |
92 | android {
93 | compileSdkVersion 23
94 | buildToolsVersion "23.0.1"
95 |
96 | defaultConfig {
97 | applicationId "com.example"
98 | minSdkVersion 16
99 | targetSdkVersion 22
100 | versionCode 1
101 | versionName "1.0"
102 | ndk {
103 | abiFilters "armeabi-v7a", "x86"
104 | }
105 | }
106 | splits {
107 | abi {
108 | reset()
109 | enable enableSeparateBuildPerCPUArchitecture
110 | universalApk false // If true, also generate a universal APK
111 | include "armeabi-v7a", "x86"
112 | }
113 | }
114 | buildTypes {
115 | release {
116 | minifyEnabled enableProguardInReleaseBuilds
117 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
118 | }
119 | }
120 | // applicationVariants are e.g. debug, release
121 | applicationVariants.all { variant ->
122 | variant.outputs.each { output ->
123 | // For each separate APK per architecture, set a unique version code as described here:
124 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
125 | def versionCodes = ["armeabi-v7a":1, "x86":2]
126 | def abi = output.getFilter(OutputFile.ABI)
127 | if (abi != null) { // null for the universal-debug, universal-release variants
128 | output.versionCodeOverride =
129 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
130 | }
131 | }
132 | }
133 | }
134 |
135 | dependencies {
136 | compile project(':react-native-vector-icons')
137 | compile fileTree(dir: "libs", include: ["*.jar"])
138 | compile "com.android.support:appcompat-v7:23.0.1"
139 | compile "com.facebook.react:react-native:+" // From node_modules
140 | }
141 |
142 | // Run this once to be able to run the application with BUCK
143 | // puts all compile dependencies into folder libs for BUCK to use
144 | task copyDownloadableDepsToLibs(type: Copy) {
145 | from configurations.compile
146 | into 'libs'
147 | }
148 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## react-native-scrollable-tab-view
3 | [](https://badge.fury.io/js/react-native-scrollable-tab-view)
4 |
5 | This is probably my favorite navigation pattern on Android, I wish it
6 | were more common on iOS! This is a very simple JavaScript-only
7 | implementation of it for React Native. For more information about how
8 | the animations behind this work, check out the Rebound section of the
9 | [React Native Animation Guide](https://facebook.github.io/react-native/docs/animations.html)
10 |
11 |
12 | ## Add it to your project
13 |
14 | 1. Run `npm install react-native-scrollable-tab-view --save`
15 | 2. `var ScrollableTabView = require('react-native-scrollable-tab-view');`
16 |
17 | ## Demo
18 | Run this example
19 |
20 |
21 |
22 |
23 | ## Basic usage
24 |
25 | ```javascript
26 | var ScrollableTabView = require('react-native-scrollable-tab-view');
27 |
28 | var App = React.createClass({
29 | render() {
30 | return (
31 |
32 |
33 |
34 |
35 |
36 | );
37 | }
38 | });
39 | ```
40 |
41 | ## Injecting a custom tab bar
42 |
43 | Suppose we had a custom tab bar called `CustomTabBar`, we would inject
44 | it into our `ScrollableTabView` like this:
45 |
46 | ```javascript
47 | var ScrollableTabView = require('react-native-scrollable-tab-view');
48 | var CustomTabBar = require('./CustomTabBar');
49 |
50 | var App = React.createClass({
51 | render() {
52 | return (
53 | }>
54 |
55 |
56 |
57 |
58 | );
59 | }
60 | });
61 | ```
62 | To start you can just copy [DefaultTabBar](https://github.com/skv-headless/react-native-scrollable-tab-view/blob/master/DefaultTabBar.js).
63 |
64 | ## Examples
65 |
66 | [SimpleExample](https://github.com/skv-headless/react-native-scrollable-tab-view/blob/master/Example/SimpleExample.js).
67 |
68 | [ScrollableTabsExample](https://github.com/skv-headless/react-native-scrollable-tab-view/blob/master/Example/ScrollableTabsExample.js).
69 |
70 | [OverlayExample](https://github.com/skv-headless/react-native-scrollable-tab-view/blob/master/Example/OverlayExample.js).
71 |
72 | [FacebookExample](https://github.com/skv-headless/react-native-scrollable-tab-view/blob/master/Example/FacebookExample.js).
73 |
74 | ## Props
75 |
76 | - **`renderTabBar`** _(Function:ReactComponent)_ - accept 1 argument `props` and should return a component to use as
77 | the tab bar. The component has `goToPage`, `tabs`, `activeTab` and
78 | `ref` added to the props, and should implement `setAnimationValue` to
79 | be able to animate itself along with the tab content. You can manually pass the `props` to the TabBar component.
80 | - **`tabBarPosition`** _(String)_ Defaults to `"top"`.
81 | - `"bottom"` to position the tab bar below content.
82 | - `"overlayTop"` or `"overlayBottom"` for a semitransparent tab bar that overlays content. Custom tab bars must consume a style prop on their outer element to support this feature: `style={this.props.style}`.
83 | - **`onChangeTab`** _(Function)_ - function to call when tab changes, should accept 1 argument which is an Object containing two keys: `i`: the index of the tab that is selected, `ref`: the ref of the tab that is selected
84 | - **`onScroll`** _(Function)_ - function to call when the pages are sliding, should accept 1 argument which is an Float number representing the page position in the slide frame.
85 | - **`locked`** _(Bool)_ - disables horizontal dragging to scroll between tabs, default is false.
86 | - **`initialPage`** _(Integer)_ - the index of the initially selected tab, defaults to 0 === first tab.
87 | - **`page`** _(Integer)_ - set selected tab(can be buggy see [#126](https://github.com/brentvatne/react-native-scrollable-tab-view/issues/126)
88 | - **`children`** _(ReactComponents)_ - each top-level child component should have a `tabLabel` prop that can be used by the tab bar component to render out the labels. The default tab bar expects it to be a string, but you can use anything you want if you make a custom tab bar.
89 | - **`tabBarUnderlineStyle`** _([View.propTypes.style](https://facebook.github.io/react-native/docs/view.html#style))_ - style of the default tab bar's underline.
90 | - **`tabBarBackgroundColor`** _(String)_ - color of the default tab bar's background, defaults to `white`
91 | - **`tabBarActiveTextColor`** _(String)_ - color of the default tab bar's text when active, defaults to `navy`
92 | - **`tabBarInactiveTextColor`** _(String)_ - color of the default tab bar's text when inactive, defaults to `black`
93 | - **`tabBarTextStyle`** _(Object)_ - Additional styles to the tab bar's text. Example: `{fontFamily: 'Roboto', fontSize: 15}`
94 | - **`style`** _([View.propTypes.style](https://facebook.github.io/react-native/docs/view.html#style))_
95 | - **`contentProps`** _(Object)_ - props that are applied to root `ScrollView`/`ViewPagerAndroid`. Note that overriding defaults set by the library may break functionality; see the source for details.
96 | - **`scrollWithoutAnimation`** _(Bool)_ - on tab press change tab without animation.
97 | - **`prerenderingSiblingsNumber`** _(Integer)_ - pre-render nearby # sibling, `Infinity` === render all the siblings, default to 0 === render current page.
98 |
99 | ## Contribution
100 | **Issues** are welcome. Please add a screenshot of bug and code snippet. Quickest way to solve issue is to reproduce it on one of the examples.
101 |
102 | **Pull requests** are welcome. If you want to change API or making something big better to create issue and discuss it first. Before submiting PR please run ```eslint .``` Also all eslint fixes are welcome.
103 |
104 | Please attach video or gif to PR's and issues it is super helpful.
105 |
106 | How to make video
107 |
108 | How to make gif from video
109 |
110 | ---
111 |
112 | **MIT Licensed**
113 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "env": {
4 | "browser": true,
5 | "node": true,
6 | "jasmine": true
7 | },
8 | "ecmaFeatures": {
9 | "arrowFunctions": true,
10 | "blockBindings": true,
11 | "classes": true,
12 | "defaultParams": true,
13 | "destructuring": true,
14 | "forOf": true,
15 | "generators": false,
16 | "modules": true,
17 | "objectLiteralComputedProperties": true,
18 | "objectLiteralDuplicateProperties": false,
19 | "objectLiteralShorthandMethods": true,
20 | "objectLiteralShorthandProperties": true,
21 | "spread": true,
22 | "superInFunctions": true,
23 | "templateStrings": true,
24 | "jsx": true
25 | },
26 | "rules": {
27 | /**
28 | * Strict mode
29 | */
30 | // babel inserts "use strict"; for us
31 | // http://eslint.org/docs/rules/strict
32 | "strict": [2, "never"],
33 |
34 | /**
35 | * ES6
36 | */
37 | "no-var": 2, // http://eslint.org/docs/rules/no-var
38 |
39 | /**
40 | * Variables
41 | */
42 | "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow
43 | "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names
44 | "no-unused-vars": [0, { // http://eslint.org/docs/rules/no-unused-vars
45 | "vars": "local",
46 | "args": "after-used"
47 | }],
48 |
49 | /**
50 | * Possible errors
51 | */
52 | "comma-dangle": [2, "always"], // http://eslint.org/docs/rules/comma-dangle
53 | "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign
54 | "no-console": 1, // http://eslint.org/docs/rules/no-console
55 | "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger
56 | "no-alert": 1, // http://eslint.org/docs/rules/no-alert
57 | "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition
58 | "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys
59 | "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case
60 | "no-empty": 2, // http://eslint.org/docs/rules/no-empty
61 | "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign
62 | "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast
63 | "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi
64 | "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign
65 | "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations
66 | "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp
67 | "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace
68 | "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls
69 | "no-reserved-keys": 0, // http://eslint.org/docs/rules/no-reserved-keys
70 | "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays
71 | "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable
72 | "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan
73 | "block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var
74 |
75 | /**
76 | * Best practices
77 | */
78 | "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return
79 | "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly
80 | "default-case": 2, // http://eslint.org/docs/rules/default-case
81 | "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation
82 | "allowKeywords": true
83 | }],
84 | "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq
85 | "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in
86 | "no-caller": 2, // http://eslint.org/docs/rules/no-caller
87 | "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null
88 | "no-eval": 2, // http://eslint.org/docs/rules/no-eval
89 | "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native
90 | "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind
91 | "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough
92 | "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal
93 | "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval
94 | "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks
95 | "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func
96 | "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str
97 | "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign
98 | "no-new": 2, // http://eslint.org/docs/rules/no-new
99 | "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func
100 | "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers
101 | "no-octal": 2, // http://eslint.org/docs/rules/no-octal
102 | "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape
103 | "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign
104 | "no-proto": 2, // http://eslint.org/docs/rules/no-proto
105 | "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare
106 | "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign
107 | "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url
108 | "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare
109 | "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences
110 | "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal
111 | "no-with": 2, // http://eslint.org/docs/rules/no-with
112 | "radix": 2, // http://eslint.org/docs/rules/radix
113 | "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top
114 | "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife
115 | "yoda": 2, // http://eslint.org/docs/rules/yoda
116 |
117 | /**
118 | * Style
119 | */
120 | "indent": [2, 2], // http://eslint.org/docs/rules/
121 | "brace-style": [2, // http://eslint.org/docs/rules/brace-style
122 | "1tbs", {
123 | "allowSingleLine": true
124 | }],
125 | "quotes": [
126 | 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes
127 | ],
128 | "camelcase": [2, { // http://eslint.org/docs/rules/camelcase
129 | "properties": "never"
130 | }],
131 | "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing
132 | "before": false,
133 | "after": true
134 | }],
135 | "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style
136 | "eol-last": 2, // http://eslint.org/docs/rules/eol-last
137 | "func-names": 1, // http://eslint.org/docs/rules/func-names
138 | "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing
139 | "beforeColon": false,
140 | "afterColon": true
141 | }],
142 | "new-cap": [2, { // http://eslint.org/docs/rules/new-cap
143 | "newIsCap": true
144 | }],
145 | "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
146 | "max": 2
147 | }],
148 | "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary
149 | "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object
150 | "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func
151 | "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces
152 | "no-extra-parens": 0, // http://eslint.org/docs/rules/no-extra-parens
153 | "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle
154 | "one-var": [2, "never"], // http://eslint.org/docs/rules/one-var
155 | "padded-blocks": 0, // http://eslint.org/docs/rules/padded-blocks
156 | "semi": [2, "always"], // http://eslint.org/docs/rules/semi
157 | "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing
158 | "before": false,
159 | "after": true
160 | }],
161 | "keyword-spacing": 2, // http://eslint.org/docs/rules/keyword-spacing
162 | "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks
163 | "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren
164 | "space-infix-ops": 2 // http://eslint.org/docs/rules/space-infix-ops
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/ScrollableTabBar.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactNative = require('react-native');
3 | const DeprecatedPropTypes = require('deprecated-react-native-prop-types');
4 | const PropTypes = require('prop-types');
5 | const createReactClass = require('create-react-class');
6 | const {
7 | View,
8 | Animated,
9 | StyleSheet,
10 | ScrollView,
11 | Text,
12 | Platform,
13 | Dimensions,
14 | } = ReactNative;
15 | const Button = require('./Button');
16 |
17 | const WINDOW_WIDTH = Dimensions.get('window').width;
18 |
19 | const ScrollableTabBar = createReactClass({
20 | propTypes: {
21 | goToPage: PropTypes.func,
22 | activeTab: PropTypes.number,
23 | tabs: PropTypes.array,
24 | backgroundColor: PropTypes.string,
25 | activeTextColor: PropTypes.string,
26 | inactiveTextColor: PropTypes.string,
27 | scrollOffset: PropTypes.number,
28 | style: DeprecatedPropTypes.ViewPropTypes.style,
29 | tabStyle: DeprecatedPropTypes.ViewPropTypes.style,
30 | tabsContainerStyle: DeprecatedPropTypes.ViewPropTypes.style,
31 | textStyle: DeprecatedPropTypes.TextPropTypes.style,
32 | renderTab: PropTypes.func,
33 | underlineStyle: DeprecatedPropTypes.ViewPropTypes.style,
34 | onScroll: PropTypes.func,
35 | },
36 |
37 | getDefaultProps() {
38 | return {
39 | scrollOffset: 52,
40 | activeTextColor: 'navy',
41 | inactiveTextColor: 'black',
42 | backgroundColor: null,
43 | style: {},
44 | tabStyle: {},
45 | tabsContainerStyle: {},
46 | underlineStyle: {},
47 | };
48 | },
49 |
50 | getInitialState() {
51 | this._tabsMeasurements = [];
52 | return {
53 | _leftTabUnderline: new Animated.Value(0),
54 | _widthTabUnderline: new Animated.Value(0),
55 | _containerWidth: null,
56 | };
57 | },
58 |
59 | componentDidMount() {
60 | this.props.scrollValue.addListener(this.updateView);
61 | },
62 |
63 | updateView(offset) {
64 | const position = Math.floor(offset.value);
65 | const pageOffset = offset.value % 1;
66 | const tabCount = this.props.tabs.length;
67 | const lastTabPosition = tabCount - 1;
68 |
69 | if (tabCount === 0 || offset.value < 0 || offset.value > lastTabPosition) {
70 | return;
71 | }
72 |
73 | if (this.necessarilyMeasurementsCompleted(position, position === lastTabPosition)) {
74 | this.updateTabPanel(position, pageOffset);
75 | this.updateTabUnderline(position, pageOffset, tabCount);
76 | }
77 | },
78 |
79 | necessarilyMeasurementsCompleted(position, isLastTab) {
80 | return this._tabsMeasurements[position] &&
81 | (isLastTab || this._tabsMeasurements[position + 1]) &&
82 | this._tabContainerMeasurements &&
83 | this._containerMeasurements;
84 | },
85 |
86 | updateTabPanel(position, pageOffset) {
87 | const containerWidth = this._containerMeasurements.width;
88 | const tabWidth = this._tabsMeasurements[position].width;
89 | const nextTabMeasurements = this._tabsMeasurements[position + 1];
90 | const nextTabWidth = nextTabMeasurements && nextTabMeasurements.width || 0;
91 | const tabOffset = this._tabsMeasurements[position].left;
92 | const absolutePageOffset = pageOffset * tabWidth;
93 | let newScrollX = tabOffset + absolutePageOffset;
94 |
95 | // center tab and smooth tab change (for when tabWidth changes a lot between two tabs)
96 | newScrollX -= (containerWidth - (1 - pageOffset) * tabWidth - pageOffset * nextTabWidth) / 2;
97 | newScrollX = newScrollX >= 0 ? newScrollX : 0;
98 |
99 | if (Platform.OS === 'android') {
100 | this._scrollView.scrollTo({x: newScrollX, y: 0, animated: false, });
101 | } else {
102 | const rightBoundScroll = this._tabContainerMeasurements.width - (this._containerMeasurements.width);
103 | newScrollX = newScrollX > rightBoundScroll ? rightBoundScroll : newScrollX;
104 | this._scrollView.scrollTo({x: newScrollX, y: 0, animated: false, });
105 | }
106 |
107 | },
108 |
109 | updateTabUnderline(position, pageOffset, tabCount) {
110 | const lineLeft = this._tabsMeasurements[position].left;
111 | const lineRight = this._tabsMeasurements[position].right;
112 |
113 | if (position < tabCount - 1) {
114 | const nextTabLeft = this._tabsMeasurements[position + 1].left;
115 | const nextTabRight = this._tabsMeasurements[position + 1].right;
116 |
117 | const newLineLeft = (pageOffset * nextTabLeft + (1 - pageOffset) * lineLeft);
118 | const newLineRight = (pageOffset * nextTabRight + (1 - pageOffset) * lineRight);
119 |
120 | this.state._leftTabUnderline.setValue(newLineLeft);
121 | this.state._widthTabUnderline.setValue(newLineRight - newLineLeft);
122 | } else {
123 | this.state._leftTabUnderline.setValue(lineLeft);
124 | this.state._widthTabUnderline.setValue(lineRight - lineLeft);
125 | }
126 | },
127 |
128 | renderTab(name, page, isTabActive, onPressHandler, onLayoutHandler) {
129 | const { activeTextColor, inactiveTextColor, textStyle, } = this.props;
130 | const textColor = isTabActive ? activeTextColor : inactiveTextColor;
131 | const fontWeight = isTabActive ? 'bold' : 'normal';
132 |
133 | return ;
147 | },
148 |
149 | measureTab(page, event) {
150 | const { x, width, height, } = event.nativeEvent.layout;
151 | this._tabsMeasurements[page] = {left: x, right: x + width, width, height, };
152 | this.updateView({value: this.props.scrollValue.__getValue(), });
153 | },
154 |
155 | render() {
156 | const tabUnderlineStyle = {
157 | position: 'absolute',
158 | height: 4,
159 | backgroundColor: 'navy',
160 | bottom: 0,
161 | };
162 |
163 | const dynamicTabUnderline = {
164 | left: this.state._leftTabUnderline,
165 | width: this.state._widthTabUnderline,
166 | };
167 |
168 | const {
169 | onScroll,
170 | } = this.props;
171 |
172 | return
176 | { this._scrollView = scrollView; }}
178 | horizontal={true}
179 | showsHorizontalScrollIndicator={false}
180 | showsVerticalScrollIndicator={false}
181 | directionalLockEnabled={true}
182 | bounces={false}
183 | scrollsToTop={false}
184 | onScroll={onScroll}
185 | scrollEventThrottle={16}
186 | >
187 |
192 | {this.props.tabs.map((name, page) => {
193 | const isTabActive = this.props.activeTab === page;
194 | const renderTab = this.props.renderTab || this.renderTab;
195 | return renderTab(name, page, isTabActive, this.props.goToPage, this.measureTab.bind(this, page));
196 | })}
197 |
198 |
199 |
200 | ;
201 | },
202 |
203 | componentDidUpdate(prevProps) {
204 | // If the tabs change, force the width of the tabs container to be recalculated
205 | if (JSON.stringify(prevProps.tabs) !== JSON.stringify(this.props.tabs) && this.state._containerWidth) {
206 | this.setState({ _containerWidth: null, });
207 | }
208 | },
209 |
210 | onTabContainerLayout(e) {
211 | this._tabContainerMeasurements = e.nativeEvent.layout;
212 | let width = this._tabContainerMeasurements.width;
213 | if (width < WINDOW_WIDTH) {
214 | width = WINDOW_WIDTH;
215 | }
216 | this.setState({ _containerWidth: width, });
217 | this.updateView({value: this.props.scrollValue.__getValue(), });
218 | },
219 |
220 | onContainerLayout(e) {
221 | this._containerMeasurements = e.nativeEvent.layout;
222 | this.updateView({value: this.props.scrollValue.__getValue(), });
223 | },
224 | });
225 |
226 | module.exports = ScrollableTabBar;
227 |
228 | const styles = StyleSheet.create({
229 | tab: {
230 | height: 49,
231 | alignItems: 'center',
232 | justifyContent: 'center',
233 | paddingLeft: 20,
234 | paddingRight: 20,
235 | },
236 | container: {
237 | height: 50,
238 | borderWidth: 1,
239 | borderTopWidth: 0,
240 | borderLeftWidth: 0,
241 | borderRightWidth: 0,
242 | borderColor: '#ccc',
243 | },
244 | tabs: {
245 | flexDirection: 'row',
246 | justifyContent: 'space-around',
247 | },
248 | });
249 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactNative = require('react-native');
3 | const DeprecatedPropTypes = require('deprecated-react-native-prop-types');
4 | const createReactClass = require('create-react-class');
5 | const PropTypes = require('prop-types');
6 | const {
7 | Dimensions,
8 | View,
9 | Animated,
10 | ScrollView,
11 | Platform,
12 | StyleSheet,
13 | InteractionManager,
14 | } = ReactNative;
15 |
16 | const ViewPagerAndroid = require('@react-native-community/viewpager');
17 | const TimerMixin = require('react-timer-mixin');
18 | const ViewPager = require('@react-native-community/viewpager');
19 |
20 | const SceneComponent = require('./SceneComponent');
21 | const DefaultTabBar = require('./DefaultTabBar');
22 | const ScrollableTabBar = require('./ScrollableTabBar');
23 |
24 | const AnimatedViewPagerAndroid = Platform.OS === 'android' ?
25 | Animated.createAnimatedComponent(ViewPager) :
26 | undefined;
27 |
28 | const ScrollableTabView = createReactClass({
29 | mixins: [TimerMixin, ],
30 | statics: {
31 | DefaultTabBar,
32 | ScrollableTabBar,
33 | },
34 | scrollOnMountCalled: false,
35 | tabWillChangeWithoutGesture: false,
36 |
37 | propTypes: {
38 | tabBarPosition: PropTypes.oneOf(['top', 'bottom', 'overlayTop', 'overlayBottom', ]),
39 | initialPage: PropTypes.number,
40 | page: PropTypes.number,
41 | onChangeTab: PropTypes.func,
42 | onScroll: PropTypes.func,
43 | renderTabBar: PropTypes.any,
44 | tabBarUnderlineStyle: DeprecatedPropTypes.ViewPropTypes.style,
45 | tabBarBackgroundColor: PropTypes.string,
46 | tabBarActiveTextColor: PropTypes.string,
47 | tabBarInactiveTextColor: PropTypes.string,
48 | tabBarTextStyle: PropTypes.object,
49 | style: DeprecatedPropTypes.ViewPropTypes.style,
50 | contentProps: PropTypes.object,
51 | scrollWithoutAnimation: PropTypes.bool,
52 | locked: PropTypes.bool,
53 | prerenderingSiblingsNumber: PropTypes.number,
54 | },
55 |
56 | getDefaultProps() {
57 | return {
58 | tabBarPosition: 'top',
59 | initialPage: 0,
60 | page: -1,
61 | onChangeTab: () => {},
62 | onScroll: () => {},
63 | contentProps: {},
64 | scrollWithoutAnimation: false,
65 | locked: false,
66 | prerenderingSiblingsNumber: 0,
67 | };
68 | },
69 |
70 | getInitialState() {
71 | const containerWidth = Dimensions.get('window').width;
72 | let scrollValue;
73 | let scrollXIOS;
74 | let positionAndroid;
75 | let offsetAndroid;
76 |
77 | if (Platform.OS === 'ios') {
78 | scrollXIOS = new Animated.Value(this.props.initialPage * containerWidth);
79 | const containerWidthAnimatedValue = new Animated.Value(containerWidth);
80 | // Need to call __makeNative manually to avoid a native animated bug. See
81 | // https://github.com/facebook/react-native/pull/14435
82 | containerWidthAnimatedValue.__makeNative();
83 | scrollValue = Animated.divide(scrollXIOS, containerWidthAnimatedValue);
84 |
85 | const callListeners = this._polyfillAnimatedValue(scrollValue);
86 | scrollXIOS.addListener(
87 | ({ value, }) => callListeners(value / this.state.containerWidth)
88 | );
89 | } else {
90 | positionAndroid = new Animated.Value(this.props.initialPage);
91 | offsetAndroid = new Animated.Value(0);
92 | scrollValue = Animated.add(positionAndroid, offsetAndroid);
93 |
94 | const callListeners = this._polyfillAnimatedValue(scrollValue);
95 | let positionAndroidValue = this.props.initialPage;
96 | let offsetAndroidValue = 0;
97 | positionAndroid.addListener(({ value, }) => {
98 | positionAndroidValue = value;
99 | callListeners(positionAndroidValue + offsetAndroidValue);
100 | });
101 | offsetAndroid.addListener(({ value, }) => {
102 | offsetAndroidValue = value;
103 | callListeners(positionAndroidValue + offsetAndroidValue);
104 | });
105 | }
106 |
107 | return {
108 | currentPage: this.props.initialPage,
109 | scrollValue,
110 | scrollXIOS,
111 | positionAndroid,
112 | offsetAndroid,
113 | containerWidth,
114 | sceneKeys: this.newSceneKeys({ currentPage: this.props.initialPage, }),
115 | };
116 | },
117 |
118 | componentDidUpdate(prevProps) {
119 | if (this.props.children !== prevProps.children) {
120 | this.updateSceneKeys({ page: this.state.currentPage, children: this.props.children, });
121 | }
122 |
123 | if (this.props.page >= 0 && this.props.page !== this.state.currentPage) {
124 | this.goToPage(this.props.page);
125 | }
126 | },
127 |
128 | componentWillUnmount() {
129 | if (Platform.OS === 'ios') {
130 | this.state.scrollXIOS.removeAllListeners();
131 | } else {
132 | this.state.positionAndroid.removeAllListeners();
133 | this.state.offsetAndroid.removeAllListeners();
134 | }
135 | },
136 |
137 | goToPage(pageNumber) {
138 | if (Platform.OS === 'ios') {
139 | const offset = pageNumber * this.state.containerWidth;
140 | if (this.scrollView) {
141 | this.scrollView.scrollTo({x: offset, y: 0, animated: !this.props.scrollWithoutAnimation, });
142 | }
143 | } else {
144 | if (this.scrollView) {
145 | this.tabWillChangeWithoutGesture = true;
146 | if (this.props.scrollWithoutAnimation) {
147 | this.scrollView.setPageWithoutAnimation(pageNumber);
148 | } else {
149 | this.scrollView.setPage(pageNumber);
150 | }
151 | }
152 | }
153 |
154 | const currentPage = this.state.currentPage;
155 | this.updateSceneKeys({
156 | page: pageNumber,
157 | callback: this._onChangeTab.bind(this, currentPage, pageNumber),
158 | });
159 | },
160 |
161 | renderTabBar(props) {
162 | if (this.props.renderTabBar === false) {
163 | return null;
164 | } else if (this.props.renderTabBar) {
165 | return React.cloneElement(this.props.renderTabBar(props), props);
166 | } else {
167 | return ;
168 | }
169 | },
170 |
171 | updateSceneKeys({ page, children = this.props.children, callback = () => {}, }) {
172 | let newKeys = this.newSceneKeys({ previousKeys: this.state.sceneKeys, currentPage: page, children, });
173 | this.setState({currentPage: page, sceneKeys: newKeys, }, callback);
174 | },
175 |
176 | newSceneKeys({ previousKeys = [], currentPage = 0, children = this.props.children, }) {
177 | let newKeys = [];
178 | this._children(children).forEach((child, idx) => {
179 | let key = this._makeSceneKey(child, idx);
180 | if (this._keyExists(previousKeys, key) ||
181 | this._shouldRenderSceneKey(idx, currentPage)) {
182 | newKeys.push(key);
183 | }
184 | });
185 | return newKeys;
186 | },
187 |
188 | // Animated.add and Animated.divide do not currently support listeners so
189 | // we have to polyfill it here since a lot of code depends on being able
190 | // to add a listener to `scrollValue`. See https://github.com/facebook/react-native/pull/12620.
191 | _polyfillAnimatedValue(animatedValue) {
192 |
193 | const listeners = new Set();
194 | const addListener = (listener) => {
195 | listeners.add(listener);
196 | };
197 |
198 | const removeListener = (listener) => {
199 | listeners.delete(listener);
200 | };
201 |
202 | const removeAllListeners = () => {
203 | listeners.clear();
204 | };
205 |
206 | animatedValue.addListener = addListener;
207 | animatedValue.removeListener = removeListener;
208 | animatedValue.removeAllListeners = removeAllListeners;
209 |
210 | return (value) => listeners.forEach(listener => listener({ value, }));
211 | },
212 |
213 | _shouldRenderSceneKey(idx, currentPageKey) {
214 | let numOfSibling = this.props.prerenderingSiblingsNumber;
215 | return (idx < (currentPageKey + numOfSibling + 1) &&
216 | idx > (currentPageKey - numOfSibling - 1));
217 | },
218 |
219 | _keyExists(sceneKeys, key) {
220 | return sceneKeys.find((sceneKey) => key === sceneKey);
221 | },
222 |
223 | _makeSceneKey(child, idx) {
224 | return child.props.tabLabel + '_' + idx;
225 | },
226 |
227 | renderScrollableContent() {
228 | if (Platform.OS === 'ios') {
229 | const scenes = this._composeScenes();
230 | return { this.scrollView = scrollView; }}
236 | onScroll={Animated.event(
237 | [{ nativeEvent: { contentOffset: { x: this.state.scrollXIOS, }, }, }, ],
238 | { useNativeDriver: true, listener: this._onScroll, }
239 | )}
240 | onMomentumScrollBegin={this._onMomentumScrollBeginAndEnd}
241 | onMomentumScrollEnd={this._onMomentumScrollBeginAndEnd}
242 | scrollEventThrottle={16}
243 | scrollsToTop={false}
244 | showsHorizontalScrollIndicator={false}
245 | scrollEnabled={!this.props.locked}
246 | directionalLockEnabled
247 | alwaysBounceVertical={false}
248 | keyboardDismissMode="on-drag"
249 | {...this.props.contentProps}
250 | >
251 | {scenes}
252 | ;
253 | } else {
254 | const scenes = this._composeScenes();
255 | return { this.scrollView = scrollView; }}
275 | {...this.props.contentProps}
276 | >
277 | {scenes}
278 | ;
279 | }
280 | },
281 |
282 | _composeScenes() {
283 | return this._children().map((child, idx) => {
284 | let key = this._makeSceneKey(child, idx);
285 | return
290 | {this._keyExists(this.state.sceneKeys, key) ? child : }
291 | ;
292 | });
293 | },
294 |
295 | _onMomentumScrollBeginAndEnd(e) {
296 | const offsetX = e.nativeEvent.contentOffset.x;
297 | const page = Math.round(offsetX / this.state.containerWidth);
298 | if (this.state.currentPage !== page) {
299 | this._updateSelectedPage(page);
300 | }
301 | },
302 |
303 | _updateSelectedPage(nextPage) {
304 | let localNextPage = nextPage;
305 | if (typeof localNextPage === 'object') {
306 | localNextPage = nextPage.nativeEvent.position;
307 | }
308 |
309 | const currentPage = this.state.currentPage;
310 | !this.tabWillChangeWithoutGesture && this.updateSceneKeys({
311 | page: localNextPage,
312 | callback: this._onChangeTab.bind(this, currentPage, localNextPage),
313 | });
314 | this.tabWillChangeWithoutGesture = false;
315 | },
316 |
317 | _onChangeTab(prevPage, currentPage) {
318 | this.props.onChangeTab({
319 | i: currentPage,
320 | ref: this._children()[currentPage],
321 | from: prevPage,
322 | });
323 | },
324 |
325 | _onScroll(e) {
326 | if (Platform.OS === 'ios') {
327 | const offsetX = e.nativeEvent.contentOffset.x;
328 | if (offsetX === 0 && !this.scrollOnMountCalled) {
329 | this.scrollOnMountCalled = true;
330 | } else {
331 | this.props.onScroll(offsetX / this.state.containerWidth);
332 | }
333 | } else {
334 | const { position, offset, } = e.nativeEvent;
335 | this.props.onScroll(position + offset);
336 | }
337 | },
338 |
339 | _handleLayout(e) {
340 | const { width, } = e.nativeEvent.layout;
341 |
342 | if (!width || width <= 0 || Math.round(width) === Math.round(this.state.containerWidth)) {
343 | return;
344 | }
345 |
346 | if (Platform.OS === 'ios') {
347 | const containerWidthAnimatedValue = new Animated.Value(width);
348 | // Need to call __makeNative manually to avoid a native animated bug. See
349 | // https://github.com/facebook/react-native/pull/14435
350 | containerWidthAnimatedValue.__makeNative();
351 | scrollValue = Animated.divide(this.state.scrollXIOS, containerWidthAnimatedValue);
352 | this.setState({ containerWidth: width, scrollValue, });
353 | } else {
354 | this.setState({ containerWidth: width, });
355 | }
356 | this.requestAnimationFrame(() => {
357 | this.goToPage(this.state.currentPage);
358 | });
359 | },
360 |
361 | _children(children = this.props.children) {
362 | return React.Children.map(children, (child) => child);
363 | },
364 |
365 | render() {
366 | let overlayTabs = (this.props.tabBarPosition === 'overlayTop' || this.props.tabBarPosition === 'overlayBottom');
367 | let tabBarProps = {
368 | goToPage: this.goToPage,
369 | tabs: this._children().map((child) => child.props.tabLabel),
370 | activeTab: this.state.currentPage,
371 | scrollValue: this.state.scrollValue,
372 | containerWidth: this.state.containerWidth,
373 | };
374 |
375 | if (this.props.tabBarBackgroundColor) {
376 | tabBarProps.backgroundColor = this.props.tabBarBackgroundColor;
377 | }
378 | if (this.props.tabBarActiveTextColor) {
379 | tabBarProps.activeTextColor = this.props.tabBarActiveTextColor;
380 | }
381 | if (this.props.tabBarInactiveTextColor) {
382 | tabBarProps.inactiveTextColor = this.props.tabBarInactiveTextColor;
383 | }
384 | if (this.props.tabBarTextStyle) {
385 | tabBarProps.textStyle = this.props.tabBarTextStyle;
386 | }
387 | if (this.props.tabBarUnderlineStyle) {
388 | tabBarProps.underlineStyle = this.props.tabBarUnderlineStyle;
389 | }
390 | if (overlayTabs) {
391 | tabBarProps.style = {
392 | position: 'absolute',
393 | left: 0,
394 | right: 0,
395 | [this.props.tabBarPosition === 'overlayTop' ? 'top' : 'bottom']: 0,
396 | };
397 | }
398 |
399 | return
400 | {this.props.tabBarPosition === 'top' && this.renderTabBar(tabBarProps)}
401 | {this.renderScrollableContent()}
402 | {(this.props.tabBarPosition === 'bottom' || overlayTabs) && this.renderTabBar(tabBarProps)}
403 | ;
404 | },
405 | });
406 |
407 | module.exports = ScrollableTabView;
408 |
409 | const styles = StyleSheet.create({
410 | container: {
411 | flex: 1,
412 | },
413 | scrollableContentAndroid: {
414 | flex: 1,
415 | },
416 | });
417 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@react-native-community/viewpager@3.3.0":
6 | version "3.3.0"
7 | resolved "https://registry.yarnpkg.com/@react-native-community/viewpager/-/viewpager-3.3.0.tgz#e613747a43a31a6f3278f817ba96fdaaa7941f23"
8 | integrity sha512-tyzh79l4t/hxiyS9QD3LRmWMs8KVkZzjrkQ8U8+8To1wmvVCBtp8BenvNsDLTBO7CpO/YmiThpmIdEZMr1WuVw==
9 |
10 | "@react-native/normalize-color@*":
11 | version "2.0.0"
12 | resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.0.0.tgz#da955909432474a9a0fe1cbffc66576a0447f567"
13 | integrity sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw==
14 |
15 | acorn-jsx@^3.0.0:
16 | version "3.0.1"
17 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
18 | integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=
19 | dependencies:
20 | acorn "^3.0.4"
21 |
22 | acorn@^3.0.4:
23 | version "3.3.0"
24 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
25 | integrity sha1-ReN/s56No/JbruP/U2niu18iAXo=
26 |
27 | acorn@^5.5.0:
28 | version "5.7.3"
29 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
30 | integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
31 |
32 | ajv-keywords@^1.0.0:
33 | version "1.5.1"
34 | resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
35 | integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw=
36 |
37 | ajv@^4.7.0:
38 | version "4.11.8"
39 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
40 | integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=
41 | dependencies:
42 | co "^4.6.0"
43 | json-stable-stringify "^1.0.1"
44 |
45 | ansi-escapes@^1.1.0:
46 | version "1.4.0"
47 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
48 | integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
49 |
50 | ansi-regex@^2.0.0:
51 | version "2.1.1"
52 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
53 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
54 |
55 | ansi-regex@^3.0.0:
56 | version "3.0.0"
57 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
58 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
59 |
60 | ansi-styles@^2.2.1:
61 | version "2.2.1"
62 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
63 | integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
64 |
65 | argparse@^1.0.7:
66 | version "1.0.10"
67 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
68 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
69 | dependencies:
70 | sprintf-js "~1.0.2"
71 |
72 | asap@~2.0.3:
73 | version "2.0.6"
74 | resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
75 | integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
76 |
77 | babel-code-frame@^6.16.0, babel-code-frame@^6.26.0:
78 | version "6.26.0"
79 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
80 | integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=
81 | dependencies:
82 | chalk "^1.1.3"
83 | esutils "^2.0.2"
84 | js-tokens "^3.0.2"
85 |
86 | babel-eslint@^6.1.2:
87 | version "6.1.2"
88 | resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-6.1.2.tgz#5293419fe3672d66598d327da9694567ba6a5f2f"
89 | integrity sha1-UpNBn+NnLWZZjTJ9qWlFZ7pqXy8=
90 | dependencies:
91 | babel-traverse "^6.0.20"
92 | babel-types "^6.0.19"
93 | babylon "^6.0.18"
94 | lodash.assign "^4.0.0"
95 | lodash.pickby "^4.0.0"
96 |
97 | babel-messages@^6.23.0:
98 | version "6.23.0"
99 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
100 | integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=
101 | dependencies:
102 | babel-runtime "^6.22.0"
103 |
104 | babel-runtime@^6.22.0, babel-runtime@^6.26.0:
105 | version "6.26.0"
106 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
107 | integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
108 | dependencies:
109 | core-js "^2.4.0"
110 | regenerator-runtime "^0.11.0"
111 |
112 | babel-traverse@^6.0.20:
113 | version "6.26.0"
114 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
115 | integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=
116 | dependencies:
117 | babel-code-frame "^6.26.0"
118 | babel-messages "^6.23.0"
119 | babel-runtime "^6.26.0"
120 | babel-types "^6.26.0"
121 | babylon "^6.18.0"
122 | debug "^2.6.8"
123 | globals "^9.18.0"
124 | invariant "^2.2.2"
125 | lodash "^4.17.4"
126 |
127 | babel-types@^6.0.19, babel-types@^6.26.0:
128 | version "6.26.0"
129 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
130 | integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=
131 | dependencies:
132 | babel-runtime "^6.26.0"
133 | esutils "^2.0.2"
134 | lodash "^4.17.4"
135 | to-fast-properties "^1.0.3"
136 |
137 | babylon@^6.0.18, babylon@^6.18.0:
138 | version "6.18.0"
139 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
140 | integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
141 |
142 | balanced-match@^1.0.0:
143 | version "1.0.0"
144 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
145 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
146 |
147 | brace-expansion@^1.1.7:
148 | version "1.1.11"
149 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
150 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
151 | dependencies:
152 | balanced-match "^1.0.0"
153 | concat-map "0.0.1"
154 |
155 | buffer-from@^1.0.0:
156 | version "1.1.1"
157 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
158 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
159 |
160 | caller-path@^0.1.0:
161 | version "0.1.0"
162 | resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
163 | integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=
164 | dependencies:
165 | callsites "^0.2.0"
166 |
167 | callsites@^0.2.0:
168 | version "0.2.0"
169 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
170 | integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=
171 |
172 | chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
173 | version "1.1.3"
174 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
175 | integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
176 | dependencies:
177 | ansi-styles "^2.2.1"
178 | escape-string-regexp "^1.0.2"
179 | has-ansi "^2.0.0"
180 | strip-ansi "^3.0.0"
181 | supports-color "^2.0.0"
182 |
183 | circular-json@^0.3.1:
184 | version "0.3.3"
185 | resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
186 | integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
187 |
188 | cli-cursor@^1.0.1:
189 | version "1.0.2"
190 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
191 | integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=
192 | dependencies:
193 | restore-cursor "^1.0.1"
194 |
195 | cli-width@^2.0.0:
196 | version "2.2.0"
197 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
198 | integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
199 |
200 | co@^4.6.0:
201 | version "4.6.0"
202 | resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
203 | integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
204 |
205 | code-point-at@^1.0.0:
206 | version "1.1.0"
207 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
208 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
209 |
210 | concat-map@0.0.1:
211 | version "0.0.1"
212 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
213 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
214 |
215 | concat-stream@^1.5.2:
216 | version "1.6.2"
217 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
218 | integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
219 | dependencies:
220 | buffer-from "^1.0.0"
221 | inherits "^2.0.3"
222 | readable-stream "^2.2.2"
223 | typedarray "^0.0.6"
224 |
225 | core-js@^1.0.0:
226 | version "1.2.7"
227 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
228 | integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
229 |
230 | core-js@^2.4.0:
231 | version "2.6.9"
232 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
233 | integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
234 |
235 | core-util-is@~1.0.0:
236 | version "1.0.2"
237 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
238 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
239 |
240 | create-react-class@^15.6.2:
241 | version "15.6.3"
242 | resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036"
243 | integrity sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==
244 | dependencies:
245 | fbjs "^0.8.9"
246 | loose-envify "^1.3.1"
247 | object-assign "^4.1.1"
248 |
249 | d@1, d@^1.0.1:
250 | version "1.0.1"
251 | resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
252 | integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
253 | dependencies:
254 | es5-ext "^0.10.50"
255 | type "^1.0.1"
256 |
257 | debug@^2.1.1, debug@^2.6.8:
258 | version "2.6.9"
259 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
260 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
261 | dependencies:
262 | ms "2.0.0"
263 |
264 | deep-is@~0.1.3:
265 | version "0.1.3"
266 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
267 | integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
268 |
269 | deprecated-react-native-prop-types@^2.3.0:
270 | version "2.3.0"
271 | resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz#c10c6ee75ff2b6de94bb127f142b814e6e08d9ab"
272 | integrity sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==
273 | dependencies:
274 | "@react-native/normalize-color" "*"
275 | invariant "*"
276 | prop-types "*"
277 |
278 | doctrine@^2.0.0:
279 | version "2.1.0"
280 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
281 | integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
282 | dependencies:
283 | esutils "^2.0.2"
284 |
285 | encoding@^0.1.11:
286 | version "0.1.12"
287 | resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
288 | integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
289 | dependencies:
290 | iconv-lite "~0.4.13"
291 |
292 | es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.51, es5-ext@~0.10.14:
293 | version "0.10.51"
294 | resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.51.tgz#ed2d7d9d48a12df86e0299287e93a09ff478842f"
295 | integrity sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==
296 | dependencies:
297 | es6-iterator "~2.0.3"
298 | es6-symbol "~3.1.1"
299 | next-tick "^1.0.0"
300 |
301 | es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3:
302 | version "2.0.3"
303 | resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
304 | integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
305 | dependencies:
306 | d "1"
307 | es5-ext "^0.10.35"
308 | es6-symbol "^3.1.1"
309 |
310 | es6-map@^0.1.3:
311 | version "0.1.5"
312 | resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
313 | integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=
314 | dependencies:
315 | d "1"
316 | es5-ext "~0.10.14"
317 | es6-iterator "~2.0.1"
318 | es6-set "~0.1.5"
319 | es6-symbol "~3.1.1"
320 | event-emitter "~0.3.5"
321 |
322 | es6-set@~0.1.5:
323 | version "0.1.5"
324 | resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
325 | integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=
326 | dependencies:
327 | d "1"
328 | es5-ext "~0.10.14"
329 | es6-iterator "~2.0.1"
330 | es6-symbol "3.1.1"
331 | event-emitter "~0.3.5"
332 |
333 | es6-symbol@3.1.1:
334 | version "3.1.1"
335 | resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
336 | integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
337 | dependencies:
338 | d "1"
339 | es5-ext "~0.10.14"
340 |
341 | es6-symbol@^3.1.1, es6-symbol@~3.1.1:
342 | version "3.1.2"
343 | resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.2.tgz#859fdd34f32e905ff06d752e7171ddd4444a7ed1"
344 | integrity sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==
345 | dependencies:
346 | d "^1.0.1"
347 | es5-ext "^0.10.51"
348 |
349 | es6-weak-map@^2.0.1:
350 | version "2.0.3"
351 | resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53"
352 | integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==
353 | dependencies:
354 | d "1"
355 | es5-ext "^0.10.46"
356 | es6-iterator "^2.0.3"
357 | es6-symbol "^3.1.1"
358 |
359 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
360 | version "1.0.5"
361 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
362 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
363 |
364 | escope@^3.6.0:
365 | version "3.6.0"
366 | resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
367 | integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=
368 | dependencies:
369 | es6-map "^0.1.3"
370 | es6-weak-map "^2.0.1"
371 | esrecurse "^4.1.0"
372 | estraverse "^4.1.1"
373 |
374 | eslint@^3.1.1:
375 | version "3.19.0"
376 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc"
377 | integrity sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=
378 | dependencies:
379 | babel-code-frame "^6.16.0"
380 | chalk "^1.1.3"
381 | concat-stream "^1.5.2"
382 | debug "^2.1.1"
383 | doctrine "^2.0.0"
384 | escope "^3.6.0"
385 | espree "^3.4.0"
386 | esquery "^1.0.0"
387 | estraverse "^4.2.0"
388 | esutils "^2.0.2"
389 | file-entry-cache "^2.0.0"
390 | glob "^7.0.3"
391 | globals "^9.14.0"
392 | ignore "^3.2.0"
393 | imurmurhash "^0.1.4"
394 | inquirer "^0.12.0"
395 | is-my-json-valid "^2.10.0"
396 | is-resolvable "^1.0.0"
397 | js-yaml "^3.5.1"
398 | json-stable-stringify "^1.0.0"
399 | levn "^0.3.0"
400 | lodash "^4.0.0"
401 | mkdirp "^0.5.0"
402 | natural-compare "^1.4.0"
403 | optionator "^0.8.2"
404 | path-is-inside "^1.0.1"
405 | pluralize "^1.2.1"
406 | progress "^1.1.8"
407 | require-uncached "^1.0.2"
408 | shelljs "^0.7.5"
409 | strip-bom "^3.0.0"
410 | strip-json-comments "~2.0.1"
411 | table "^3.7.8"
412 | text-table "~0.2.0"
413 | user-home "^2.0.0"
414 |
415 | espree@^3.4.0:
416 | version "3.5.4"
417 | resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
418 | integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==
419 | dependencies:
420 | acorn "^5.5.0"
421 | acorn-jsx "^3.0.0"
422 |
423 | esprima@^4.0.0:
424 | version "4.0.1"
425 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
426 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
427 |
428 | esquery@^1.0.0:
429 | version "1.0.1"
430 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
431 | integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==
432 | dependencies:
433 | estraverse "^4.0.0"
434 |
435 | esrecurse@^4.1.0:
436 | version "4.2.1"
437 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
438 | integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
439 | dependencies:
440 | estraverse "^4.1.0"
441 |
442 | estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
443 | version "4.3.0"
444 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
445 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
446 |
447 | esutils@^2.0.2:
448 | version "2.0.3"
449 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
450 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
451 |
452 | event-emitter@~0.3.5:
453 | version "0.3.5"
454 | resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
455 | integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
456 | dependencies:
457 | d "1"
458 | es5-ext "~0.10.14"
459 |
460 | exit-hook@^1.0.0:
461 | version "1.1.1"
462 | resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
463 | integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=
464 |
465 | fast-levenshtein@~2.0.4:
466 | version "2.0.6"
467 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
468 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
469 |
470 | fbjs@^0.8.9:
471 | version "0.8.17"
472 | resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
473 | integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
474 | dependencies:
475 | core-js "^1.0.0"
476 | isomorphic-fetch "^2.1.1"
477 | loose-envify "^1.0.0"
478 | object-assign "^4.1.0"
479 | promise "^7.1.1"
480 | setimmediate "^1.0.5"
481 | ua-parser-js "^0.7.18"
482 |
483 | figures@^1.3.5:
484 | version "1.7.0"
485 | resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
486 | integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
487 | dependencies:
488 | escape-string-regexp "^1.0.5"
489 | object-assign "^4.1.0"
490 |
491 | file-entry-cache@^2.0.0:
492 | version "2.0.0"
493 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
494 | integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=
495 | dependencies:
496 | flat-cache "^1.2.1"
497 | object-assign "^4.0.1"
498 |
499 | flat-cache@^1.2.1:
500 | version "1.3.4"
501 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f"
502 | integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==
503 | dependencies:
504 | circular-json "^0.3.1"
505 | graceful-fs "^4.1.2"
506 | rimraf "~2.6.2"
507 | write "^0.2.1"
508 |
509 | fs.realpath@^1.0.0:
510 | version "1.0.0"
511 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
512 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
513 |
514 | generate-function@^2.0.0:
515 | version "2.3.1"
516 | resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f"
517 | integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==
518 | dependencies:
519 | is-property "^1.0.2"
520 |
521 | generate-object-property@^1.1.0:
522 | version "1.2.0"
523 | resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
524 | integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=
525 | dependencies:
526 | is-property "^1.0.0"
527 |
528 | glob@^7.0.0, glob@^7.0.3, glob@^7.1.3:
529 | version "7.1.4"
530 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
531 | integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
532 | dependencies:
533 | fs.realpath "^1.0.0"
534 | inflight "^1.0.4"
535 | inherits "2"
536 | minimatch "^3.0.4"
537 | once "^1.3.0"
538 | path-is-absolute "^1.0.0"
539 |
540 | globals@^9.14.0, globals@^9.18.0:
541 | version "9.18.0"
542 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
543 | integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
544 |
545 | graceful-fs@^4.1.2:
546 | version "4.2.2"
547 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
548 | integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
549 |
550 | has-ansi@^2.0.0:
551 | version "2.0.0"
552 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
553 | integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
554 | dependencies:
555 | ansi-regex "^2.0.0"
556 |
557 | iconv-lite@~0.4.13:
558 | version "0.4.24"
559 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
560 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
561 | dependencies:
562 | safer-buffer ">= 2.1.2 < 3"
563 |
564 | ignore@^3.2.0:
565 | version "3.3.10"
566 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
567 | integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
568 |
569 | imurmurhash@^0.1.4:
570 | version "0.1.4"
571 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
572 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
573 |
574 | inflight@^1.0.4:
575 | version "1.0.6"
576 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
577 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
578 | dependencies:
579 | once "^1.3.0"
580 | wrappy "1"
581 |
582 | inherits@2, inherits@^2.0.3, inherits@~2.0.3:
583 | version "2.0.4"
584 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
585 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
586 |
587 | inquirer@^0.12.0:
588 | version "0.12.0"
589 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e"
590 | integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=
591 | dependencies:
592 | ansi-escapes "^1.1.0"
593 | ansi-regex "^2.0.0"
594 | chalk "^1.0.0"
595 | cli-cursor "^1.0.1"
596 | cli-width "^2.0.0"
597 | figures "^1.3.5"
598 | lodash "^4.3.0"
599 | readline2 "^1.0.1"
600 | run-async "^0.1.0"
601 | rx-lite "^3.1.2"
602 | string-width "^1.0.1"
603 | strip-ansi "^3.0.0"
604 | through "^2.3.6"
605 |
606 | interpret@^1.0.0:
607 | version "1.2.0"
608 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
609 | integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
610 |
611 | invariant@*, invariant@^2.2.2:
612 | version "2.2.4"
613 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
614 | integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
615 | dependencies:
616 | loose-envify "^1.0.0"
617 |
618 | is-fullwidth-code-point@^1.0.0:
619 | version "1.0.0"
620 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
621 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
622 | dependencies:
623 | number-is-nan "^1.0.0"
624 |
625 | is-fullwidth-code-point@^2.0.0:
626 | version "2.0.0"
627 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
628 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
629 |
630 | is-my-ip-valid@^1.0.0:
631 | version "1.0.0"
632 | resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824"
633 | integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==
634 |
635 | is-my-json-valid@^2.10.0:
636 | version "2.20.0"
637 | resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz#1345a6fca3e8daefc10d0fa77067f54cedafd59a"
638 | integrity sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==
639 | dependencies:
640 | generate-function "^2.0.0"
641 | generate-object-property "^1.1.0"
642 | is-my-ip-valid "^1.0.0"
643 | jsonpointer "^4.0.0"
644 | xtend "^4.0.0"
645 |
646 | is-property@^1.0.0, is-property@^1.0.2:
647 | version "1.0.2"
648 | resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
649 | integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=
650 |
651 | is-resolvable@^1.0.0:
652 | version "1.1.0"
653 | resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
654 | integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
655 |
656 | is-stream@^1.0.1:
657 | version "1.1.0"
658 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
659 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
660 |
661 | isarray@~1.0.0:
662 | version "1.0.0"
663 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
664 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
665 |
666 | isomorphic-fetch@^2.1.1:
667 | version "2.2.1"
668 | resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
669 | integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
670 | dependencies:
671 | node-fetch "^1.0.1"
672 | whatwg-fetch ">=0.10.0"
673 |
674 | "js-tokens@^3.0.0 || ^4.0.0":
675 | version "4.0.0"
676 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
677 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
678 |
679 | js-tokens@^3.0.2:
680 | version "3.0.2"
681 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
682 | integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
683 |
684 | js-yaml@^3.5.1:
685 | version "3.13.1"
686 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
687 | integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
688 | dependencies:
689 | argparse "^1.0.7"
690 | esprima "^4.0.0"
691 |
692 | json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
693 | version "1.0.1"
694 | resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
695 | integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=
696 | dependencies:
697 | jsonify "~0.0.0"
698 |
699 | jsonify@~0.0.0:
700 | version "0.0.0"
701 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
702 | integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
703 |
704 | jsonpointer@^4.0.0:
705 | version "4.0.1"
706 | resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
707 | integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk=
708 |
709 | levn@^0.3.0, levn@~0.3.0:
710 | version "0.3.0"
711 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
712 | integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
713 | dependencies:
714 | prelude-ls "~1.1.2"
715 | type-check "~0.3.2"
716 |
717 | lodash.assign@^4.0.0:
718 | version "4.2.0"
719 | resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
720 | integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=
721 |
722 | lodash.pickby@^4.0.0:
723 | version "4.6.0"
724 | resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff"
725 | integrity sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=
726 |
727 | lodash@^4.0.0, lodash@^4.17.4, lodash@^4.3.0:
728 | version "4.17.15"
729 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
730 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
731 |
732 | loose-envify@^1.0.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
733 | version "1.4.0"
734 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
735 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
736 | dependencies:
737 | js-tokens "^3.0.0 || ^4.0.0"
738 |
739 | minimatch@^3.0.4:
740 | version "3.0.4"
741 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
742 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
743 | dependencies:
744 | brace-expansion "^1.1.7"
745 |
746 | minimist@0.0.8:
747 | version "0.0.8"
748 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
749 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
750 |
751 | mkdirp@^0.5.0, mkdirp@^0.5.1:
752 | version "0.5.1"
753 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
754 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
755 | dependencies:
756 | minimist "0.0.8"
757 |
758 | ms@2.0.0:
759 | version "2.0.0"
760 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
761 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
762 |
763 | mute-stream@0.0.5:
764 | version "0.0.5"
765 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
766 | integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=
767 |
768 | natural-compare@^1.4.0:
769 | version "1.4.0"
770 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
771 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
772 |
773 | next-tick@^1.0.0:
774 | version "1.0.0"
775 | resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
776 | integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
777 |
778 | node-fetch@^1.0.1:
779 | version "1.7.3"
780 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
781 | integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
782 | dependencies:
783 | encoding "^0.1.11"
784 | is-stream "^1.0.1"
785 |
786 | number-is-nan@^1.0.0:
787 | version "1.0.1"
788 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
789 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
790 |
791 | object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
792 | version "4.1.1"
793 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
794 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
795 |
796 | once@^1.3.0:
797 | version "1.4.0"
798 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
799 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
800 | dependencies:
801 | wrappy "1"
802 |
803 | onetime@^1.0.0:
804 | version "1.1.0"
805 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
806 | integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=
807 |
808 | optionator@^0.8.2:
809 | version "0.8.2"
810 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
811 | integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
812 | dependencies:
813 | deep-is "~0.1.3"
814 | fast-levenshtein "~2.0.4"
815 | levn "~0.3.0"
816 | prelude-ls "~1.1.2"
817 | type-check "~0.3.2"
818 | wordwrap "~1.0.0"
819 |
820 | os-homedir@^1.0.0:
821 | version "1.0.2"
822 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
823 | integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
824 |
825 | path-is-absolute@^1.0.0:
826 | version "1.0.1"
827 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
828 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
829 |
830 | path-is-inside@^1.0.1:
831 | version "1.0.2"
832 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
833 | integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
834 |
835 | path-parse@^1.0.6:
836 | version "1.0.6"
837 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
838 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
839 |
840 | pluralize@^1.2.1:
841 | version "1.2.1"
842 | resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
843 | integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=
844 |
845 | prelude-ls@~1.1.2:
846 | version "1.1.2"
847 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
848 | integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
849 |
850 | process-nextick-args@~2.0.0:
851 | version "2.0.1"
852 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
853 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
854 |
855 | progress@^1.1.8:
856 | version "1.1.8"
857 | resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
858 | integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=
859 |
860 | promise@^7.1.1:
861 | version "7.3.1"
862 | resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
863 | integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
864 | dependencies:
865 | asap "~2.0.3"
866 |
867 | prop-types@*:
868 | version "15.8.1"
869 | resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
870 | integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
871 | dependencies:
872 | loose-envify "^1.4.0"
873 | object-assign "^4.1.1"
874 | react-is "^16.13.1"
875 |
876 | prop-types@^15.6.0:
877 | version "15.7.2"
878 | resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
879 | integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
880 | dependencies:
881 | loose-envify "^1.4.0"
882 | object-assign "^4.1.1"
883 | react-is "^16.8.1"
884 |
885 | react-is@^16.13.1:
886 | version "16.13.1"
887 | resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
888 | integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
889 |
890 | react-is@^16.8.1:
891 | version "16.9.0"
892 | resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
893 | integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==
894 |
895 | react-timer-mixin@^0.13.3:
896 | version "0.13.4"
897 | resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz#75a00c3c94c13abe29b43d63b4c65a88fc8264d3"
898 | integrity sha512-4+ow23tp/Tv7hBM5Az5/Be/eKKF7DIvJ09voz5LyHGQaqqz9WV8YMs31eFvcYQs7d451LSg7kDJV70XYN/Ug/Q==
899 |
900 | readable-stream@^2.2.2:
901 | version "2.3.6"
902 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
903 | integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
904 | dependencies:
905 | core-util-is "~1.0.0"
906 | inherits "~2.0.3"
907 | isarray "~1.0.0"
908 | process-nextick-args "~2.0.0"
909 | safe-buffer "~5.1.1"
910 | string_decoder "~1.1.1"
911 | util-deprecate "~1.0.1"
912 |
913 | readline2@^1.0.1:
914 | version "1.0.1"
915 | resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
916 | integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=
917 | dependencies:
918 | code-point-at "^1.0.0"
919 | is-fullwidth-code-point "^1.0.0"
920 | mute-stream "0.0.5"
921 |
922 | rechoir@^0.6.2:
923 | version "0.6.2"
924 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
925 | integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
926 | dependencies:
927 | resolve "^1.1.6"
928 |
929 | regenerator-runtime@^0.11.0:
930 | version "0.11.1"
931 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
932 | integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
933 |
934 | require-uncached@^1.0.2:
935 | version "1.0.3"
936 | resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
937 | integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=
938 | dependencies:
939 | caller-path "^0.1.0"
940 | resolve-from "^1.0.0"
941 |
942 | resolve-from@^1.0.0:
943 | version "1.0.1"
944 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
945 | integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=
946 |
947 | resolve@^1.1.6:
948 | version "1.12.0"
949 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6"
950 | integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==
951 | dependencies:
952 | path-parse "^1.0.6"
953 |
954 | restore-cursor@^1.0.1:
955 | version "1.0.1"
956 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
957 | integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=
958 | dependencies:
959 | exit-hook "^1.0.0"
960 | onetime "^1.0.0"
961 |
962 | rimraf@~2.6.2:
963 | version "2.6.3"
964 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
965 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
966 | dependencies:
967 | glob "^7.1.3"
968 |
969 | run-async@^0.1.0:
970 | version "0.1.0"
971 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
972 | integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=
973 | dependencies:
974 | once "^1.3.0"
975 |
976 | rx-lite@^3.1.2:
977 | version "3.1.2"
978 | resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
979 | integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=
980 |
981 | safe-buffer@~5.1.0, safe-buffer@~5.1.1:
982 | version "5.1.2"
983 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
984 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
985 |
986 | "safer-buffer@>= 2.1.2 < 3":
987 | version "2.1.2"
988 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
989 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
990 |
991 | setimmediate@^1.0.5:
992 | version "1.0.5"
993 | resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
994 | integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
995 |
996 | shelljs@^0.7.5:
997 | version "0.7.8"
998 | resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
999 | integrity sha1-3svPh0sNHl+3LhSxZKloMEjprLM=
1000 | dependencies:
1001 | glob "^7.0.0"
1002 | interpret "^1.0.0"
1003 | rechoir "^0.6.2"
1004 |
1005 | slice-ansi@0.0.4:
1006 | version "0.0.4"
1007 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
1008 | integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=
1009 |
1010 | sprintf-js@~1.0.2:
1011 | version "1.0.3"
1012 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
1013 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
1014 |
1015 | string-width@^1.0.1:
1016 | version "1.0.2"
1017 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
1018 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
1019 | dependencies:
1020 | code-point-at "^1.0.0"
1021 | is-fullwidth-code-point "^1.0.0"
1022 | strip-ansi "^3.0.0"
1023 |
1024 | string-width@^2.0.0:
1025 | version "2.1.1"
1026 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
1027 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
1028 | dependencies:
1029 | is-fullwidth-code-point "^2.0.0"
1030 | strip-ansi "^4.0.0"
1031 |
1032 | string_decoder@~1.1.1:
1033 | version "1.1.1"
1034 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
1035 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
1036 | dependencies:
1037 | safe-buffer "~5.1.0"
1038 |
1039 | strip-ansi@^3.0.0:
1040 | version "3.0.1"
1041 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
1042 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
1043 | dependencies:
1044 | ansi-regex "^2.0.0"
1045 |
1046 | strip-ansi@^4.0.0:
1047 | version "4.0.0"
1048 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
1049 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
1050 | dependencies:
1051 | ansi-regex "^3.0.0"
1052 |
1053 | strip-bom@^3.0.0:
1054 | version "3.0.0"
1055 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
1056 | integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
1057 |
1058 | strip-json-comments@~2.0.1:
1059 | version "2.0.1"
1060 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
1061 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
1062 |
1063 | supports-color@^2.0.0:
1064 | version "2.0.0"
1065 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
1066 | integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
1067 |
1068 | table@^3.7.8:
1069 | version "3.8.3"
1070 | resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f"
1071 | integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=
1072 | dependencies:
1073 | ajv "^4.7.0"
1074 | ajv-keywords "^1.0.0"
1075 | chalk "^1.1.1"
1076 | lodash "^4.0.0"
1077 | slice-ansi "0.0.4"
1078 | string-width "^2.0.0"
1079 |
1080 | text-table@~0.2.0:
1081 | version "0.2.0"
1082 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
1083 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
1084 |
1085 | through@^2.3.6:
1086 | version "2.3.8"
1087 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
1088 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
1089 |
1090 | to-fast-properties@^1.0.3:
1091 | version "1.0.3"
1092 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
1093 | integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=
1094 |
1095 | type-check@~0.3.2:
1096 | version "0.3.2"
1097 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
1098 | integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
1099 | dependencies:
1100 | prelude-ls "~1.1.2"
1101 |
1102 | type@^1.0.1:
1103 | version "1.2.0"
1104 | resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
1105 | integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
1106 |
1107 | typedarray@^0.0.6:
1108 | version "0.0.6"
1109 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
1110 | integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
1111 |
1112 | ua-parser-js@^0.7.18:
1113 | version "0.7.20"
1114 | resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098"
1115 | integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==
1116 |
1117 | user-home@^2.0.0:
1118 | version "2.0.0"
1119 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
1120 | integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8=
1121 | dependencies:
1122 | os-homedir "^1.0.0"
1123 |
1124 | util-deprecate@~1.0.1:
1125 | version "1.0.2"
1126 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
1127 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
1128 |
1129 | whatwg-fetch@>=0.10.0:
1130 | version "3.0.0"
1131 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
1132 | integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
1133 |
1134 | wordwrap@~1.0.0:
1135 | version "1.0.0"
1136 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
1137 | integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
1138 |
1139 | wrappy@1:
1140 | version "1.0.2"
1141 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1142 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
1143 |
1144 | write@^0.2.1:
1145 | version "0.2.1"
1146 | resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
1147 | integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=
1148 | dependencies:
1149 | mkdirp "^0.5.1"
1150 |
1151 | xtend@^4.0.0:
1152 | version "4.0.2"
1153 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
1154 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
1155 |
--------------------------------------------------------------------------------