Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f1ed20a6e |
@@ -5,5 +5,4 @@
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
||||
|
||||
[alias]
|
||||
movies = //Examples/Movies/android/app:app
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
-Xmx512m -XX:+HeapDumpOnOutOfMemoryError
|
||||
@@ -19,7 +19,6 @@
|
||||
"__DEV__": true,
|
||||
"__dirname": false,
|
||||
"__fbBatchedBridgeConfig": false,
|
||||
"alert": false,
|
||||
"cancelAnimationFrame": false,
|
||||
"clearImmediate": true,
|
||||
"clearInterval": false,
|
||||
@@ -27,11 +26,8 @@
|
||||
"console": false,
|
||||
"document": false,
|
||||
"escape": false,
|
||||
"Event": false,
|
||||
"EventTarget": false,
|
||||
"exports": false,
|
||||
"fetch": false,
|
||||
"FormData": false,
|
||||
"global": false,
|
||||
"jest": false,
|
||||
"Map": true,
|
||||
@@ -47,29 +43,7 @@
|
||||
"setTimeout": false,
|
||||
"window": false,
|
||||
"XMLHttpRequest": false,
|
||||
"pit": false,
|
||||
|
||||
// Flow global types.
|
||||
"ReactComponent": false,
|
||||
"ReactClass": false,
|
||||
"ReactElement": false,
|
||||
"ReactPropsCheckType": false,
|
||||
"ReactPropsChainableTypeChecker": false,
|
||||
"ReactPropTypes": false,
|
||||
"SyntheticEvent": false,
|
||||
"$Either": false,
|
||||
"$All": false,
|
||||
"$Tuple": false,
|
||||
"$Supertype": false,
|
||||
"$Subtype": false,
|
||||
"$Shape": false,
|
||||
"$Diff": false,
|
||||
"$Keys": false,
|
||||
"$Enum": false,
|
||||
"$Exports": false,
|
||||
"$FlowIssue": false,
|
||||
"$FlowFixMe": false,
|
||||
"$FixMe": false
|
||||
"pit": false
|
||||
},
|
||||
|
||||
"rules": {
|
||||
@@ -107,12 +81,13 @@
|
||||
"curly": 1, // specify curly brace conventions for all control statements
|
||||
"default-case": 0, // require default case in switch statements (off by default)
|
||||
"dot-notation": 1, // encourages use of dot notation whenever possible
|
||||
"eqeqeq": [1, "allow-null"], // require the use of === and !==
|
||||
"eqeqeq": 1, // require the use of === and !==
|
||||
"guard-for-in": 0, // make sure for-in loops have an if statement (off by default)
|
||||
"no-alert": 1, // disallow the use of alert, confirm, and prompt
|
||||
"no-caller": 1, // disallow use of arguments.caller or arguments.callee
|
||||
"no-div-regex": 1, // disallow division operators explicitly at beginning of regular expression (off by default)
|
||||
"no-else-return": 0, // disallow else after a return in an if (off by default)
|
||||
"no-empty-label": 1, // disallow use of labels for anything other then loops and switches
|
||||
"no-eq-null": 0, // disallow comparisons to null without a type-checking operator (off by default)
|
||||
"no-eval": 1, // disallow use of eval()
|
||||
"no-extend-native": 1, // disallow adding to native types
|
||||
@@ -147,6 +122,11 @@
|
||||
"wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses (off by default)
|
||||
"yoda": 1, // require or disallow Yoda conditions
|
||||
|
||||
// Strict Mode
|
||||
// These rules relate to using strict mode.
|
||||
|
||||
"strict": [2, "global"], // require or disallow the "use strict" pragma in the global scope (off by default in the node environment)
|
||||
|
||||
// Variables
|
||||
// These rules have to do with variable declarations.
|
||||
|
||||
@@ -176,8 +156,6 @@
|
||||
// These rules are purely matters of style and are quite subjective.
|
||||
|
||||
"key-spacing": 0,
|
||||
"keyword-spacing": 1, // enforce spacing before and after keywords
|
||||
"jsx-quotes": [1, "prefer-double"],
|
||||
"comma-spacing": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"brace-style": 0, // enforce one true brace style (off by default)
|
||||
@@ -201,9 +179,11 @@
|
||||
"quote-props": 0, // require quotes around object literal property names (off by default)
|
||||
"semi": 1, // require or disallow use of semicolons instead of ASI
|
||||
"sort-vars": 0, // sort variables within the same declaration block (off by default)
|
||||
"space-after-keywords": 1, // require a space after certain keywords (off by default)
|
||||
"space-in-brackets": 0, // require or disallow spaces inside brackets (off by default)
|
||||
"space-in-parens": 0, // require or disallow spaces inside parentheses (off by default)
|
||||
"space-infix-ops": 1, // require spaces around operators
|
||||
"space-return-throw-case": 1, // require a space after return, throw, and case
|
||||
"space-unary-ops": [1, { "words": true, "nonwords": false }], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default)
|
||||
"max-nested-callbacks": 0, // specify the maximum depth callbacks can be nested (off by default)
|
||||
"one-var": 0, // allow just one var statement per function (off by default)
|
||||
@@ -221,6 +201,7 @@
|
||||
|
||||
"react/display-name": 0,
|
||||
"react/jsx-boolean-value": 0,
|
||||
"react/jsx-quotes": [1, "double", "avoid-escape"],
|
||||
"react/jsx-no-undef": 1,
|
||||
"react/jsx-sort-props": 0,
|
||||
"react/jsx-uses-react": 0,
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
# Ignore react and fbjs where there are overlaps, but don't ignore
|
||||
# anything that react-native relies on
|
||||
.*/node_modules/fbjs/lib/Map.js
|
||||
.*/node_modules/fbjs/lib/Promise.js
|
||||
.*/node_modules/fbjs/lib/fetch.js
|
||||
.*/node_modules/fbjs/lib/ExecutionEnvironment.js
|
||||
.*/node_modules/fbjs/lib/isEmpty.js
|
||||
.*/node_modules/fbjs/lib/crc32.js
|
||||
.*/node_modules/fbjs/lib/ErrorUtils.js
|
||||
|
||||
# Flow has a built-in definition for the 'react' module which we prefer to use
|
||||
@@ -25,11 +28,6 @@
|
||||
.*/node_modules/react/lib/React.js
|
||||
.*/node_modules/react/lib/ReactDOM.js
|
||||
|
||||
.*/__mocks__/.*
|
||||
.*/__tests__/.*
|
||||
|
||||
.*/commoner/test/source/widget/share.js
|
||||
|
||||
# Ignore commoner tests
|
||||
.*/node_modules/commoner/test/.*
|
||||
|
||||
@@ -42,54 +40,26 @@
|
||||
# Ignore Website
|
||||
.*/website/.*
|
||||
|
||||
# Ignore generators
|
||||
.*/local-cli/generator.*
|
||||
|
||||
# Ignore BUCK generated folders
|
||||
.*\.buckd/
|
||||
|
||||
.*/node_modules/is-my-json-valid/test/.*\.json
|
||||
.*/node_modules/iconv-lite/encodings/tables/.*\.json
|
||||
.*/node_modules/y18n/test/.*\.json
|
||||
.*/node_modules/spdx-license-ids/spdx-license-ids.json
|
||||
.*/node_modules/spdx-exceptions/index.json
|
||||
.*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json
|
||||
.*/node_modules/resolve/lib/core.json
|
||||
.*/node_modules/jsonparse/samplejson/.*\.json
|
||||
.*/node_modules/json5/test/.*\.json
|
||||
.*/node_modules/ua-parser-js/test/.*\.json
|
||||
.*/node_modules/builtin-modules/builtin-modules.json
|
||||
.*/node_modules/binary-extensions/binary-extensions.json
|
||||
.*/node_modules/url-regex/tlds.json
|
||||
.*/node_modules/joi/.*\.json
|
||||
.*/node_modules/isemail/.*\.json
|
||||
.*/node_modules/tr46/.*\.json
|
||||
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
Libraries/react-native/react-native-interface.js
|
||||
flow/
|
||||
|
||||
[options]
|
||||
module.system=haste
|
||||
|
||||
esproposal.class_static_fields=enable
|
||||
esproposal.class_instance_fields=enable
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
|
||||
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\)$' -> 'RelativeImageStub'
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-2]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-2]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-0]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-0]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[version]
|
||||
^0.22.0
|
||||
0.20.1
|
||||
|
||||
@@ -24,23 +24,13 @@ project.xcworkspace
|
||||
# Gradle
|
||||
/build/
|
||||
/Examples/**/android/app/build/
|
||||
/Examples/**/android/app/gradle/
|
||||
/Examples/**/android/app/gradlew
|
||||
/Examples/**/android/app/gradlew.bat
|
||||
/ReactAndroid/build/
|
||||
|
||||
# Buck
|
||||
.buckd
|
||||
buck-out
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/armeabi-v7a/
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/x86/
|
||||
|
||||
# Android
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
/android/
|
||||
|
||||
# Node
|
||||
node_modules
|
||||
|
||||
@@ -2,39 +2,86 @@ language: objective-c
|
||||
|
||||
osx_image: xcode7.2
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- .nvm
|
||||
|
||||
install:
|
||||
- brew reinstall nvm
|
||||
- mkdir -p /Users/travis/build/facebook/.nvm
|
||||
- export NVM_DIR="/Users/travis/build/facebook/.nvm"
|
||||
- mkdir -p .nvm
|
||||
- export NVM_DIR="$PWD/.nvm"
|
||||
- source $(brew --prefix nvm)/nvm.sh
|
||||
# testing with npm@2 for diversity, Circle tests with npm@3
|
||||
- nvm install 4.4.0
|
||||
- nvm install 5
|
||||
- rm -Rf "${TMPDIR}/jest_preprocess_cache"
|
||||
- npm config set spin=false
|
||||
- npm config set progress=false
|
||||
- npm install -g flow-bin@`node -p "require('fs').readFileSync('.flowconfig', 'utf8').split('[version]')[1].trim()"`
|
||||
- npm install
|
||||
|
||||
script:
|
||||
- if [[ "$TEST_TYPE" = objc ]]; then travis_retry ./scripts/objc-test.sh; fi
|
||||
- if [[ "$TEST_TYPE" = e2e-objc ]]; then travis_retry ./scripts/e2e-test.sh --ios; fi
|
||||
- if [[ "$TEST_TYPE" = js ]]; then npm run flow check; fi
|
||||
- if [[ "$TEST_TYPE" = js ]]; then npm test -- --maxWorkers=1; fi
|
||||
- if [[ "$TEST_TYPE" = js ]]; then travis_retry ./scripts/e2e-test.sh --packager; fi
|
||||
- |
|
||||
if [ "$TEST_TYPE" = objc ]
|
||||
then
|
||||
|
||||
./scripts/objc-test.sh
|
||||
|
||||
elif [ "$TEST_TYPE" = js ]
|
||||
then
|
||||
|
||||
npm install github@0.2.4
|
||||
cat <(echo eslint; npm run lint --silent -- --format=json; echo flow; flow --json) | GITHUB_TOKEN="af6ef0d15709bc91d""06a6217a5a826a226fb57b7" node bots/code-analysis-bot.js
|
||||
flow check && npm test -- '\/Libraries\/'
|
||||
|
||||
elif [ "$TEST_TYPE" = packager ]
|
||||
then
|
||||
|
||||
npm test -- '\/packager\/'
|
||||
|
||||
elif [ "$TEST_TYPE" = cli ]
|
||||
then
|
||||
|
||||
npm test -- '\/(local|private|react-native)-cli\/'
|
||||
|
||||
elif [ "$TEST_TYPE" = build_website ]
|
||||
then
|
||||
|
||||
cd website
|
||||
$(which npm) install
|
||||
./setup.sh
|
||||
if [ "$TRAVIS_PULL_REQUEST" = false ] && [ "$TRAVIS_BRANCH" = master ]; then
|
||||
# Automatically publish the website
|
||||
echo "machine github.com login reactjs-bot password $GITHUB_TOKEN" >~/.netrc
|
||||
./publish.sh
|
||||
else
|
||||
# Make sure the website builds without error
|
||||
node server/generate.js
|
||||
fi
|
||||
|
||||
elif [ "$TEST_TYPE" = e2e ]
|
||||
then
|
||||
./scripts/e2e-test.sh
|
||||
else
|
||||
echo "Unknown test type: $TEST_TYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- TEST_TYPE=objc
|
||||
- TEST_TYPE=js
|
||||
- TEST_TYPE=e2e-objc
|
||||
- TEST_TYPE=packager
|
||||
- TEST_TYPE=cli
|
||||
- TEST_TYPE=build_website
|
||||
- TEST_TYPE=e2e
|
||||
global:
|
||||
# $GITHUB_TOKEN
|
||||
- secure: "HlmG8M2DmBUSBh6KH1yVIe/8gR4iibg4WfcHq1x/xYQxGbvleq7NOo04V6eFHnl9cvZCu+PKH0841WLnGR7c4BBf47GVu/o16nXzggPumHKy++lDzxFPlJ1faMDfjg/5vjbAxRUe7D3y98hQSeGHH4tedc8LvTaFLVu7iiGqvjU="
|
||||
# $APPETIZE_TOKEN
|
||||
- secure: "egsvVSpszTzrNd6bN62DsVAzMiSZI/OHgdizfPryqvqWBf655ztE6XFQSEFNpuIAzSKDDF25ioT8iPfVsbC1iK6HDWHfmqYxML0L+OoU0gi+hV2oKUBFZDZ1fwSnFoWuBdNdMDpLlUxvJp6N1WyfNOB2dxuZUt8eTt48Hi3+Hpc="
|
||||
# $S3_TOKEN
|
||||
- secure: "lY8JZPA0A7zT7L5KF9BBg34XYWIeR/RJiEvE7l7oVr88KnEPtyd//79eHhhVKnUnav7zsk5QJwkcX0MxKTp/dp4G0Am+zOX+sfA8kQrJ+2/+FzFW7AEsW/kHByfaIEIly9DQvUFt4I4oMm8nQZysJLahDgNWglyI3RTuJp//hcY="
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^.*-stable$/
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- bestander@gmail.com
|
||||
on_failure: change
|
||||
on_success: change
|
||||
|
||||
@@ -17,19 +17,13 @@ The core team will be monitoring for pull requests. When we get one, we'll run s
|
||||
*Before* submitting a pull request, please make sure the following is done…
|
||||
|
||||
1. Fork the repo and create your branch from `master`.
|
||||
2. **Describe your test plan in your commit.** If you've added code that should be tested, add tests!
|
||||
2. If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. If you've updated the docs, verify the website locally and submit screenshots if applicable
|
||||
```
|
||||
$ cd website
|
||||
$ npm install && npm start
|
||||
go to: http://localhost:8079/react-native/index.html
|
||||
```
|
||||
5. Add the copyright notice to the top of any new files you've added.
|
||||
6. Ensure tests pass on Travis and Circle CI.
|
||||
7. Make sure your code lints (`node linter.js <files touched>`).
|
||||
8. Squash your commits (`git rebase -i`).
|
||||
9. If you haven't already, sign the [CLA](https://code.facebook.com/cla).
|
||||
4. Add the copyright notice to the top of any new files you've added.
|
||||
5. Ensure tests pass on Travis and Circle CI.
|
||||
6. Make sure your code lints (`node linter.js <files touched>`).
|
||||
7. Squash your commits (`git rebase -i`).
|
||||
8. If you haven't already, sign the [CLA](https://code.facebook.com/cla).
|
||||
|
||||
#### Copyright Notice for files
|
||||
|
||||
@@ -79,7 +73,6 @@ Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
|
||||
|
||||
#### General
|
||||
|
||||
* **Most important: Look around.** Match the style you see used in the rest of the project. This includes formatting, naming things in code, naming things in documentation.
|
||||
* Add trailing commas,
|
||||
* 2 spaces for indentation (no tabs)
|
||||
* "Attractive"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-alert": 0
|
||||
}
|
||||
}
|
||||
@@ -53,8 +53,6 @@ class Board extends React.Component {
|
||||
}
|
||||
|
||||
class Tile extends React.Component {
|
||||
state: any;
|
||||
|
||||
static _getPosition(index): number {
|
||||
return BOARD_PADDING + (index * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||
}
|
||||
@@ -149,7 +147,6 @@ class GameEndOverlay extends React.Component {
|
||||
class Game2048 extends React.Component {
|
||||
startX: number;
|
||||
startY: number;
|
||||
state: any;
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
@@ -27,7 +27,7 @@ var {
|
||||
} = React;
|
||||
var TimerMixin = require('react-timer-mixin');
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
var invariant = require('invariant');
|
||||
var dismissKeyboard = require('dismissKeyboard');
|
||||
|
||||
var MovieCell = require('./MovieCell');
|
||||
@@ -316,7 +316,7 @@ var SearchScreen = React.createClass({
|
||||
onSearchChange={this.onSearchChange}
|
||||
isLoading={this.state.isLoading}
|
||||
onFocus={() =>
|
||||
this.refs.listview && this.refs.listview.getScrollResponder().scrollTo({ x: 0, y: 0 })}
|
||||
this.refs.listview && this.refs.listview.getScrollResponder().scrollTo(0, 0)}
|
||||
/>
|
||||
<View style={styles.separator} />
|
||||
{content}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
include_defs('//ReactAndroid/DEFS')
|
||||
|
||||
android_binary(
|
||||
name = 'app',
|
||||
manifest = 'src/main/AndroidManifest.xml',
|
||||
keystore = '//keystores:debug',
|
||||
deps = [
|
||||
':movies-lib',
|
||||
],
|
||||
)
|
||||
|
||||
android_library(
|
||||
name = 'movies-lib',
|
||||
srcs = glob(['src/main/java/**/*.java']),
|
||||
deps = [
|
||||
react_native_target('java/com/facebook/csslayout:csslayout'),
|
||||
react_native_target('java/com/facebook/react:react'),
|
||||
react_native_target('java/com/facebook/react/devsupport:devsupport'),
|
||||
react_native_target('java/com/facebook/react/modules/core:core'),
|
||||
react_native_target('java/com/facebook/react/shell:shell'),
|
||||
react_native_target('java/com/facebook/react/touch:touch'),
|
||||
react_native_target('java/com/facebook/react/uimanager:uimanager'),
|
||||
react_native_target('java/com/facebook/react/uimanager/annotations:annotations'),
|
||||
react_native_target('java/com/facebook/react/views/image:image'),
|
||||
react_native_target('java/com/facebook/react/views/recyclerview:recyclerview'),
|
||||
react_native_target('java/com/facebook/react/views/scroll:scroll'),
|
||||
react_native_target('java/com/facebook/react/views/text:text'),
|
||||
react_native_target('java/com/facebook/react/views/view:view'),
|
||||
# .so files are prebuilt by Gradle with `./gradlew :ReactAndroid:packageReactNdkLibsForBuck`
|
||||
react_native_target('jni/prebuilt:reactnative-libs'),
|
||||
react_native_target('jni/prebuilt:android-jsc'),
|
||||
react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'),
|
||||
react_native_dep('third-party/java/jsr-305:jsr-305'),
|
||||
':res',
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
android_resource(
|
||||
name = 'res',
|
||||
res = 'src/main/res',
|
||||
package = 'com.facebook.react.movies',
|
||||
)
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -11,42 +11,79 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.facebook.react.movies;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.facebook.react.LifecycleState;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
public class MoviesActivity extends Activity implements DefaultHardwareBackBtnHandler {
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
private ReactInstanceManager mReactInstanceManager;
|
||||
|
||||
public class MoviesActivity extends ReactActivity {
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "MoviesApp";
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mReactInstanceManager = ReactInstanceManager.builder()
|
||||
.setApplication(getApplication())
|
||||
.setBundleAssetName("MoviesApp.android.bundle")
|
||||
.setJSMainModuleName("Examples/Movies/MoviesApp.android")
|
||||
.addPackage(new MainReactPackage())
|
||||
.setUseDeveloperSupport(true)
|
||||
.setInitialLifecycleState(LifecycleState.RESUMED)
|
||||
.build();
|
||||
|
||||
((ReactRootView) findViewById(R.id.react_root_view))
|
||||
.startReactApplication(mReactInstanceManager, "MoviesApp", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable String getBundleAssetName() {
|
||||
return "MoviesApp.android.bundle";
|
||||
};
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "Examples/Movies/MoviesApp.android";
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
|
||||
mReactInstanceManager.showDevOptionsDialog();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
return true;
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage()
|
||||
);
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onResume(this, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onBackPressed();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeDefaultOnBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ var styles = StyleSheet.create({
|
||||
textAlign: 'center',
|
||||
},
|
||||
newGame: {
|
||||
backgroundColor: '#887765',
|
||||
backgroundColor: '#887766',
|
||||
padding: 20,
|
||||
borderRadius: 5,
|
||||
},
|
||||
|
||||
@@ -20,7 +20,6 @@ var {
|
||||
ActionSheetIOS,
|
||||
StyleSheet,
|
||||
Text,
|
||||
UIManager,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
@@ -99,6 +98,7 @@ var ActionSheetTintExample = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var ShareActionSheetExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
@@ -121,14 +121,16 @@ var ShareActionSheetExample = React.createClass({
|
||||
|
||||
showShareActionSheet() {
|
||||
ActionSheetIOS.showShareActionSheetWithOptions({
|
||||
url: this.props.url,
|
||||
url: 'https://code.facebook.com',
|
||||
message: 'message to go with the shared url',
|
||||
subject: 'a subject to go in the email heading',
|
||||
excludedActivityTypes: [
|
||||
'com.apple.UIKit.activity.PostToTwitter'
|
||||
]
|
||||
},
|
||||
(error) => alert(error),
|
||||
(error) => {
|
||||
console.error(error);
|
||||
},
|
||||
(success, method) => {
|
||||
var text;
|
||||
if (success) {
|
||||
@@ -141,50 +143,6 @@ var ShareActionSheetExample = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
var ShareScreenshotExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
text: ''
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text onPress={this.showShareActionSheet} style={style.button}>
|
||||
Click to show the Share ActionSheet
|
||||
</Text>
|
||||
<Text>
|
||||
{this.state.text}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
showShareActionSheet() {
|
||||
// Take the snapshot (returns a temp file uri)
|
||||
UIManager.takeSnapshot('window').then((uri) => {
|
||||
// Share image data
|
||||
ActionSheetIOS.showShareActionSheetWithOptions({
|
||||
url: uri,
|
||||
excludedActivityTypes: [
|
||||
'com.apple.UIKit.activity.PostToTwitter'
|
||||
]
|
||||
},
|
||||
(error) => alert(error),
|
||||
(success, method) => {
|
||||
var text;
|
||||
if (success) {
|
||||
text = `Shared via ${method}`;
|
||||
} else {
|
||||
text = 'You didn\'t share';
|
||||
}
|
||||
this.setState({text});
|
||||
});
|
||||
}).catch((error) => alert(error));
|
||||
}
|
||||
});
|
||||
|
||||
var style = StyleSheet.create({
|
||||
button: {
|
||||
marginBottom: 10,
|
||||
@@ -205,20 +163,6 @@ exports.examples = [
|
||||
},
|
||||
{
|
||||
title: 'Show Share Action Sheet',
|
||||
render(): ReactElement {
|
||||
return <ShareActionSheetExample url="https://code.facebook.com" />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Share Local Image',
|
||||
render(): ReactElement {
|
||||
return <ShareActionSheetExample url="bunny.png" />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Share Screenshot',
|
||||
render(): ReactElement {
|
||||
return <ShareScreenshotExample />;
|
||||
}
|
||||
render(): ReactElement { return <ShareActionSheetExample />; }
|
||||
}
|
||||
];
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Alert,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
@@ -133,4 +134,4 @@ var styles = StyleSheet.create({
|
||||
module.exports = {
|
||||
AlertExample,
|
||||
SimpleAlertExampleBlock,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,19 +36,37 @@ exports.examples = [{
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Prompt Options',
|
||||
render(): ReactElement {
|
||||
return <PromptOptions />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Prompt Types',
|
||||
title: 'Alert Types',
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.prompt('Plain Text Entry')}>
|
||||
onPress={() => AlertIOS.alert(
|
||||
'Hello World',
|
||||
null,
|
||||
[
|
||||
{text: 'OK', onPress: (text) => console.log('OK pressed'), type: 'default'}
|
||||
]
|
||||
)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
{'default'}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.alert(
|
||||
'Plain Text Entry',
|
||||
null,
|
||||
[
|
||||
{text: 'Submit', onPress: (text) => console.log('Text: ' + text), type: 'plain-text'},
|
||||
{text: 'Cancel', onPress: () => console.log('Cancel'), style: 'cancel'}
|
||||
]
|
||||
)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
@@ -59,7 +77,14 @@ exports.examples = [{
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.prompt('Secure Text', null, null, 'secure-text')}>
|
||||
onPress={() => AlertIOS.alert(
|
||||
'Secure Text Entry',
|
||||
null,
|
||||
[
|
||||
{text: 'Submit', onPress: (text) => console.log('Password: ' + text), type: 'secure-text'},
|
||||
{text: 'Cancel', onPress: () => console.log('Cancel'), style: 'cancel'}
|
||||
]
|
||||
)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
@@ -70,7 +95,14 @@ exports.examples = [{
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.prompt('Login & Password', null, null, 'login-password')}>
|
||||
onPress={() => AlertIOS.alert(
|
||||
'Login & Password',
|
||||
null,
|
||||
[
|
||||
{text: 'Submit', onPress: (details) => console.log('Login: ' + details.login + '; Password: ' + details.password), type: 'login-password'},
|
||||
{text: 'Cancel', onPress: () => console.log('Cancel'), style: 'cancel'}
|
||||
]
|
||||
)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
@@ -82,29 +114,32 @@ exports.examples = [{
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Prompt',
|
||||
render(): React.Component {
|
||||
return <PromptExample />;
|
||||
}
|
||||
}];
|
||||
|
||||
class PromptOptions extends React.Component {
|
||||
state: any;
|
||||
customButtons: Array<Object>;
|
||||
|
||||
class PromptExample extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// $FlowFixMe this seems to be a Flow bug, `saveResponse` is defined below
|
||||
this.saveResponse = this.saveResponse.bind(this);
|
||||
this.promptResponse = this.promptResponse.bind(this);
|
||||
this.state = {
|
||||
promptValue: undefined,
|
||||
};
|
||||
|
||||
this.customButtons = [{
|
||||
this.title = 'Type a value';
|
||||
this.defaultValue = 'Default value';
|
||||
this.buttons = [{
|
||||
text: 'Custom OK',
|
||||
onPress: this.saveResponse
|
||||
onPress: this.promptResponse
|
||||
}, {
|
||||
text: 'Custom Cancel',
|
||||
style: 'cancel',
|
||||
}];
|
||||
|
||||
this.state = {
|
||||
promptValue: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -116,7 +151,7 @@ class PromptOptions extends React.Component {
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.prompt('Type a value', null, this.saveResponse)}>
|
||||
onPress={this.prompt.bind(this, this.title, null, null, this.promptResponse)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
@@ -127,7 +162,7 @@ class PromptOptions extends React.Component {
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.prompt('Type a value', null, this.customButtons)}>
|
||||
onPress={this.prompt.bind(this, this.title, null, this.buttons, null)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
@@ -138,22 +173,22 @@ class PromptOptions extends React.Component {
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.prompt('Type a value', null, this.saveResponse, undefined, 'Default value')}>
|
||||
onPress={this.prompt.bind(this, this.title, this.defaultValue, null, this.promptResponse)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
prompt with title, callback & default value
|
||||
prompt with title, default value & callback
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => AlertIOS.prompt('Type a value', null, this.customButtons, 'login-password', 'admin@site.com')}>
|
||||
onPress={this.prompt.bind(this, this.title, this.defaultValue, this.buttons, null)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
prompt with title, custom buttons, login/password & default value
|
||||
prompt with title, default value & custom buttons
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
@@ -161,8 +196,13 @@ class PromptOptions extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
saveResponse(promptValue) {
|
||||
this.setState({ promptValue: JSON.stringify(promptValue) });
|
||||
prompt() {
|
||||
// Flow's apply support is broken: #7035621
|
||||
((AlertIOS.prompt: any).apply: any)(AlertIOS, arguments);
|
||||
}
|
||||
|
||||
promptResponse(promptValue) {
|
||||
this.setState({ promptValue });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@ exports.examples = [
|
||||
'mounts.',
|
||||
render: function() {
|
||||
class FadeInView extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -68,8 +66,6 @@ exports.examples = [
|
||||
}
|
||||
}
|
||||
class FadeInExample extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
@@ -32,10 +32,6 @@ var CIRCLE_MARGIN = 18;
|
||||
var NUM_CIRCLES = 30;
|
||||
|
||||
class Circle extends React.Component {
|
||||
state: any;
|
||||
props: any;
|
||||
longTimer: number;
|
||||
|
||||
_onLongPress: () => void;
|
||||
_toggleIsActive: () => void;
|
||||
constructor(props: Object): void {
|
||||
@@ -160,13 +156,6 @@ class Circle extends React.Component {
|
||||
}
|
||||
|
||||
class AnExApp extends React.Component {
|
||||
state: any;
|
||||
props: any;
|
||||
|
||||
static title = 'Animated - Gratuitous App';
|
||||
static description = 'Bunch of Animations - tap a circle to ' +
|
||||
'open a view with more animations, or longPress and drag to reorder circles.';
|
||||
|
||||
_onMove: (position: Point) => void;
|
||||
constructor(props: any): void {
|
||||
super(props);
|
||||
@@ -277,6 +266,10 @@ function moveToClosest({activeKey, keys, restLayouts}, position) {
|
||||
}
|
||||
}
|
||||
|
||||
AnExApp.title = 'Animated - Gratuitous App';
|
||||
AnExApp.description = 'Bunch of Animations - tap a circle to ' +
|
||||
'open a view with more animations, or longPress and drag to reorder circles.';
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
|
||||
@@ -36,8 +36,6 @@ var BOBBLE_SPOTS = [...Array(NUM_BOBBLES)].map((_, i) => { // static positions
|
||||
});
|
||||
|
||||
class AnExBobble extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
|
||||
@@ -26,8 +26,6 @@ var {
|
||||
} = React;
|
||||
|
||||
class AnExChained extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AnExScroll
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
@@ -27,7 +26,12 @@ var {
|
||||
} = React;
|
||||
|
||||
class AnExScroll extends React.Component {
|
||||
state: any = { scrollX: new Animated.Value(0) };
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
scrollX: new Animated.Value(0),
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
var width = this.props.panelWidth;
|
||||
|
||||
@@ -31,8 +31,6 @@ var AnExScroll = require('./AnExScroll');
|
||||
var AnExTilt = require('./AnExTilt');
|
||||
|
||||
class AnExSet extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
function randColor() {
|
||||
|
||||
@@ -26,8 +26,6 @@ var {
|
||||
} = React;
|
||||
|
||||
class AnExTilt extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule AppStateExample
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppState,
|
||||
Text,
|
||||
View
|
||||
} = React;
|
||||
|
||||
var AppStateSubscription = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
appState: AppState.currentState,
|
||||
previousAppStates: [],
|
||||
};
|
||||
},
|
||||
componentDidMount: function() {
|
||||
AppState.addEventListener('change', this._handleAppStateChange);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
AppState.removeEventListener('change', this._handleAppStateChange);
|
||||
},
|
||||
_handleAppStateChange: function(appState) {
|
||||
var previousAppStates = this.state.previousAppStates.slice();
|
||||
previousAppStates.push(this.state.appState);
|
||||
this.setState({
|
||||
appState,
|
||||
previousAppStates,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
if (this.props.showCurrentOnly) {
|
||||
return (
|
||||
<View>
|
||||
<Text>{this.state.appState}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View>
|
||||
<Text>{JSON.stringify(this.state.previousAppStates)}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.title = 'AppState';
|
||||
exports.description = 'app background status';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'AppState.currentState',
|
||||
description: 'Can be null on app initialization',
|
||||
render() { return <Text>{AppState.currentState}</Text>; }
|
||||
},
|
||||
{
|
||||
title: 'Subscribed AppState:',
|
||||
description: 'This changes according to the current state, so you can only ever see it rendered as "active"',
|
||||
render(): ReactElement { return <AppStateSubscription showCurrentOnly={true} />; }
|
||||
},
|
||||
{
|
||||
title: 'Previous states:',
|
||||
render(): ReactElement { return <AppStateSubscription showCurrentOnly={false} />; }
|
||||
},
|
||||
];
|
||||
@@ -98,34 +98,6 @@ var styles = StyleSheet.create({
|
||||
marginRight: 10,
|
||||
backgroundColor: 'lightgrey',
|
||||
},
|
||||
border9: {
|
||||
borderWidth: 10,
|
||||
borderTopLeftRadius: 10,
|
||||
borderBottomRightRadius: 20,
|
||||
borderColor: 'black',
|
||||
},
|
||||
border10: {
|
||||
borderWidth: 10,
|
||||
backgroundColor: 'white',
|
||||
borderTopLeftRadius: 10,
|
||||
borderBottomRightRadius: 20,
|
||||
borderColor: 'black',
|
||||
elevation: 10,
|
||||
},
|
||||
border11: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
borderStyle: 'solid',
|
||||
overflow: 'hidden',
|
||||
borderTopWidth: 50,
|
||||
borderRightWidth: 0,
|
||||
borderBottomWidth: 50,
|
||||
borderLeftWidth: 100,
|
||||
borderTopColor: 'transparent',
|
||||
borderRightColor: 'transparent',
|
||||
borderBottomColor: 'transparent',
|
||||
borderLeftColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = 'Border';
|
||||
@@ -208,26 +180,4 @@ exports.examples = [
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Corner Radii',
|
||||
description: 'borderTopLeftRadius & borderBottomRightRadius',
|
||||
render() {
|
||||
return <View style={[styles.box, styles.border9]} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Corner Radii / Elevation',
|
||||
description: 'borderTopLeftRadius & borderBottomRightRadius & elevation',
|
||||
platform: 'android',
|
||||
render() {
|
||||
return <View style={[styles.box, styles.border10]} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'CSS Trick - Triangle',
|
||||
description: 'create a triangle by manipulating border colors and widths',
|
||||
render() {
|
||||
return <View style={[styles.border11]} />;
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
@@ -148,8 +148,7 @@ var CameraRollView = React.createClass({
|
||||
fetchParams.after = this.state.lastCursor;
|
||||
}
|
||||
|
||||
CameraRoll.getPhotos(fetchParams)
|
||||
.then((data) => this._appendAssets(data), (e) => logError(e));
|
||||
CameraRoll.getPhotos(fetchParams, this._appendAssets, logError);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,26 +23,23 @@ var {
|
||||
} = React;
|
||||
|
||||
var ClipboardExample = React.createClass({
|
||||
getInitialState() {
|
||||
getInitialState: function() {
|
||||
return {
|
||||
content: 'Content will appear here'
|
||||
};
|
||||
},
|
||||
|
||||
async _setClipboardContent(){
|
||||
|
||||
_setContentToClipboard:function(){
|
||||
Clipboard.setString('Hello World');
|
||||
try {
|
||||
var content = await Clipboard.getString();
|
||||
Clipboard.getString(content => {
|
||||
this.setState({content});
|
||||
} catch (e) {
|
||||
this.setState({content:e.message});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text onPress={this._setClipboardContent} style={{color: 'blue'}}>
|
||||
<Text onPress={this._setContentToClipboard} style={{color: 'blue'}}>
|
||||
Tap to put "Hello World" in the clipboard
|
||||
</Text>
|
||||
<Text style={{color: 'red', marginTop: 20}}>
|
||||
@@ -58,8 +55,6 @@ exports.description = 'Show Clipboard contents.';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Clipboard.setString() and getString()',
|
||||
render() {
|
||||
return <ClipboardExample/>;
|
||||
}
|
||||
render(): ReactElement { return <ClipboardExample />; }
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
DatePickerAndroid,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableWithoutFeedback,
|
||||
} = React;
|
||||
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var DatePickerAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'DatePickerAndroid',
|
||||
description: 'Standard Android date picker dialog',
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
presetDate: new Date(2020, 4, 5),
|
||||
allDate: new Date(2020, 4, 5),
|
||||
simpleText: 'pick a date',
|
||||
minText: 'pick a date, no earlier than today',
|
||||
maxText: 'pick a date, no later than today',
|
||||
presetText: 'pick a date, preset to 2020/5/5',
|
||||
allText: 'pick a date between 2020/5/1 and 2020/5/10',
|
||||
};
|
||||
},
|
||||
|
||||
async showPicker(stateKey, options) {
|
||||
try {
|
||||
var newState = {};
|
||||
const {action, year, month, day} = await DatePickerAndroid.open(options);
|
||||
if (action === DatePickerAndroid.dismissedAction) {
|
||||
newState[stateKey + 'Text'] = 'dismissed';
|
||||
} else {
|
||||
var date = new Date(year, month, day);
|
||||
newState[stateKey + 'Text'] = date.toLocaleDateString();
|
||||
newState[stateKey + 'Date'] = date;
|
||||
}
|
||||
this.setState(newState);
|
||||
} catch ({code, message}) {
|
||||
console.warn(`Error in example '${stateKey}': `, message);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<UIExplorerPage title="DatePickerAndroid">
|
||||
<UIExplorerBlock title="Simple date picker">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'simple', {date: this.state.simpleDate})}>
|
||||
<Text style={styles.text}>{this.state.simpleText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Date picker with pre-set date">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'preset', {date: this.state.presetDate})}>
|
||||
<Text style={styles.text}>{this.state.presetText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Date picker with minDate">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'min', {
|
||||
date: this.state.minDate,
|
||||
minDate: new Date(),
|
||||
})}>
|
||||
<Text style={styles.text}>{this.state.minText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Date picker with maxDate">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'max', {
|
||||
date: this.state.maxDate,
|
||||
maxDate: new Date(),
|
||||
})}>
|
||||
<Text style={styles.text}>{this.state.maxText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Date picker with all options">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'all', {
|
||||
date: this.state.allDate,
|
||||
minDate: new Date(2020, 4, 1),
|
||||
maxDate: new Date(2020, 4, 10),
|
||||
})}>
|
||||
<Text style={styles.text}>{this.state.allText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
text: {
|
||||
color: 'black',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = DatePickerAndroidExample;
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
export type Example = {
|
||||
title: string,
|
||||
render: () => ?ReactElement<any>,
|
||||
/* $FlowFixMe(>=0.16.0) */
|
||||
render: () => ?ReactElement<any, any, any>,
|
||||
description?: string,
|
||||
platform?: string;
|
||||
};
|
||||
|
||||
@@ -46,7 +46,6 @@ var ImageCapInsetsExample = React.createClass({
|
||||
<Image
|
||||
source={require('image!story-background')}
|
||||
style={styles.storyBackground}
|
||||
resizeMode={Image.resizeMode.stretch}
|
||||
capInsets={{left: 15, right: 15, bottom: 15, top: 15}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -22,7 +22,6 @@ var {
|
||||
Image,
|
||||
ImageEditor,
|
||||
NativeModules,
|
||||
Platform,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
@@ -31,6 +30,8 @@ var {
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var RCTScrollViewConsts = UIManager.RCTScrollView.Constants;
|
||||
|
||||
var PAGE_SIZE = 20;
|
||||
|
||||
type ImageOffset = {
|
||||
@@ -47,11 +48,10 @@ type ImageCropData = {
|
||||
offset: ImageOffset;
|
||||
size: ImageSize;
|
||||
displaySize?: ?ImageSize;
|
||||
resizeMode?: ?any;
|
||||
resizeMode?: ?any;
|
||||
};
|
||||
|
||||
class SquareImageCropper extends React.Component {
|
||||
state: any;
|
||||
_isMounted: boolean;
|
||||
_transformData: ImageCropData;
|
||||
|
||||
@@ -67,21 +67,22 @@ class SquareImageCropper extends React.Component {
|
||||
this._fetchRandomPhoto();
|
||||
}
|
||||
|
||||
async _fetchRandomPhoto() {
|
||||
try {
|
||||
const data = await CameraRoll.getPhotos({first: PAGE_SIZE});
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
}
|
||||
var edges = data.edges;
|
||||
var edge = edges[Math.floor(Math.random() * edges.length)];
|
||||
var randomPhoto = edge && edge.node && edge.node.image;
|
||||
if (randomPhoto) {
|
||||
this.setState({randomPhoto});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Can't get a photo from camera roll", error);
|
||||
}
|
||||
_fetchRandomPhoto() {
|
||||
CameraRoll.getPhotos(
|
||||
{first: PAGE_SIZE},
|
||||
(data) => {
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
}
|
||||
var edges = data.edges;
|
||||
var edge = edges[Math.floor(Math.random() * edges.length)];
|
||||
var randomPhoto = edge && edge.node && edge.node.image;
|
||||
if (randomPhoto) {
|
||||
this.setState({randomPhoto});
|
||||
}
|
||||
},
|
||||
(error) => undefined
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -189,49 +190,29 @@ class SquareImageCropper extends React.Component {
|
||||
}
|
||||
|
||||
class ImageCropper extends React.Component {
|
||||
_contentOffset: ImageOffset;
|
||||
_maximumZoomScale: number;
|
||||
_minimumZoomScale: number;
|
||||
_scaledImageSize: ImageSize;
|
||||
_horizontal: boolean;
|
||||
_contentOffset: ImageOffset;
|
||||
|
||||
componentWillMount() {
|
||||
// Scale an image to the minimum size that is large enough to completely
|
||||
// fill the crop box.
|
||||
var widthRatio = this.props.image.width / this.props.size.width;
|
||||
var heightRatio = this.props.image.height / this.props.size.height;
|
||||
this._horizontal = widthRatio > heightRatio;
|
||||
if (this._horizontal) {
|
||||
this._scaledImageSize = {
|
||||
width: this.props.image.width / heightRatio,
|
||||
height: this.props.size.height,
|
||||
};
|
||||
} else {
|
||||
if (widthRatio < heightRatio) {
|
||||
this._scaledImageSize = {
|
||||
width: this.props.size.width,
|
||||
height: this.props.image.height / widthRatio,
|
||||
};
|
||||
if (Platform.OS === 'android') {
|
||||
// hack to work around Android ScrollView a) not supporting zoom, and
|
||||
// b) not supporting vertical scrolling when nested inside another
|
||||
// vertical ScrollView (which it is, when displayed inside UIExplorer)
|
||||
this._scaledImageSize.width *= 2;
|
||||
this._scaledImageSize.height *= 2;
|
||||
this._horizontal = true;
|
||||
}
|
||||
} else {
|
||||
this._scaledImageSize = {
|
||||
width: this.props.image.width / heightRatio,
|
||||
height: this.props.size.height,
|
||||
};
|
||||
}
|
||||
this._contentOffset = {
|
||||
x: (this._scaledImageSize.width - this.props.size.width) / 2,
|
||||
y: (this._scaledImageSize.height - this.props.size.height) / 2,
|
||||
};
|
||||
this._maximumZoomScale = Math.min(
|
||||
this.props.image.width / this._scaledImageSize.width,
|
||||
this.props.image.height / this._scaledImageSize.height
|
||||
);
|
||||
this._minimumZoomScale = Math.max(
|
||||
this.props.size.width / this._scaledImageSize.width,
|
||||
this.props.size.height / this._scaledImageSize.height
|
||||
);
|
||||
this._updateTransformData(
|
||||
this._contentOffset,
|
||||
this._scaledImageSize,
|
||||
@@ -267,15 +248,19 @@ class ImageCropper extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
var decelerationRate =
|
||||
RCTScrollViewConsts && RCTScrollViewConsts.DecelerationRate ?
|
||||
RCTScrollViewConsts.DecelerationRate.Fast :
|
||||
0;
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
alwaysBounceVertical={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
contentOffset={this._contentOffset}
|
||||
decelerationRate="fast"
|
||||
horizontal={this._horizontal}
|
||||
maximumZoomScale={this._maximumZoomScale}
|
||||
minimumZoomScale={this._minimumZoomScale}
|
||||
decelerationRate={decelerationRate}
|
||||
horizontal={true}
|
||||
maximumZoomScale={3.0}
|
||||
onMomentumScrollEnd={this._onScroll.bind(this)}
|
||||
onScrollEndDrag={this._onScroll.bind(this)}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
@@ -25,7 +18,6 @@
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
@@ -156,15 +148,15 @@ exports.examples = [
|
||||
},
|
||||
{
|
||||
title: 'Plain Static Image',
|
||||
description: 'Static assets should be placed in the source code tree, and ' +
|
||||
'required in the same way as JavaScript modules.',
|
||||
description: 'Static assets should be required by prefixing with `image!` ' +
|
||||
'and are located in the app bundle.',
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.horizontal}>
|
||||
<Image source={require('./uie_thumb_normal.png')} style={styles.icon} />
|
||||
<Image source={require('./uie_thumb_selected.png')} style={styles.icon} />
|
||||
<Image source={require('./uie_comment_normal.png')} style={styles.icon} />
|
||||
<Image source={require('./uie_comment_highlighted.png')} style={styles.icon} />
|
||||
<Image source={require('image!uie_thumb_normal')} style={styles.icon} />
|
||||
<Image source={require('image!uie_thumb_selected')} style={styles.icon} />
|
||||
<Image source={require('image!uie_comment_normal')} style={styles.icon} />
|
||||
<Image source={require('image!uie_comment_highlighted')} style={styles.icon} />
|
||||
</View>
|
||||
);
|
||||
},
|
||||
@@ -195,20 +187,6 @@ exports.examples = [
|
||||
},
|
||||
platform: 'ios',
|
||||
},
|
||||
{
|
||||
title: 'defaultSource',
|
||||
description: 'Show a placeholder image when a network image is loading',
|
||||
render: function() {
|
||||
return (
|
||||
<Image
|
||||
defaultSource={require('./bunny.png')}
|
||||
source={{uri: 'http://facebook.github.io/origami/public/images/birds.jpg'}}
|
||||
style={styles.base}
|
||||
/>
|
||||
);
|
||||
},
|
||||
platform: 'ios',
|
||||
},
|
||||
{
|
||||
title: 'Border Color',
|
||||
render: function() {
|
||||
@@ -342,19 +320,19 @@ exports.examples = [
|
||||
<View>
|
||||
<View style={styles.horizontal}>
|
||||
<Image
|
||||
source={require('./uie_thumb_normal.png')}
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, {borderRadius: 5, tintColor: '#5ac8fa' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('./uie_thumb_normal.png')}
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#4cd964' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('./uie_thumb_normal.png')}
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#ff2d55' }]}
|
||||
/>
|
||||
<Image
|
||||
source={require('./uie_thumb_normal.png')}
|
||||
source={require('image!uie_thumb_normal')}
|
||||
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#8e8e93' }]}
|
||||
/>
|
||||
</View>
|
||||
@@ -389,59 +367,37 @@ exports.examples = [
|
||||
'rendered within the frame.',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
{[smallImage, fullImage].map((image, index) => {
|
||||
return (
|
||||
<View key={index}>
|
||||
<View style={styles.horizontal}>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Contain
|
||||
</Text>
|
||||
<Image
|
||||
style={styles.resizeMode}
|
||||
resizeMode={Image.resizeMode.contain}
|
||||
source={image}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.leftMargin}>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Cover
|
||||
</Text>
|
||||
<Image
|
||||
style={styles.resizeMode}
|
||||
resizeMode={Image.resizeMode.cover}
|
||||
source={image}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.horizontal}>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Stretch
|
||||
</Text>
|
||||
<Image
|
||||
style={styles.resizeMode}
|
||||
resizeMode={Image.resizeMode.stretch}
|
||||
source={image}
|
||||
/>
|
||||
</View>
|
||||
{ Platform.OS === 'android' ?
|
||||
<View style={styles.leftMargin}>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Center
|
||||
</Text>
|
||||
<Image
|
||||
style={styles.resizeMode}
|
||||
resizeMode={Image.resizeMode.center}
|
||||
source={image}
|
||||
/>
|
||||
</View>
|
||||
: null }
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
<View style={styles.horizontal}>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Contain
|
||||
</Text>
|
||||
<Image
|
||||
style={styles.resizeMode}
|
||||
resizeMode={Image.resizeMode.contain}
|
||||
source={fullImage}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.leftMargin}>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Cover
|
||||
</Text>
|
||||
<Image
|
||||
style={styles.resizeMode}
|
||||
resizeMode={Image.resizeMode.cover}
|
||||
source={fullImage}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.leftMargin}>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Stretch
|
||||
</Text>
|
||||
<Image
|
||||
style={styles.resizeMode}
|
||||
resizeMode={Image.resizeMode.stretch}
|
||||
source={fullImage}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
@@ -485,7 +441,7 @@ exports.examples = [
|
||||
{
|
||||
title: 'Image Size',
|
||||
render: function() {
|
||||
return <ImageSizeExample source={fullImage} />;
|
||||
return <ImageSizeExample source={fullImage} />;
|
||||
},
|
||||
platform: 'ios',
|
||||
},
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Linking,
|
||||
IntentAndroid,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableNativeFeedback,
|
||||
@@ -30,9 +30,9 @@ var OpenURLButton = React.createClass({
|
||||
},
|
||||
|
||||
handleClick: function() {
|
||||
Linking.canOpenURL(this.props.url).then(supported => {
|
||||
IntentAndroid.canOpenURL(this.props.url, (supported) => {
|
||||
if (supported) {
|
||||
Linking.openURL(this.props.url);
|
||||
IntentAndroid.openURL(this.props.url);
|
||||
} else {
|
||||
console.log('Don\'t know how to open URI: ' + this.props.url);
|
||||
}
|
||||
@@ -54,8 +54,8 @@ var OpenURLButton = React.createClass({
|
||||
var IntentAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'Linking',
|
||||
description: 'Shows how to use Linking to open URLs.',
|
||||
title: 'IntentAndroid',
|
||||
description: 'Shows how to use Android Intents to open URLs.',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
@@ -64,9 +64,7 @@ var IntentAndroidExample = React.createClass({
|
||||
<OpenURLButton url={'https://www.facebook.com'} />
|
||||
<OpenURLButton url={'http://www.facebook.com'} />
|
||||
<OpenURLButton url={'http://facebook.com'} />
|
||||
<OpenURLButton url={'fb://notifications'} />
|
||||
<OpenURLButton url={'geo:37.484847,-122.148386'} />
|
||||
<OpenURLButton url={'tel:9876543210'} />
|
||||
</UIExplorerBlock>
|
||||
);
|
||||
},
|
||||
@@ -30,7 +30,7 @@ var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var ListViewSimpleExample = React.createClass({
|
||||
statics: {
|
||||
title: '<ListView>',
|
||||
title: '<ListView> - Simple',
|
||||
description: 'Performant, scrollable list of data.'
|
||||
},
|
||||
|
||||
@@ -50,14 +50,13 @@ var ListViewSimpleExample = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage
|
||||
title={this.props.navigator ? null : '<ListView>'}
|
||||
title={this.props.navigator ? null : '<ListView> - Simple'}
|
||||
noSpacer={true}
|
||||
noScroll={true}>
|
||||
<ListView
|
||||
dataSource={this.state.dataSource}
|
||||
renderRow={this._renderRow}
|
||||
renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
|
||||
renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator} />}
|
||||
/>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
@@ -75,6 +74,7 @@ var ListViewSimpleExample = React.createClass({
|
||||
{rowData + ' - ' + LOREM_IPSUM.substr(0, rowHash % 301 + 10)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.separator} />
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
|
||||
@@ -67,9 +67,6 @@ var ListViewGridLayoutExample = React.createClass({
|
||||
<ListView
|
||||
contentContainerStyle={styles.list}
|
||||
dataSource={this.state.dataSource}
|
||||
initialListSize={21}
|
||||
pageSize={3} // should be a multiple of the no. of visible cells per row
|
||||
scrollRenderAheadDistance={500}
|
||||
renderRow={this._renderRow}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -32,6 +32,7 @@ var {
|
||||
UIManager,
|
||||
} = NativeModules;
|
||||
|
||||
var PAGE_SIZE = 4;
|
||||
var THUMB_URLS = [
|
||||
require('./Thumbnails/like.png'),
|
||||
require('./Thumbnails/dislike.png'),
|
||||
@@ -181,8 +182,8 @@ var ListViewPagingExample = React.createClass({
|
||||
renderSectionHeader={this.renderSectionHeader}
|
||||
renderRow={this.renderRow}
|
||||
initialListSize={10}
|
||||
pageSize={4}
|
||||
scrollRenderAheadDistance={500}
|
||||
pageSize={PAGE_SIZE}
|
||||
scrollRenderAheadDistance={2000}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -313,27 +313,13 @@ exports.examples = [
|
||||
}}>
|
||||
<Image
|
||||
style={{width:30, height:30}}
|
||||
source={require('./uie_thumb_selected.png')}
|
||||
source={require('image!uie_thumb_selected')}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
),
|
||||
}}/>;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Annotation focus example',
|
||||
render() {
|
||||
return <AnnotationExample style={styles.map} annotation={{
|
||||
title: 'More Info...',
|
||||
onFocus: () => {
|
||||
alert('Annotation gets focus');
|
||||
},
|
||||
onBlur: () => {
|
||||
alert('Annotation lost focus');
|
||||
}
|
||||
}}/>;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Draggable pin',
|
||||
render() {
|
||||
|
||||
@@ -19,7 +19,7 @@ var React = require('react-native');
|
||||
var {
|
||||
Modal,
|
||||
StyleSheet,
|
||||
Switch,
|
||||
SwitchIOS,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
@@ -96,9 +96,7 @@ var ModalExample = React.createClass({
|
||||
<Modal
|
||||
animated={this.state.animated}
|
||||
transparent={this.state.transparent}
|
||||
visible={this.state.modalVisible}
|
||||
onRequestClose={() => {this._setModalVisible(false)}}
|
||||
>
|
||||
visible={this.state.modalVisible}>
|
||||
<View style={[styles.container, modalBackgroundStyle]}>
|
||||
<View style={[styles.innerContainer, innerContainerTransparentStyle]}>
|
||||
<Text>This modal was presented {this.state.animated ? 'with' : 'without'} animation.</Text>
|
||||
@@ -113,12 +111,12 @@ var ModalExample = React.createClass({
|
||||
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowTitle}>Animated</Text>
|
||||
<Switch value={this.state.animated} onValueChange={this._toggleAnimated} />
|
||||
<SwitchIOS value={this.state.animated} onValueChange={this._toggleAnimated} />
|
||||
</View>
|
||||
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowTitle}>Transparent</Text>
|
||||
<Switch value={this.state.transparent} onValueChange={this._toggleTransparent} />
|
||||
<SwitchIOS value={this.state.transparent} onValueChange={this._toggleTransparent} />
|
||||
</View>
|
||||
|
||||
<Button onPress={this._setModalVisible.bind(this, true)}>
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableOpacity
|
||||
} = React;
|
||||
|
||||
var _getRandomRoute = function() {
|
||||
return {
|
||||
title: '#' + Math.ceil(Math.random() * 1000),
|
||||
};
|
||||
};
|
||||
|
||||
var Navigator = NavigationExperimental.LegacyNavigator;
|
||||
|
||||
class NavButton extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
style={styles.button}
|
||||
underlayColor="#B5B5B5"
|
||||
onPress={this.props.onPress}>
|
||||
<Text style={styles.buttonText}>{this.props.text}</Text>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var BreadcrumbNavSample = React.createClass({
|
||||
|
||||
componentWillMount: function() {
|
||||
this._navBarRouteMapper = {
|
||||
rightContentForRoute: function(route, navigator) {
|
||||
return null;
|
||||
},
|
||||
titleContentForRoute: function(route, navigator) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigator.push(_getRandomRoute())}>
|
||||
<Text style={styles.titleText}>{route.title}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
iconForRoute: function(route, navigator) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => { navigator.popToRoute(route); }}
|
||||
style={styles.crumbIconPlaceholder}
|
||||
/>
|
||||
);
|
||||
},
|
||||
separatorForRoute: function(route, navigator) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={navigator.pop}
|
||||
style={styles.crumbSeparatorPlaceholder}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
_renderScene: function(route, navigator) {
|
||||
return (
|
||||
<ScrollView style={styles.scene}>
|
||||
<NavButton
|
||||
onPress={() => { navigator.push(_getRandomRoute()); }}
|
||||
text="Push"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => { navigator.immediatelyResetRouteStack([_getRandomRoute(), _getRandomRoute()]); }}
|
||||
text="Reset w/ 2 scenes"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => { navigator.popToTop(); }}
|
||||
text="Pop to top"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => { navigator.replace(_getRandomRoute()); }}
|
||||
text="Replace"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => { this.props.navigator.pop(); }}
|
||||
text="Close breadcrumb example"
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<Navigator
|
||||
style={styles.container}
|
||||
initialRoute={_getRandomRoute()}
|
||||
renderScene={this._renderScene}
|
||||
navigationBar={
|
||||
<Navigator.BreadcrumbNavigationBar
|
||||
routeMapper={this._navBarRouteMapper}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
scene: {
|
||||
paddingTop: 50,
|
||||
flex: 1,
|
||||
},
|
||||
button: {
|
||||
backgroundColor: 'white',
|
||||
padding: 15,
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
borderBottomColor: '#CDCDCD',
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
container: {
|
||||
overflow: 'hidden',
|
||||
backgroundColor: '#dddddd',
|
||||
flex: 1,
|
||||
},
|
||||
titleText: {
|
||||
fontSize: 18,
|
||||
color: '#666666',
|
||||
textAlign: 'center',
|
||||
fontWeight: 'bold',
|
||||
lineHeight: 32,
|
||||
},
|
||||
crumbIconPlaceholder: {
|
||||
flex: 1,
|
||||
backgroundColor: '#666666',
|
||||
},
|
||||
crumbSeparatorPlaceholder: {
|
||||
flex: 1,
|
||||
backgroundColor: '#aaaaaa',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = BreadcrumbNavSample;
|
||||
@@ -1,218 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
TabBarIOS,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var _getRandomRoute = function() {
|
||||
return {
|
||||
randNumber: Math.ceil(Math.random() * 1000),
|
||||
};
|
||||
};
|
||||
|
||||
var Navigator = NavigationExperimental.LegacyNavigator;
|
||||
|
||||
class NavButton extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
style={styles.button}
|
||||
underlayColor="#B5B5B5"
|
||||
onPress={this.props.onPress}>
|
||||
<Text style={styles.buttonText}>{this.props.text}</Text>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var ROUTE_STACK = [
|
||||
_getRandomRoute(),
|
||||
_getRandomRoute(),
|
||||
_getRandomRoute(),
|
||||
];
|
||||
var INIT_ROUTE_INDEX = 1;
|
||||
|
||||
class JumpingNavBar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
tabIndex: props.initTabIndex,
|
||||
};
|
||||
}
|
||||
handleWillFocus(route) {
|
||||
var tabIndex = ROUTE_STACK.indexOf(route);
|
||||
this.setState({ tabIndex, });
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.tabs}>
|
||||
<TabBarIOS>
|
||||
<TabBarIOS.Item
|
||||
icon={require('image!tabnav_notification')}
|
||||
selected={this.state.tabIndex === 0}
|
||||
onPress={() => {
|
||||
this.props.onTabIndex(0);
|
||||
this.setState({ tabIndex: 0, });
|
||||
}}>
|
||||
<View />
|
||||
</TabBarIOS.Item>
|
||||
<TabBarIOS.Item
|
||||
icon={require('image!tabnav_list')}
|
||||
selected={this.state.tabIndex === 1}
|
||||
onPress={() => {
|
||||
this.props.onTabIndex(1);
|
||||
this.setState({ tabIndex: 1, });
|
||||
}}>
|
||||
<View />
|
||||
</TabBarIOS.Item>
|
||||
<TabBarIOS.Item
|
||||
icon={require('image!tabnav_settings')}
|
||||
selected={this.state.tabIndex === 2}
|
||||
onPress={() => {
|
||||
this.props.onTabIndex(2);
|
||||
this.setState({ tabIndex: 2, });
|
||||
}}>
|
||||
<View />
|
||||
</TabBarIOS.Item>
|
||||
</TabBarIOS>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var JumpingNavSample = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<Navigator
|
||||
debugOverlay={false}
|
||||
style={styles.appContainer}
|
||||
ref={(navigator) => {
|
||||
this._navigator = navigator;
|
||||
}}
|
||||
initialRoute={ROUTE_STACK[INIT_ROUTE_INDEX]}
|
||||
initialRouteStack={ROUTE_STACK}
|
||||
renderScene={this.renderScene}
|
||||
configureScene={() => ({
|
||||
...Navigator.SceneConfigs.HorizontalSwipeJump,
|
||||
})}
|
||||
navigationBar={
|
||||
<JumpingNavBar
|
||||
ref={(navBar) => { this.navBar = navBar; }}
|
||||
initTabIndex={INIT_ROUTE_INDEX}
|
||||
routeStack={ROUTE_STACK}
|
||||
onTabIndex={(index) => {
|
||||
this._navigator.jumpTo(ROUTE_STACK[index]);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
renderScene: function(route, navigator) {
|
||||
var backBtn;
|
||||
var forwardBtn;
|
||||
if (ROUTE_STACK.indexOf(route) !== 0) {
|
||||
backBtn = (
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
navigator.jumpBack();
|
||||
}}
|
||||
text="jumpBack"
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (ROUTE_STACK.indexOf(route) !== ROUTE_STACK.length - 1) {
|
||||
forwardBtn = (
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
navigator.jumpForward();
|
||||
}}
|
||||
text="jumpForward"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ScrollView style={styles.scene}>
|
||||
<Text style={styles.messageText}>#{route.randNumber}</Text>
|
||||
{backBtn}
|
||||
{forwardBtn}
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
navigator.jumpTo(ROUTE_STACK[1]);
|
||||
}}
|
||||
text="jumpTo middle route"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.pop();
|
||||
}}
|
||||
text="Exit Navigation Example"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.push({
|
||||
message: 'Came from jumping example',
|
||||
});
|
||||
}}
|
||||
text="Nav Menu"
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
button: {
|
||||
backgroundColor: 'white',
|
||||
padding: 15,
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
borderBottomColor: '#CDCDCD',
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
appContainer: {
|
||||
overflow: 'hidden',
|
||||
backgroundColor: '#dddddd',
|
||||
flex: 1,
|
||||
},
|
||||
messageText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
padding: 15,
|
||||
marginTop: 50,
|
||||
marginLeft: 15,
|
||||
},
|
||||
scene: {
|
||||
flex: 1,
|
||||
paddingTop: 20,
|
||||
backgroundColor: '#EAEAEA',
|
||||
},
|
||||
tabs: {
|
||||
height: 50,
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = JumpingNavSample;
|
||||
@@ -1,219 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
} = React;
|
||||
|
||||
var BreadcrumbNavSample = require('./BreadcrumbNavSample');
|
||||
var NavigationBarSample = require('./NavigationBarSample');
|
||||
var JumpingNavSample = require('./JumpingNavSample');
|
||||
|
||||
var Navigator = NavigationExperimental.LegacyNavigator;
|
||||
|
||||
class NavButton extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
style={styles.button}
|
||||
underlayColor="#B5B5B5"
|
||||
onPress={this.props.onPress}>
|
||||
<Text style={styles.buttonText}>{this.props.text}</Text>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NavMenu extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ScrollView style={styles.scene}>
|
||||
<Text style={styles.messageText}>{this.props.message}</Text>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.push({
|
||||
message: 'Swipe right to dismiss',
|
||||
sceneConfig: Navigator.SceneConfigs.FloatFromRight,
|
||||
});
|
||||
}}
|
||||
text="Float in from right"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.push({
|
||||
message: 'Swipe down to dismiss',
|
||||
sceneConfig: Navigator.SceneConfigs.FloatFromBottom,
|
||||
});
|
||||
}}
|
||||
text="Float in from bottom"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.pop();
|
||||
}}
|
||||
text="Pop"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.popToTop();
|
||||
}}
|
||||
text="Pop to top"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.push({ id: 'navbar' });
|
||||
}}
|
||||
text="Navbar Example"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.push({ id: 'jumping' });
|
||||
}}
|
||||
text="Jumping Example"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.push({ id: 'breadcrumbs' });
|
||||
}}
|
||||
text="Breadcrumbs Example"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.onExampleExit();
|
||||
}}
|
||||
text="Exit <LegacyNavigator> Example"
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var TabBarExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: '<LegacyNavigator> (Experimental)',
|
||||
description: 'Experimental navigator that ports the API of the current ' +
|
||||
'Navigator component',
|
||||
},
|
||||
|
||||
renderScene: function(route, nav) {
|
||||
switch (route.id) {
|
||||
case 'navbar':
|
||||
return <NavigationBarSample navigator={nav} />;
|
||||
case 'breadcrumbs':
|
||||
return <BreadcrumbNavSample navigator={nav} />;
|
||||
case 'jumping':
|
||||
return <JumpingNavSample navigator={nav} />;
|
||||
default:
|
||||
return (
|
||||
<NavMenu
|
||||
message={route.message}
|
||||
navigator={nav}
|
||||
onExampleExit={this.props.onExampleExit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<Navigator
|
||||
ref={this._setNavigatorRef}
|
||||
style={styles.container}
|
||||
initialRoute={{ message: 'First Scene', }}
|
||||
renderScene={this.renderScene}
|
||||
configureScene={(route) => {
|
||||
if (route.sceneConfig) {
|
||||
return route.sceneConfig;
|
||||
}
|
||||
return Navigator.SceneConfigs.FloatFromBottom;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._listeners && this._listeners.forEach(listener => listener.remove());
|
||||
},
|
||||
|
||||
_setNavigatorRef: function(navigator) {
|
||||
if (navigator !== this._navigator) {
|
||||
this._navigator = navigator;
|
||||
|
||||
if (navigator) {
|
||||
var callback = (event) => {
|
||||
console.log(
|
||||
`LegacyNavigator: event ${event.type}`,
|
||||
{
|
||||
route: JSON.stringify(event.data.route),
|
||||
target: event.target,
|
||||
type: event.type,
|
||||
}
|
||||
);
|
||||
};
|
||||
// Observe focus change events from the owner.
|
||||
this._listeners = [
|
||||
navigator.navigationContext.addListener('willfocus', callback),
|
||||
navigator.navigationContext.addListener('didfocus', callback),
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
messageText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
padding: 15,
|
||||
marginTop: 50,
|
||||
marginLeft: 15,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
button: {
|
||||
backgroundColor: 'white',
|
||||
padding: 15,
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
borderBottomColor: '#CDCDCD',
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
scene: {
|
||||
flex: 1,
|
||||
paddingTop: 20,
|
||||
backgroundColor: '#ccc',
|
||||
}
|
||||
});
|
||||
|
||||
TabBarExample.external = true;
|
||||
|
||||
module.exports = TabBarExample;
|
||||
@@ -1,201 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableOpacity,
|
||||
} = React;
|
||||
|
||||
var Navigator = NavigationExperimental.LegacyNavigator;
|
||||
|
||||
class NavButton extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
style={styles.button}
|
||||
underlayColor="#B5B5B5"
|
||||
onPress={this.props.onPress}>
|
||||
<Text style={styles.buttonText}>{this.props.text}</Text>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var NavigationBarRouteMapper = {
|
||||
|
||||
LeftButton: function(route, navigator, index, navState) {
|
||||
if (index === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var previousRoute = navState.routeStack[index - 1];
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigator.pop()}
|
||||
style={styles.navBarLeftButton}>
|
||||
<Text style={[styles.navBarText, styles.navBarButtonText]}>
|
||||
{previousRoute.title}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
|
||||
RightButton: function(route, navigator, index, navState) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigator.push(newRandomRoute())}
|
||||
style={styles.navBarRightButton}>
|
||||
<Text style={[styles.navBarText, styles.navBarButtonText]}>
|
||||
Next
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
|
||||
Title: function(route, navigator, index, navState) {
|
||||
return (
|
||||
<Text style={[styles.navBarText, styles.navBarTitleText]}>
|
||||
{route.title} [{index}]
|
||||
</Text>
|
||||
);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
function newRandomRoute() {
|
||||
return {
|
||||
title: '#' + Math.ceil(Math.random() * 1000),
|
||||
};
|
||||
}
|
||||
|
||||
var NavigationBarSample = React.createClass({
|
||||
|
||||
componentWillMount: function() {
|
||||
var navigator = this.props.navigator;
|
||||
|
||||
var callback = (event) => {
|
||||
console.log(
|
||||
`NavigationBarSample : event ${event.type}`,
|
||||
{
|
||||
route: JSON.stringify(event.data.route),
|
||||
target: event.target,
|
||||
type: event.type,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Observe focus change events from this component.
|
||||
this._listeners = [
|
||||
navigator.navigationContext.addListener('willfocus', callback),
|
||||
navigator.navigationContext.addListener('didfocus', callback),
|
||||
];
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._listeners && this._listeners.forEach(listener => listener.remove());
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<Navigator
|
||||
debugOverlay={false}
|
||||
style={styles.appContainer}
|
||||
initialRoute={newRandomRoute()}
|
||||
renderScene={(route, navigator) => (
|
||||
<ScrollView style={styles.scene}>
|
||||
<Text style={styles.messageText}>{route.content}</Text>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
navigator.immediatelyResetRouteStack([
|
||||
newRandomRoute(),
|
||||
newRandomRoute(),
|
||||
newRandomRoute(),
|
||||
]);
|
||||
}}
|
||||
text="Reset w/ 3 scenes"
|
||||
/>
|
||||
<NavButton
|
||||
onPress={() => {
|
||||
this.props.navigator.pop();
|
||||
}}
|
||||
text="Exit NavigationBar Example"
|
||||
/>
|
||||
</ScrollView>
|
||||
)}
|
||||
navigationBar={
|
||||
<Navigator.NavigationBar
|
||||
routeMapper={NavigationBarRouteMapper}
|
||||
style={styles.navBar}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
messageText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
padding: 15,
|
||||
marginTop: 50,
|
||||
marginLeft: 15,
|
||||
},
|
||||
button: {
|
||||
backgroundColor: 'white',
|
||||
padding: 15,
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
borderBottomColor: '#CDCDCD',
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
navBar: {
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
navBarText: {
|
||||
fontSize: 16,
|
||||
marginVertical: 10,
|
||||
},
|
||||
navBarTitleText: {
|
||||
color: '#373E4D',
|
||||
fontWeight: '500',
|
||||
marginVertical: 9,
|
||||
},
|
||||
navBarLeftButton: {
|
||||
paddingLeft: 10,
|
||||
},
|
||||
navBarRightButton: {
|
||||
paddingRight: 10,
|
||||
},
|
||||
navBarButtonText: {
|
||||
color: '#5890FF',
|
||||
},
|
||||
scene: {
|
||||
flex: 1,
|
||||
paddingTop: 20,
|
||||
backgroundColor: '#EAEAEA',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationBarSample;
|
||||
@@ -1,160 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
|
||||
const {
|
||||
Animated,
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
} = React;
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
|
||||
const {
|
||||
AnimatedView: NavigationAnimatedView,
|
||||
Card: NavigationCard,
|
||||
Header: NavigationHeader,
|
||||
Reducer: NavigationReducer,
|
||||
RootContainer: NavigationRootContainer,
|
||||
} = NavigationExperimental;
|
||||
|
||||
const NavigationBasicReducer = NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (action.type === 'push') {
|
||||
return (state) => state || {key: action.key};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getReducerForState: (initialState) => (state) => state || initialState,
|
||||
initialState: {
|
||||
key: 'AnimatedExampleStackKey',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'First Route'},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
class NavigationAnimatedExample extends React.Component {
|
||||
componentWillMount() {
|
||||
this._renderCard = this._renderCard.bind(this);
|
||||
this._renderHeader = this._renderHeader.bind(this);
|
||||
this._renderNavigation = this._renderNavigation.bind(this);
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
this._renderTitleComponent = this._renderTitleComponent.bind(this);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
reducer={NavigationBasicReducer}
|
||||
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
|
||||
persistenceKey="NavigationAnimExampleState"
|
||||
renderNavigation={this._renderNavigation}
|
||||
/>
|
||||
);
|
||||
}
|
||||
handleBackAction() {
|
||||
return (
|
||||
this.navRootContainer &&
|
||||
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
|
||||
);
|
||||
}
|
||||
_renderNavigation(navigationState, onNavigate) {
|
||||
if (!navigationState) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<NavigationAnimatedView
|
||||
navigationState={navigationState}
|
||||
style={styles.animatedView}
|
||||
renderOverlay={this._renderHeader}
|
||||
applyAnimation={(pos, navState) => {
|
||||
Animated.timing(pos, {toValue: navState.index, duration: 500}).start();
|
||||
}}
|
||||
renderScene={this._renderCard}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderHeader(/*NavigationSceneRendererProps*/ props) {
|
||||
return (
|
||||
<NavigationHeader
|
||||
{...props}
|
||||
renderTitleComponent={this._renderTitleComponent}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderTitleComponent(/*NavigationSceneRendererProps*/ props) {
|
||||
return (
|
||||
<NavigationHeader.Title>
|
||||
{props.scene.navigationState.key}
|
||||
</NavigationHeader.Title>
|
||||
);
|
||||
}
|
||||
|
||||
_renderCard(/*NavigationSceneRendererProps*/ props) {
|
||||
return (
|
||||
<NavigationCard
|
||||
{...props}
|
||||
key={'card_' + props.scene.navigationState.key}
|
||||
renderScene={this._renderScene}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderScene(/*NavigationSceneRendererProps*/ props) {
|
||||
return (
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<NavigationExampleRow
|
||||
text={props.scene.navigationState.key}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Push!"
|
||||
onPress={() => {
|
||||
props.onNavigate({
|
||||
type: 'push',
|
||||
key: 'Route #' + props.scenes.length,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit Animated Nav Example"
|
||||
onPress={this.props.onExampleExit}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
animatedView: {
|
||||
flex: 1,
|
||||
},
|
||||
scrollView: {
|
||||
marginTop: NavigationHeader.HEIGHT,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationAnimatedExample;
|
||||
@@ -1,100 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
} = React;
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const {
|
||||
RootContainer: NavigationRootContainer,
|
||||
Reducer: NavigationReducer,
|
||||
} = NavigationExperimental;
|
||||
const StackReducer = NavigationReducer.StackReducer;
|
||||
|
||||
const NavigationBasicReducer = NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (action.type === 'push') {
|
||||
return (state) => state || {key: action.key};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getReducerForState: (initialState) => (state) => state || initialState,
|
||||
initialState: {
|
||||
key: 'BasicExampleStackKey',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'First Route'},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const NavigationBasicExample = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
reducer={NavigationBasicReducer}
|
||||
persistenceKey="NavigationBasicExampleState"
|
||||
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
|
||||
renderNavigation={(navState, onNavigate) => {
|
||||
if (!navState) { return null; }
|
||||
return (
|
||||
<ScrollView style={styles.topView}>
|
||||
<NavigationExampleRow
|
||||
text={`Current page: ${navState.children[navState.index].key}`}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text={`Push page #${navState.children.length}`}
|
||||
onPress={() => {
|
||||
onNavigate({ type: 'push', key: 'page #' + navState.children.length });
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="pop"
|
||||
onPress={() => {
|
||||
onNavigate(NavigationRootContainer.getBackAction());
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit Basic Nav Example"
|
||||
onPress={this.props.onExampleExit}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
handleBackAction: function() {
|
||||
return (
|
||||
this.navRootContainer &&
|
||||
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
|
||||
);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
topView: {
|
||||
backgroundColor: '#E9E9EF',
|
||||
flex: 1,
|
||||
paddingTop: 30,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationBasicExample;
|
||||
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const React = require('react-native');
|
||||
|
||||
const {
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
} = React;
|
||||
|
||||
const {
|
||||
CardStack: NavigationCardStack,
|
||||
StateUtils: NavigationStateUtils,
|
||||
RootContainer: NavigationRootContainer,
|
||||
} = NavigationExperimental;
|
||||
|
||||
function createReducer(initialState) {
|
||||
return (currentState, action) => {
|
||||
switch (action.type) {
|
||||
case 'RootContainerInitialAction':
|
||||
return initialState;
|
||||
|
||||
case 'push':
|
||||
return NavigationStateUtils.push(currentState, {key: action.key});
|
||||
|
||||
case 'back':
|
||||
case 'pop':
|
||||
return currentState.index > 0 ?
|
||||
NavigationStateUtils.pop(currentState) :
|
||||
currentState;
|
||||
|
||||
default:
|
||||
return currentState;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const ExampleReducer = createReducer({
|
||||
index: 0,
|
||||
key: 'exmaple',
|
||||
children: [{key: 'First Route'}],
|
||||
});
|
||||
|
||||
class NavigationCardStackExample extends React.Component {
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.state = {isHorizontal: true};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this._renderNavigation = this._renderNavigation.bind(this);
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
this._toggleDirection = this._toggleDirection.bind(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
reducer={ExampleReducer}
|
||||
renderNavigation={this._renderNavigation}
|
||||
style={styles.main}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderNavigation(navigationState, onNavigate) {
|
||||
return (
|
||||
<NavigationCardStack
|
||||
direction={this.state.isHorizontal ? 'horizontal' : 'vertical'}
|
||||
navigationState={navigationState}
|
||||
onNavigate={onNavigate}
|
||||
renderScene={this._renderScene}
|
||||
style={styles.main}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderScene(/*NavigationSceneRendererProps*/ props) {
|
||||
return (
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<NavigationExampleRow
|
||||
text={
|
||||
this.state.isHorizontal ?
|
||||
'direction = "horizontal"' :
|
||||
'direction = "vertical"'
|
||||
}
|
||||
onPress={this._toggleDirection}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text={'route = ' + props.scene.navigationState.key}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Push Route"
|
||||
onPress={() => {
|
||||
props.onNavigate({
|
||||
type: 'push',
|
||||
key: 'Route ' + props.scenes.length,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Pop Route"
|
||||
onPress={() => {
|
||||
props.onNavigate({
|
||||
type: 'pop',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit Card Stack Example"
|
||||
onPress={this.props.onExampleExit}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
_toggleDirection() {
|
||||
this.setState({
|
||||
isHorizontal: !this.state.isHorizontal,
|
||||
});
|
||||
}
|
||||
|
||||
_onNavigate(action) {
|
||||
if (action && action.type === 'back') {
|
||||
this._pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
main: {
|
||||
flex: 1,
|
||||
},
|
||||
scrollView: {
|
||||
marginTop: 64
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationCardStackExample;
|
||||
@@ -1,321 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const NavigationExampleTabBar = require('./NavigationExampleTabBar');
|
||||
|
||||
const {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
const {
|
||||
CardStack: NavigationCardStack,
|
||||
Container: NavigationContainer,
|
||||
Header: NavigationHeader,
|
||||
Reducer: NavigationReducer,
|
||||
RootContainer: NavigationRootContainer,
|
||||
View: NavigationView,
|
||||
} = NavigationExperimental;
|
||||
|
||||
|
||||
import type {
|
||||
NavigationParentState,
|
||||
NavigationSceneRenderer,
|
||||
NavigationSceneRendererProps,
|
||||
} from 'NavigationTypeDefinition';
|
||||
|
||||
type Action = {
|
||||
isExitAction?: boolean,
|
||||
};
|
||||
|
||||
const ExampleExitAction = () => ({
|
||||
isExitAction: true,
|
||||
});
|
||||
|
||||
ExampleExitAction.match = (action: Action) => (
|
||||
action && action.isExitAction === true
|
||||
);
|
||||
|
||||
const PageAction = (type) => ({
|
||||
type,
|
||||
isPageAction: true,
|
||||
});
|
||||
|
||||
PageAction.match = (action) => (
|
||||
action && action.isPageAction === true
|
||||
);
|
||||
|
||||
const ExampleProfilePageAction = (type) => ({
|
||||
...PageAction(type),
|
||||
isProfilePageAction: true,
|
||||
});
|
||||
|
||||
ExampleProfilePageAction.match = (action) => (
|
||||
action && action.isProfilePageAction === true
|
||||
);
|
||||
|
||||
const ExampleInfoAction = () => PageAction('InfoPage');
|
||||
|
||||
const ExampleNotifProfileAction = () => ExampleProfilePageAction('NotifProfilePage');
|
||||
|
||||
const _jsInstanceUniqueId = '' + Date.now();
|
||||
|
||||
let _uniqueIdCount = 0;
|
||||
|
||||
function pageStateActionMap(action) {
|
||||
return {
|
||||
key: 'page-' + _jsInstanceUniqueId + '-' + (_uniqueIdCount++),
|
||||
type: action.type,
|
||||
};
|
||||
}
|
||||
|
||||
const ExampleAppReducer = NavigationReducer.TabsReducer({
|
||||
key: 'AppNavigationState',
|
||||
initialIndex: 0,
|
||||
tabReducers: [
|
||||
NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (PageAction.match(action) && !ExampleProfilePageAction.match(action)) {
|
||||
return (state) => (state || pageStateActionMap(action));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
initialState: {
|
||||
key: 'notifs',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'base', type: 'NotifsPage'},
|
||||
],
|
||||
},
|
||||
}),
|
||||
NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (PageAction.match(action) && !ExampleProfilePageAction.match(action)) {
|
||||
return (state) => (state || pageStateActionMap(action));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
initialState: {
|
||||
key: 'settings',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'base', type: 'SettingsPage'},
|
||||
],
|
||||
},
|
||||
}),
|
||||
NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (PageAction.match(action) || ExampleProfilePageAction.match(action)) {
|
||||
return (state) => (state || pageStateActionMap(action));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
initialState: {
|
||||
key: 'profile',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'base', type: 'ProfilePage'},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
function stateTypeTitleMap(pageState: any) {
|
||||
switch (pageState.type) {
|
||||
case 'ProfilePage':
|
||||
return 'Profile Page';
|
||||
case 'NotifsPage':
|
||||
return 'Notifications';
|
||||
case 'SettingsPage':
|
||||
return 'Settings';
|
||||
case 'InfoPage':
|
||||
return 'Info Page';
|
||||
case 'NotifProfilePage':
|
||||
return 'Page in Profile';
|
||||
}
|
||||
}
|
||||
|
||||
class ExampleTabScreen extends React.Component {
|
||||
_renderCard: NavigationSceneRenderer;
|
||||
_renderHeader: NavigationSceneRenderer;
|
||||
_renderScene: NavigationSceneRenderer;
|
||||
|
||||
componentWillMount() {
|
||||
this._renderHeader = this._renderHeader.bind(this);
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<NavigationCardStack
|
||||
style={styles.tabContent}
|
||||
navigationState={this.props.navigationState}
|
||||
renderOverlay={this._renderHeader}
|
||||
renderScene={this._renderScene}
|
||||
/>
|
||||
);
|
||||
}
|
||||
_renderHeader(props: NavigationSceneRendererProps) {
|
||||
return (
|
||||
<NavigationHeader
|
||||
{...props}
|
||||
renderTitleComponent={this._renderTitleComponent}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderTitleComponent(props: NavigationSceneRendererProps) {
|
||||
return (
|
||||
<NavigationHeader.Title>
|
||||
{stateTypeTitleMap(props.scene.navigationState)}
|
||||
</NavigationHeader.Title>
|
||||
);
|
||||
}
|
||||
|
||||
_renderScene(props: NavigationSceneRendererProps) {
|
||||
const {onNavigate} = props;
|
||||
return (
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<NavigationExampleRow
|
||||
text="Open page"
|
||||
onPress={() => {
|
||||
onNavigate(ExampleInfoAction());
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Open a page in the profile tab"
|
||||
onPress={() => {
|
||||
onNavigate(ExampleNotifProfileAction());
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit Composition Example"
|
||||
onPress={() => {
|
||||
onNavigate(ExampleExitAction());
|
||||
}}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
ExampleTabScreen = NavigationContainer.create(ExampleTabScreen);
|
||||
|
||||
class NavigationCompositionExample extends React.Component {
|
||||
navRootContainer: NavigationRootContainer;
|
||||
|
||||
render() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
reducer={ExampleAppReducer}
|
||||
persistenceKey="NavigationCompositionState"
|
||||
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
|
||||
renderNavigation={this.renderApp.bind(this)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
handleBackAction(): boolean {
|
||||
return (
|
||||
this.navRootContainer &&
|
||||
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
|
||||
);
|
||||
}
|
||||
renderApp(navigationState: NavigationParentState, onNavigate: Function) {
|
||||
if (!navigationState) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<View style={styles.topView}>
|
||||
<ExampleMainView
|
||||
navigationState={navigationState}
|
||||
onExampleExit={this.props.onExampleExit}
|
||||
/>
|
||||
<NavigationExampleTabBar
|
||||
tabs={navigationState.children}
|
||||
index={navigationState.index}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ExampleMainView extends React.Component {
|
||||
_renderScene: NavigationSceneRenderer;
|
||||
|
||||
componentWillMount() {
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<NavigationView
|
||||
navigationState={this.props.navigationState}
|
||||
style={styles.tabsContent}
|
||||
renderScene={this._renderScene}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderScene(props: NavigationSceneRendererProps): ReactElement {
|
||||
const {scene} = props;
|
||||
return (
|
||||
<ExampleTabScreen
|
||||
key={'tab_screen' + scene.key}
|
||||
navigationState={scene.navigationState}
|
||||
onNavigate={this._handleNavigation.bind(this, scene.key)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_handleNavigation(tabKey, action) {
|
||||
if (ExampleExitAction.match(action)) {
|
||||
this.props.onExampleExit();
|
||||
return;
|
||||
}
|
||||
this.props.onNavigate(action);
|
||||
}
|
||||
}
|
||||
|
||||
ExampleMainView = NavigationContainer.create(ExampleMainView);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
topView: {
|
||||
flex: 1,
|
||||
},
|
||||
tabsContent: {
|
||||
flex: 1,
|
||||
},
|
||||
scrollView: {
|
||||
marginTop: NavigationHeader.HEIGHT
|
||||
},
|
||||
tabContent: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationCompositionExample;
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Text,
|
||||
PixelRatio,
|
||||
StyleSheet,
|
||||
View,
|
||||
TouchableHighlight,
|
||||
} = React;
|
||||
|
||||
var NavigationExampleRow = React.createClass({
|
||||
render: function() {
|
||||
if (this.props.onPress) {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
style={styles.row}
|
||||
underlayColor="#D0D0D0"
|
||||
onPress={this.props.onPress}>
|
||||
<Text style={styles.buttonText}>
|
||||
{this.props.text}
|
||||
</Text>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowText}>
|
||||
{this.props.text}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
padding: 15,
|
||||
backgroundColor: 'white',
|
||||
borderBottomWidth: 1 / PixelRatio.get(),
|
||||
borderBottomColor: '#CDCDCD',
|
||||
},
|
||||
rowText: {
|
||||
fontSize: 17,
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationExampleRow;
|
||||
@@ -1,81 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} = React;
|
||||
const {
|
||||
Container: NavigationContainer,
|
||||
Reducer: NavigationReducer,
|
||||
} = NavigationExperimental;
|
||||
const {
|
||||
JumpToAction,
|
||||
} = NavigationReducer.TabsReducer;
|
||||
|
||||
var NavigationExampleTabBar = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.tabBar}>
|
||||
{this.props.tabs.map(this._renderTab)}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
_renderTab: function(tab, index) {
|
||||
var textStyle = [styles.tabButtonText];
|
||||
if (this.props.index === index) {
|
||||
textStyle.push(styles.selectedTabButtonText);
|
||||
}
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.tabButton}
|
||||
key={tab.key}
|
||||
onPress={() => {
|
||||
this.props.onNavigate(JumpToAction(index));
|
||||
}}>
|
||||
<Text style={textStyle}>
|
||||
{tab.key}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
NavigationExampleTabBar = NavigationContainer.create(NavigationExampleTabBar);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
tabBar: {
|
||||
height: 50,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
tabButton: {
|
||||
flex: 1,
|
||||
},
|
||||
tabButtonText: {
|
||||
paddingTop: 20,
|
||||
textAlign: 'center',
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
selectedTabButtonText: {
|
||||
color: 'blue',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationExampleTabBar;
|
||||
@@ -1,152 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AsyncStorage,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
var NavigationExampleRow = require('./NavigationExampleRow');
|
||||
|
||||
/*
|
||||
* Heads up! This file is not the real navigation example- only a utility to switch between them.
|
||||
*
|
||||
* To learn how to use the Navigation API, take a look at the following example files:
|
||||
*/
|
||||
var EXAMPLES = {
|
||||
'Tabs': require('./NavigationTabsExample'),
|
||||
'Basic': require('./NavigationBasicExample'),
|
||||
'Animated Example': require('./NavigationAnimatedExample'),
|
||||
'Composition': require('./NavigationCompositionExample'),
|
||||
'Card Stack Example': require('./NavigationCardStackExample'),
|
||||
'Tic Tac Toe': require('./NavigationTicTacToeExample'),
|
||||
};
|
||||
|
||||
var EXAMPLE_STORAGE_KEY = 'NavigationExperimentalExample';
|
||||
|
||||
var NavigationExperimentalExample = React.createClass({
|
||||
statics: {
|
||||
title: 'Navigation (Experimental)',
|
||||
description: 'Upcoming navigation APIs and animated navigation views',
|
||||
external: true,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
example: null,
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem(EXAMPLE_STORAGE_KEY, (err, example) => {
|
||||
if (err || !example || !EXAMPLES[example]) {
|
||||
this.setState({
|
||||
example: 'menu',
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
example,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setExample: function(example) {
|
||||
this.setState({
|
||||
example,
|
||||
});
|
||||
AsyncStorage.setItem(EXAMPLE_STORAGE_KEY, example);
|
||||
},
|
||||
|
||||
_renderMenu: function() {
|
||||
var exitRow = null;
|
||||
if (this.props.onExampleExit) {
|
||||
exitRow = (
|
||||
<NavigationExampleRow
|
||||
text="Exit Navigation Examples"
|
||||
onPress={this.props.onExampleExit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={styles.menu}>
|
||||
<ScrollView>
|
||||
{this._renderExampleList()}
|
||||
{exitRow}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
_renderExampleList: function() {
|
||||
return Object.keys(EXAMPLES).map(exampleName => (
|
||||
<NavigationExampleRow
|
||||
key={exampleName}
|
||||
text={exampleName}
|
||||
onPress={() => {
|
||||
this.setExample(exampleName);
|
||||
}}
|
||||
/>
|
||||
));
|
||||
},
|
||||
|
||||
_exitInnerExample: function() {
|
||||
this.setExample('menu');
|
||||
},
|
||||
|
||||
handleBackAction: function() {
|
||||
const wasHandledByExample = (
|
||||
this.exampleRef &&
|
||||
this.exampleRef.handleBackAction &&
|
||||
this.exampleRef.handleBackAction()
|
||||
);
|
||||
if (wasHandledByExample) {
|
||||
return true;
|
||||
}
|
||||
if (this.state.example && this.state.example !== 'menu') {
|
||||
this._exitInnerExample();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.example === 'menu') {
|
||||
return this._renderMenu();
|
||||
}
|
||||
if (EXAMPLES[this.state.example]) {
|
||||
var Component = EXAMPLES[this.state.example];
|
||||
return (
|
||||
<Component
|
||||
onExampleExit={this._exitInnerExample}
|
||||
ref={exampleRef => { this.exampleRef = exampleRef; }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
menu: {
|
||||
backgroundColor: '#E9E9EF',
|
||||
flex: 1,
|
||||
marginTop: 20,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationExperimentalExample;
|
||||
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
const {
|
||||
Container: NavigationContainer,
|
||||
RootContainer: NavigationRootContainer,
|
||||
Reducer: NavigationReducer,
|
||||
} = NavigationExperimental;
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const NavigationExampleTabBar = require('./NavigationExampleTabBar');
|
||||
|
||||
class ExmpleTabPage extends React.Component {
|
||||
render() {
|
||||
const currentTabRoute = this.props.tabs[this.props.index];
|
||||
return (
|
||||
<ScrollView style={styles.tabPage}>
|
||||
<NavigationExampleRow
|
||||
text={`Current Tab is: ${currentTabRoute.key}`}
|
||||
/>
|
||||
{this.props.tabs.map((tab, index) => (
|
||||
<NavigationExampleRow
|
||||
key={tab.key}
|
||||
text={`Go to ${tab.key}`}
|
||||
onPress={() => {
|
||||
this.props.onNavigate(NavigationReducer.TabsReducer.JumpToAction(index));
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<NavigationExampleRow
|
||||
text="Exit Tabs Example"
|
||||
onPress={this.props.onExampleExit}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
ExmpleTabPage = NavigationContainer.create(ExmpleTabPage);
|
||||
|
||||
const ExampleTabsReducer = NavigationReducer.TabsReducer({
|
||||
tabReducers: [
|
||||
(lastRoute) => lastRoute || {key: 'one'},
|
||||
(lastRoute) => lastRoute || {key: 'two'},
|
||||
(lastRoute) => lastRoute || {key: 'three'},
|
||||
],
|
||||
});
|
||||
|
||||
class NavigationTabsExample extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
reducer={ExampleTabsReducer}
|
||||
persistenceKey="NAV_EXAMPLE_STATE_TABS"
|
||||
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
|
||||
renderNavigation={(navigationState) => {
|
||||
if (!navigationState) { return null; }
|
||||
return (
|
||||
<View style={styles.topView}>
|
||||
<ExmpleTabPage
|
||||
tabs={navigationState.children}
|
||||
index={navigationState.index}
|
||||
onExampleExit={this.props.onExampleExit}
|
||||
/>
|
||||
<NavigationExampleTabBar
|
||||
tabs={navigationState.children}
|
||||
index={navigationState.index}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
handleBackAction() {
|
||||
return (
|
||||
this.navRootContainer &&
|
||||
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
topView: {
|
||||
flex: 1,
|
||||
paddingTop: 30,
|
||||
},
|
||||
tabPage: {
|
||||
backgroundColor: '#E9E9EF',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationTabsExample;
|
||||
@@ -1,314 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule NavigationTicTacToeExample
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
const {
|
||||
Container: NavigationContainer,
|
||||
RootContainer: NavigationRootContainer,
|
||||
} = NavigationExperimental;
|
||||
|
||||
type GameGrid = Array<Array<?string>>;
|
||||
|
||||
const evenOddPlayerMap = ['O', 'X'];
|
||||
const rowLetterMap = ['a', 'b', 'c'];
|
||||
|
||||
function parseGame(game: string): GameGrid {
|
||||
const gameTurns = game ? game.split('-') : [];
|
||||
const grid = Array(3);
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const row = Array(3);
|
||||
for (let j = 0; j < 3; j++) {
|
||||
const turnIndex = gameTurns.indexOf(rowLetterMap[i]+j);
|
||||
if (turnIndex === -1) {
|
||||
row[j] = null;
|
||||
} else {
|
||||
row[j] = evenOddPlayerMap[turnIndex % 2];
|
||||
}
|
||||
}
|
||||
grid[i] = row;
|
||||
}
|
||||
return grid;
|
||||
}
|
||||
|
||||
function playTurn(game: string, row: number, col: number): string {
|
||||
const turn = rowLetterMap[row] + col;
|
||||
return game ? (game + '-' + turn) : turn;
|
||||
}
|
||||
|
||||
function getWinner(gameString: string): ?string {
|
||||
const game = parseGame(gameString);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
if (game[i][0] !== null && game[i][0] === game[i][1] &&
|
||||
game[i][0] === game[i][2]) {
|
||||
return game[i][0];
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < 3; i++) {
|
||||
if (game[0][i] !== null && game[0][i] === game[1][i] &&
|
||||
game[0][i] === game[2][i]) {
|
||||
return game[0][i];
|
||||
}
|
||||
}
|
||||
if (game[0][0] !== null && game[0][0] === game[1][1] &&
|
||||
game[0][0] === game[2][2]) {
|
||||
return game[0][0];
|
||||
}
|
||||
if (game[0][2] !== null && game[0][2] === game[1][1] &&
|
||||
game[0][2] === game[2][0]) {
|
||||
return game[0][2];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isGameOver(gameString: string): boolean {
|
||||
if (getWinner(gameString)) {
|
||||
return true;
|
||||
}
|
||||
const game = parseGame(gameString);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
for (var j = 0; j < 3; j++) {
|
||||
if (game[i][j] === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class Cell extends React.Component {
|
||||
props: any;
|
||||
cellStyle() {
|
||||
switch (this.props.player) {
|
||||
case 'X':
|
||||
return styles.cellX;
|
||||
case 'O':
|
||||
return styles.cellO;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
textStyle() {
|
||||
switch (this.props.player) {
|
||||
case 'X':
|
||||
return styles.cellTextX;
|
||||
case 'O':
|
||||
return styles.cellTextO;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
onPress={this.props.onPress}
|
||||
underlayColor="transparent"
|
||||
activeOpacity={0.5}>
|
||||
<View style={[styles.cell, this.cellStyle()]}>
|
||||
<Text style={[styles.cellText, this.textStyle()]}>
|
||||
{this.props.player}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function GameEndOverlay(props) {
|
||||
if (!isGameOver(props.game)) {
|
||||
return <View />;
|
||||
}
|
||||
const winner = getWinner(props.game);
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<Text style={styles.overlayMessage}>
|
||||
{winner ? winner + ' wins!' : 'It\'s a tie!'}
|
||||
</Text>
|
||||
<TouchableHighlight
|
||||
onPress={() => props.onNavigate(GameActions.Reset())}
|
||||
underlayColor="transparent"
|
||||
activeOpacity={0.5}>
|
||||
<View style={styles.newGame}>
|
||||
<Text style={styles.newGameText}>New Game</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
GameEndOverlay = NavigationContainer.create(GameEndOverlay);
|
||||
|
||||
function TicTacToeGame(props) {
|
||||
var rows = parseGame(props.game).map((cells, row) =>
|
||||
<View key={'row' + row} style={styles.row}>
|
||||
{cells.map((player, col) =>
|
||||
<Cell
|
||||
key={'cell' + col}
|
||||
player={player}
|
||||
onPress={() => props.onNavigate(GameActions.Turn(row, col))}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text
|
||||
style={styles.closeButton}
|
||||
onPress={props.onExampleExit}>
|
||||
Close
|
||||
</Text>
|
||||
<Text style={styles.title}>EXTREME T3</Text>
|
||||
<View style={styles.board}>
|
||||
{rows}
|
||||
</View>
|
||||
<GameEndOverlay
|
||||
game={props.game}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
TicTacToeGame = NavigationContainer.create(TicTacToeGame);
|
||||
|
||||
const GameActions = {
|
||||
Turn: (row, col) => ({type: 'TicTacToeTurnAction', row, col }),
|
||||
Reset: (row, col) => ({type: 'TicTacToeResetAction' }),
|
||||
};
|
||||
|
||||
function GameReducer(lastGame: ?string, action: Object): string {
|
||||
if (!lastGame) {
|
||||
lastGame = '';
|
||||
}
|
||||
if (action.type === 'TicTacToeResetAction') {
|
||||
return '';
|
||||
}
|
||||
if (!isGameOver(lastGame) && action.type === 'TicTacToeTurnAction') {
|
||||
return playTurn(lastGame, action.row, action.col);
|
||||
}
|
||||
return lastGame;
|
||||
}
|
||||
|
||||
class NavigationTicTacToeExample extends React.Component {
|
||||
static GameView = TicTacToeGame;
|
||||
static GameReducer = GameReducer;
|
||||
static GameActions = GameActions;
|
||||
render() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
reducer={GameReducer}
|
||||
persistenceKey="TicTacToeGameState"
|
||||
renderNavigation={(game) => (
|
||||
<TicTacToeGame
|
||||
game={game}
|
||||
onExampleExit={this.props.onExampleExit}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
closeButton: {
|
||||
position: 'absolute',
|
||||
left: 10,
|
||||
top: 30,
|
||||
fontSize: 14,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'white'
|
||||
},
|
||||
title: {
|
||||
fontFamily: 'Chalkduster',
|
||||
fontSize: 39,
|
||||
marginBottom: 20,
|
||||
},
|
||||
board: {
|
||||
padding: 5,
|
||||
backgroundColor: '#47525d',
|
||||
borderRadius: 10,
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
cell: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 5,
|
||||
backgroundColor: '#7b8994',
|
||||
margin: 5,
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
cellX: {
|
||||
backgroundColor: '#72d0eb',
|
||||
},
|
||||
cellO: {
|
||||
backgroundColor: '#7ebd26',
|
||||
},
|
||||
cellText: {
|
||||
fontSize: 50,
|
||||
fontFamily: 'AvenirNext-Bold',
|
||||
},
|
||||
cellTextX: {
|
||||
color: '#19a9e5',
|
||||
},
|
||||
cellTextO: {
|
||||
color: '#b9dc2f',
|
||||
},
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: 'rgba(221, 221, 221, 0.5)',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
overlayMessage: {
|
||||
fontSize: 40,
|
||||
marginBottom: 20,
|
||||
marginLeft: 20,
|
||||
marginRight: 20,
|
||||
fontFamily: 'AvenirNext-DemiBold',
|
||||
textAlign: 'center',
|
||||
},
|
||||
newGame: {
|
||||
backgroundColor: '#887766',
|
||||
padding: 20,
|
||||
borderRadius: 5,
|
||||
},
|
||||
newGameText: {
|
||||
color: 'white',
|
||||
fontSize: 20,
|
||||
fontFamily: 'AvenirNext-DemiBold',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationTicTacToeExample;
|
||||
@@ -24,6 +24,8 @@ var {
|
||||
TouchableOpacity,
|
||||
} = React;
|
||||
|
||||
var cssVar = require('cssVar');
|
||||
|
||||
class NavButton extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
@@ -176,7 +178,7 @@ var styles = StyleSheet.create({
|
||||
marginVertical: 10,
|
||||
},
|
||||
navBarTitleText: {
|
||||
color: '#373E4D',
|
||||
color: cssVar('fbui-bluegray-60'),
|
||||
fontWeight: '500',
|
||||
marginVertical: 9,
|
||||
},
|
||||
@@ -187,7 +189,7 @@ var styles = StyleSheet.create({
|
||||
paddingRight: 10,
|
||||
},
|
||||
navBarButtonText: {
|
||||
color: '#5890FF',
|
||||
color: cssVar('fbui-accent-blue'),
|
||||
},
|
||||
scene: {
|
||||
flex: 1,
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule NavigatorExample
|
||||
*/
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var React = require('react-native');
|
||||
var {
|
||||
NavigatorIOS,
|
||||
StatusBar,
|
||||
StatusBarIOS,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
@@ -45,7 +45,7 @@ var NavigatorIOSColors = React.createClass({
|
||||
|
||||
render: function() {
|
||||
// Set StatusBar with light contents to get better contrast
|
||||
StatusBar.setBarStyle('light-content');
|
||||
StatusBarIOS.setStyle('light-content');
|
||||
|
||||
return (
|
||||
<NavigatorIOS
|
||||
@@ -55,7 +55,7 @@ var NavigatorIOSColors = React.createClass({
|
||||
title: '<NavigatorIOS>',
|
||||
rightButtonTitle: 'Done',
|
||||
onRightButtonPress: () => {
|
||||
StatusBar.setBarStyle('default');
|
||||
StatusBarIOS.setStyle('default');
|
||||
this.props.onExampleExit();
|
||||
},
|
||||
passProps: {
|
||||
|
||||
@@ -15,12 +15,11 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const ViewExample = require('./ViewExample');
|
||||
const createExamplePage = require('./createExamplePage');
|
||||
const {
|
||||
var React = require('react-native');
|
||||
var ViewExample = require('./ViewExample');
|
||||
var createExamplePage = require('./createExamplePage');
|
||||
var {
|
||||
AlertIOS,
|
||||
NavigatorIOS,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
@@ -28,7 +27,8 @@ const {
|
||||
View,
|
||||
} = React;
|
||||
|
||||
const EmptyPage = React.createClass({
|
||||
var EmptyPage = React.createClass({
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.emptyPage}>
|
||||
@@ -38,24 +38,41 @@ const EmptyPage = React.createClass({
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
const NavigatorIOSExamplePage = React.createClass({
|
||||
var NavigatorIOSExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: '<NavigatorIOS>',
|
||||
description: 'iOS navigation capabilities',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var recurseTitle = 'Recurse Navigation';
|
||||
if (!this.props.depth || this.props.depth === 1) {
|
||||
if (!this.props.topExampleRoute) {
|
||||
recurseTitle += ' - more examples here';
|
||||
}
|
||||
return (
|
||||
<ScrollView style={styles.list}>
|
||||
<View style={styles.line}/>
|
||||
<View style={styles.group}>
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowNote}>
|
||||
See <UIExplorerApp> for top-level usage.
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.line}/>
|
||||
<View style={styles.groupSpace}/>
|
||||
<View style={styles.line}/>
|
||||
<View style={styles.group}>
|
||||
{this._renderRow(recurseTitle, () => {
|
||||
this.props.navigator.push({
|
||||
title: NavigatorIOSExample.title,
|
||||
component: NavigatorIOSExamplePage,
|
||||
component: NavigatorIOSExample,
|
||||
backButtonTitle: 'Custom Back',
|
||||
passProps: {depth: this.props.depth ? this.props.depth + 1 : 1},
|
||||
passProps: {topExampleRoute: this.props.topExampleRoute || this.props.route},
|
||||
});
|
||||
})}
|
||||
{this._renderRow('Push View Example', () => {
|
||||
@@ -105,39 +122,40 @@ const NavigatorIOSExamplePage = React.createClass({
|
||||
{this._renderRow('Pop to top', () => {
|
||||
this.props.navigator.popToTop();
|
||||
})}
|
||||
{this._renderReplace()}
|
||||
{this._renderRow('Replace here', () => {
|
||||
var prevRoute = this.props.route;
|
||||
this.props.navigator.replace({
|
||||
title: 'New Navigation',
|
||||
component: EmptyPage,
|
||||
rightButtonTitle: 'Undo',
|
||||
onRightButtonPress: () => this.props.navigator.replace(prevRoute),
|
||||
passProps: {
|
||||
text: 'The component is replaced, but there is currently no ' +
|
||||
'way to change the right button or title of the current route',
|
||||
}
|
||||
});
|
||||
})}
|
||||
{this._renderReplacePrevious()}
|
||||
{this._renderReplacePreviousAndPop()}
|
||||
{this._renderRow('Exit NavigatorIOS Example', this.props.onExampleExit)}
|
||||
{this._renderPopToTopNavExample()}
|
||||
</View>
|
||||
<View style={styles.line}/>
|
||||
</ScrollView>
|
||||
);
|
||||
},
|
||||
|
||||
_renderReplace: function() {
|
||||
if (!this.props.depth) {
|
||||
// this is to avoid replacing the top of the stack
|
||||
_renderPopToTopNavExample: function() {
|
||||
if (!this.props.topExampleRoute) {
|
||||
return null;
|
||||
}
|
||||
return this._renderRow('Replace here', () => {
|
||||
var prevRoute = this.props.route;
|
||||
this.props.navigator.replace({
|
||||
title: 'New Navigation',
|
||||
component: EmptyPage,
|
||||
rightButtonTitle: 'Undo',
|
||||
onRightButtonPress: () => this.props.navigator.replace(prevRoute),
|
||||
passProps: {
|
||||
text: 'The component is replaced, but there is currently no ' +
|
||||
'way to change the right button or title of the current route',
|
||||
}
|
||||
});
|
||||
return this._renderRow('Pop to top NavigatorIOSExample', () => {
|
||||
this.props.navigator.popToRoute(this.props.topExampleRoute);
|
||||
});
|
||||
},
|
||||
|
||||
_renderReplacePrevious: function() {
|
||||
if (!this.props.depth || this.props.depth < 2) {
|
||||
// this is to avoid replacing the top of the stack
|
||||
if (!this.props.topExampleRoute) {
|
||||
// this is to avoid replacing the UIExplorerList at the top of the stack
|
||||
return null;
|
||||
}
|
||||
return this._renderRow('Replace previous', () => {
|
||||
@@ -153,8 +171,8 @@ const NavigatorIOSExamplePage = React.createClass({
|
||||
},
|
||||
|
||||
_renderReplacePreviousAndPop: function() {
|
||||
if (!this.props.depth || this.props.depth < 2) {
|
||||
// this is to avoid replacing the top of the stack
|
||||
if (!this.props.topExampleRoute) {
|
||||
// this is to avoid replacing the UIExplorerList at the top of the stack
|
||||
return null;
|
||||
}
|
||||
return this._renderRow('Replace previous and pop', () => {
|
||||
@@ -185,34 +203,7 @@ const NavigatorIOSExamplePage = React.createClass({
|
||||
},
|
||||
});
|
||||
|
||||
const NavigatorIOSExample = React.createClass({
|
||||
statics: {
|
||||
title: '<NavigatorIOS>',
|
||||
description: 'iOS navigation capabilities',
|
||||
external: true,
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const {onExampleExit} = this.props;
|
||||
return (
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
initialRoute={{
|
||||
title: NavigatorIOSExample.title,
|
||||
component: NavigatorIOSExamplePage,
|
||||
passProps: {onExampleExit},
|
||||
}}
|
||||
itemWrapperStyle={styles.itemWrapper}
|
||||
tintColor="#008888"
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
var styles = StyleSheet.create({
|
||||
customWrapperStyle: {
|
||||
backgroundColor: '#bbdddd',
|
||||
},
|
||||
|
||||
@@ -134,8 +134,8 @@ const IsConnectionExpensive = React.createClass({
|
||||
};
|
||||
},
|
||||
_checkIfExpensive() {
|
||||
NetInfo.isConnectionExpensive().then(
|
||||
isConnectionExpensive => { this.setState({isConnectionExpensive}); }
|
||||
NetInfo.isConnectionExpensive(
|
||||
(isConnectionExpensive) => { this.setState({isConnectionExpensive}); }
|
||||
);
|
||||
},
|
||||
render() {
|
||||
|
||||
@@ -16,123 +16,127 @@
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const StyleSheet = require('StyleSheet');
|
||||
const UIExplorerBlock = require('UIExplorerBlock');
|
||||
const UIExplorerPage = require('UIExplorerPage');
|
||||
|
||||
const {
|
||||
Picker,
|
||||
PickerAndroid,
|
||||
Text,
|
||||
TouchableWithoutFeedback,
|
||||
} = React;
|
||||
const Item = Picker.Item;
|
||||
|
||||
const PickerExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: '<Picker>',
|
||||
description: 'Provides multiple options to choose from, using either a dropdown menu or a dialog.',
|
||||
},
|
||||
const Item = PickerAndroid.Item;
|
||||
|
||||
const PickerAndroidExample = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
selected1: 'key1',
|
||||
selected2: 'key1',
|
||||
selected3: 'key1',
|
||||
selected4: 'key1',
|
||||
color: 'red',
|
||||
mode: Picker.MODE_DIALOG,
|
||||
mode: PickerAndroid.MODE_DIALOG,
|
||||
};
|
||||
},
|
||||
|
||||
displayName: 'Android Picker',
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title="<Picker>">
|
||||
<UIExplorerPage title="<PickerAndroid>">
|
||||
<UIExplorerBlock title="Basic Picker">
|
||||
<Picker
|
||||
style={styles.picker}
|
||||
selectedValue={this.state.selected1}
|
||||
onValueChange={this.onValueChange.bind(this, 'selected1')}>
|
||||
<Item label="hello" value="key0" />
|
||||
<Item label="world" value="key1" />
|
||||
</Picker>
|
||||
<PickerAndroid
|
||||
style={{width: 100, height: 56}}
|
||||
onSelect={this.onSelect.bind(this, 'selected1')}>
|
||||
<Item text="hello" value="key0" selected={this.state.selected1 === 'key0'} />
|
||||
<Item text="world" value="key1" selected={this.state.selected1 === 'key1'} />
|
||||
</PickerAndroid>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Disabled picker">
|
||||
<Picker style={styles.picker} enabled={false} selectedValue={this.state.selected1}>
|
||||
<Item label="hello" value="key0" />
|
||||
<Item label="world" value="key1" />
|
||||
</Picker>
|
||||
<PickerAndroid style={{width: 100, height: 56}} enabled={false}>
|
||||
<Item text="hello" value="key0" selected={this.state.selected1 === 'key0'} />
|
||||
<Item text="world" value="key1" selected={this.state.selected1 === 'key1'} />
|
||||
</PickerAndroid>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Dropdown Picker">
|
||||
<Picker
|
||||
style={styles.picker}
|
||||
selectedValue={this.state.selected2}
|
||||
onValueChange={this.onValueChange.bind(this, 'selected2')}
|
||||
<PickerAndroid
|
||||
style={{width: 100, height: 56}}
|
||||
onSelect={this.onSelect.bind(this, 'selected2')}
|
||||
mode="dropdown">
|
||||
<Item label="hello" value="key0" />
|
||||
<Item label="world" value="key1" />
|
||||
</Picker>
|
||||
<Item text="hello" value="key0" selected={this.state.selected2 === 'key0'} />
|
||||
<Item text="world" value="key1" selected={this.state.selected2 === 'key1'} />
|
||||
</PickerAndroid>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Alternating Picker">
|
||||
<PickerAndroid
|
||||
style={{width: 100, height: 56}}
|
||||
onSelect={this.onSelect.bind(this, 'selected3')}
|
||||
mode={this.state.mode}>
|
||||
<Item text="hello" value="key0" selected={this.state.selected3 === 'key0'} />
|
||||
<Item text="world" value="key1" selected={this.state.selected3 === 'key1'} />
|
||||
</PickerAndroid>
|
||||
<TouchableWithoutFeedback onPress={this.changeMode}>
|
||||
<Text>Tap here to switch between dialog/dropdown.</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Picker with prompt message">
|
||||
<Picker
|
||||
style={styles.picker}
|
||||
selectedValue={this.state.selected3}
|
||||
onValueChange={this.onValueChange.bind(this, 'selected3')}
|
||||
<PickerAndroid
|
||||
style={{width: 100, height: 56}}
|
||||
onSelect={this.onSelect.bind(this, 'selected4')}
|
||||
prompt="Pick one, just one">
|
||||
<Item label="hello" value="key0" />
|
||||
<Item label="world" value="key1" />
|
||||
</Picker>
|
||||
<Item text="hello" value="key0" selected={this.state.selected4 === 'key0'} />
|
||||
<Item text="world" value="key1" selected={this.state.selected4 === 'key1'} />
|
||||
</PickerAndroid>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Picker with no listener">
|
||||
<Picker style={styles.picker}>
|
||||
<Item label="hello" value="key0" />
|
||||
<Item label="world" value="key1" />
|
||||
</Picker>
|
||||
<PickerAndroid style={{width: 100, height: 56}}>
|
||||
<Item text="hello" value="key0" />
|
||||
<Item text="world" value="key1" />
|
||||
</PickerAndroid>
|
||||
<Text>
|
||||
Cannot change the value of this picker because it doesn't update selectedValue.
|
||||
You can not change the value of this picker because it doesn't set a selected prop on
|
||||
its items.
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Colorful pickers">
|
||||
<Picker
|
||||
style={[styles.picker, {color: 'white', backgroundColor: '#333'}]}
|
||||
selectedValue={this.state.color}
|
||||
onValueChange={this.onValueChange.bind(this, 'color')}
|
||||
<PickerAndroid style={{width: 100, height: 56, color: 'black'}}
|
||||
onSelect={this.onSelect.bind(this, 'color')}
|
||||
mode="dropdown">
|
||||
<Item label="red" color="red" value="red" />
|
||||
<Item label="green" color="green" value="green" />
|
||||
<Item label="blue" color="blue" value="blue" />
|
||||
</Picker>
|
||||
<Picker
|
||||
style={styles.picker}
|
||||
selectedValue={this.state.color}
|
||||
onValueChange={this.onValueChange.bind(this, 'color')}
|
||||
<Item text="red" color="red" value="red" selected={this.state.color === 'red'}/>
|
||||
<Item text="green" color="green" value="green" selected={this.state.color === 'green'}/>
|
||||
<Item text="blue" color="blue" value="blue" selected={this.state.color === 'blue'}/>
|
||||
</PickerAndroid>
|
||||
<PickerAndroid style={{width: 100, height: 56}}
|
||||
onSelect={this.onSelect.bind(this, 'color')}
|
||||
mode="dialog">
|
||||
<Item label="red" color="red" value="red" />
|
||||
<Item label="green" color="green" value="green" />
|
||||
<Item label="blue" color="blue" value="blue" />
|
||||
</Picker>
|
||||
<Item text="red" color="red" value="red" selected={this.state.color === 'red'}/>
|
||||
<Item text="green" color="green" value="green" selected={this.state.color === 'green'}/>
|
||||
<Item text="blue" color="blue" value="blue" selected={this.state.color === 'blue'} />
|
||||
</PickerAndroid>
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
|
||||
changeMode: function() {
|
||||
const newMode = this.state.mode === Picker.MODE_DIALOG
|
||||
? Picker.MODE_DROPDOWN
|
||||
: Picker.MODE_DIALOG;
|
||||
const newMode = this.state.mode === PickerAndroid.MODE_DIALOG
|
||||
? PickerAndroid.MODE_DROPDOWN
|
||||
: PickerAndroid.MODE_DIALOG;
|
||||
this.setState({mode: newMode});
|
||||
},
|
||||
|
||||
onValueChange: function(key: string, value: string) {
|
||||
onSelect: function(key, value) {
|
||||
const newState = {};
|
||||
newState[key] = value;
|
||||
this.setState(newState);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
picker: {
|
||||
width: 100,
|
||||
exports.title = '<PickerAndroid>';
|
||||
exports.displayName = 'PickerAndroidExample';
|
||||
exports.description = 'The Android Picker component provides multiple options to choose from';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'PickerAndroidExample',
|
||||
render(): ReactElement { return <PickerAndroidExample />; }
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = PickerExample;
|
||||
];
|
||||
|
||||
@@ -182,7 +182,7 @@ var BoxOnlyExample = React.createClass({
|
||||
});
|
||||
|
||||
type ExampleClass = {
|
||||
Component: ReactClass<any>,
|
||||
Component: ReactClass<any, any, any>,
|
||||
title: string,
|
||||
description: string,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
PullToRefreshViewAndroid,
|
||||
Text,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
borderColor: 'grey',
|
||||
borderWidth: 1,
|
||||
padding: 20,
|
||||
backgroundColor: '#3a5795',
|
||||
margin: 5,
|
||||
},
|
||||
text: {
|
||||
alignSelf: 'center',
|
||||
color: '#fff',
|
||||
|
||||
},
|
||||
layout: {
|
||||
flex: 1,
|
||||
},
|
||||
scrollview: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const Row = React.createClass({
|
||||
_onClick: function() {
|
||||
this.props.onClick(this.props.data);
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<TouchableWithoutFeedback onPress={this._onClick} >
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.text}>
|
||||
{this.props.data.text + ' (' + this.props.data.clicks + ' clicks)'}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
},
|
||||
});
|
||||
const PullToRefreshViewAndroidExample = React.createClass({
|
||||
statics: {
|
||||
title: '<PullToRefreshViewAndroid>',
|
||||
description: 'Container that adds pull-to-refresh support to its child view.'
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
isRefreshing: false,
|
||||
loaded: 0,
|
||||
rowData: Array.from(new Array(20)).map(
|
||||
(val, i) => ({text: 'Initial row' + i, clicks: 0})
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
_onClick(row) {
|
||||
row.clicks++;
|
||||
this.setState({
|
||||
rowData: this.state.rowData,
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
const rows = this.state.rowData.map((row, ii) => {
|
||||
return <Row key={ii} data={row} onClick={this._onClick}/>;
|
||||
});
|
||||
return (
|
||||
<PullToRefreshViewAndroid
|
||||
style={styles.layout}
|
||||
refreshing={this.state.isRefreshing}
|
||||
onRefresh={this._onRefresh}
|
||||
colors={['#ff0000', '#00ff00', '#0000ff']}
|
||||
progressBackgroundColor={'#ffff00'}
|
||||
>
|
||||
<ScrollView style={styles.scrollview}>
|
||||
{rows}
|
||||
</ScrollView>
|
||||
</PullToRefreshViewAndroid>
|
||||
);
|
||||
},
|
||||
|
||||
_onRefresh() {
|
||||
this.setState({isRefreshing: true});
|
||||
setTimeout(() => {
|
||||
// prepend 10 items
|
||||
const rowData = Array.from(new Array(10))
|
||||
.map((val, i) => ({
|
||||
text: 'Loaded row' + (+this.state.loaded + i),
|
||||
clicks: 0,
|
||||
}))
|
||||
.concat(this.state.rowData);
|
||||
|
||||
this.setState({
|
||||
loaded: this.state.loaded + 10,
|
||||
isRefreshing: false,
|
||||
rowData: rowData,
|
||||
});
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
module.exports = PullToRefreshViewAndroidExample;
|
||||
@@ -84,8 +84,6 @@ class NotificationExample extends React.Component {
|
||||
}
|
||||
|
||||
class NotificationPermissionExample extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {permissions: null};
|
||||
@@ -128,7 +126,7 @@ exports.description = 'Apple PushNotification and badge value';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Badge Number',
|
||||
render(): ReactElement {
|
||||
render(): React.Component {
|
||||
PushNotificationIOS.requestPermissions();
|
||||
|
||||
return (
|
||||
@@ -147,13 +145,13 @@ exports.examples = [
|
||||
},
|
||||
{
|
||||
title: 'Push Notifications',
|
||||
render(): ReactElement {
|
||||
render(): React.Component {
|
||||
return <NotificationExample />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Notifications Permissions',
|
||||
render(): ReactElement {
|
||||
render(): React.Component {
|
||||
return <NotificationPermissionExample />;
|
||||
}
|
||||
}];
|
||||
|
||||
@@ -82,7 +82,7 @@ exports.description = 'Examples that show useful methods when embedding React Na
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Updating app properties in runtime',
|
||||
render(): ReactElement {
|
||||
render(): React.Component {
|
||||
return (
|
||||
<AppPropertiesUpdateExample/>
|
||||
);
|
||||
@@ -90,7 +90,7 @@ exports.examples = [
|
||||
},
|
||||
{
|
||||
title: 'RCTRootView\'s size flexibility',
|
||||
render(): ReactElement {
|
||||
render(): React.Component {
|
||||
return (
|
||||
<RootViewSizeFlexibilityExample/>
|
||||
);
|
||||
|
||||
@@ -69,7 +69,7 @@ const RefreshControlExample = React.createClass({
|
||||
isRefreshing: false,
|
||||
loaded: 0,
|
||||
rowData: Array.from(new Array(20)).map(
|
||||
(val, i) => ({text: 'Initial row ' + i, clicks: 0})),
|
||||
(val, i) => ({text: 'Initial row' + i, clicks: 0})),
|
||||
};
|
||||
},
|
||||
|
||||
@@ -108,7 +108,7 @@ const RefreshControlExample = React.createClass({
|
||||
// prepend 10 items
|
||||
const rowData = Array.from(new Array(10))
|
||||
.map((val, i) => ({
|
||||
text: 'Loaded row ' + (+this.state.loaded + i),
|
||||
text: 'Loaded row' + (+this.state.loaded + i),
|
||||
clicks: 0,
|
||||
}))
|
||||
.concat(this.state.rowData);
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
class RootViewSizeFlexibilityExampleApp extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props: {toggled: boolean}) {
|
||||
super(props);
|
||||
this.state = { toggled: false };
|
||||
}
|
||||
|
||||
_onPressButton() {
|
||||
this.setState({ toggled: !this.state.toggled });
|
||||
}
|
||||
|
||||
render() {
|
||||
const viewStyle = this.state.toggled ? styles.bigContainer : styles.smallContainer;
|
||||
|
||||
return (
|
||||
<TouchableHighlight onPress={this._onPressButton.bind(this)}>
|
||||
<View style={viewStyle}>
|
||||
<View style={styles.center}>
|
||||
<Text style={styles.whiteText}>
|
||||
React Native Button
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
bigContainer: {
|
||||
flex: 1,
|
||||
height: 60,
|
||||
backgroundColor: 'gray',
|
||||
},
|
||||
smallContainer: {
|
||||
flex: 1,
|
||||
height: 40,
|
||||
backgroundColor: 'gray',
|
||||
},
|
||||
center: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
whiteText: {
|
||||
color: 'white',
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = RootViewSizeFlexibilityExampleApp;
|
||||
@@ -19,8 +19,6 @@ var React = require('react-native');
|
||||
var {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
Image
|
||||
} = React;
|
||||
@@ -33,45 +31,27 @@ exports.examples = [
|
||||
title: '<ScrollView>',
|
||||
description: 'To make content scrollable, wrap it within a <ScrollView> component',
|
||||
render: function() {
|
||||
var _scrollView: ScrollView;
|
||||
return (
|
||||
<View>
|
||||
<ScrollView
|
||||
ref={(scrollView) => { _scrollView = scrollView; }}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
onScroll={() => { console.log('onScroll!'); }}
|
||||
scrollEventThrottle={200}
|
||||
style={styles.scrollView}>
|
||||
{THUMBS.map(createThumbRow)}
|
||||
</ScrollView>
|
||||
<TouchableOpacity
|
||||
style={styles.button}
|
||||
onPress={() => { _scrollView.scrollTo({y: 0}); }}>
|
||||
<Text>Scroll to top</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<ScrollView
|
||||
automaticallyAdjustContentInsets={false}
|
||||
onScroll={() => { console.log('onScroll!'); }}
|
||||
scrollEventThrottle={200}
|
||||
style={styles.scrollView}>
|
||||
{THUMBS.map(createThumbRow)}
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}, {
|
||||
title: '<ScrollView> (horizontal = true)',
|
||||
description: 'You can display <ScrollView>\'s child components horizontally rather than vertically',
|
||||
render: function() {
|
||||
var _scrollView: ScrollView;
|
||||
return (
|
||||
<View>
|
||||
<ScrollView
|
||||
ref={(scrollView) => { _scrollView = scrollView; }}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
horizontal={true}
|
||||
style={[styles.scrollView, styles.horizontalScrollView]}>
|
||||
{THUMBS.map(createThumbRow)}
|
||||
</ScrollView>
|
||||
<TouchableOpacity
|
||||
style={styles.button}
|
||||
onPress={() => { _scrollView.scrollTo({x: 0}); }}>
|
||||
<Text>Scroll to start</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<ScrollView
|
||||
automaticallyAdjustContentInsets={false}
|
||||
horizontal={true}
|
||||
style={[styles.scrollView, styles.horizontalScrollView]}>
|
||||
{THUMBS.map(createThumbRow)}
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}];
|
||||
|
||||
@@ -13,18 +13,17 @@
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
var React = require('React');
|
||||
var Text = require('Text');
|
||||
var View = require('View');
|
||||
|
||||
class SetPropertiesExampleApp extends React.Component {
|
||||
var SetPropertiesExampleApp = React.createClass({
|
||||
|
||||
render() {
|
||||
const wrapperStyle = {
|
||||
render: function() {
|
||||
var wrapperStyle = {
|
||||
backgroundColor: this.props.color,
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
@@ -38,8 +37,7 @@ class SetPropertiesExampleApp extends React.Component {
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SetPropertiesExampleApp;
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Slider,
|
||||
Text,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var SliderExample = React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
value: 0,
|
||||
}
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
value: this.props.value,
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text style={styles.text} >
|
||||
{this.state.value && +this.state.value.toFixed(3)}
|
||||
</Text>
|
||||
<Slider
|
||||
{...this.props}
|
||||
onValueChange={(value) => this.setState({value: value})} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var SlidingCompleteExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
slideCompletionValue: 0,
|
||||
slideCompletionCount: 0,
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<SliderExample
|
||||
{...this.props}
|
||||
onSlidingComplete={(value) => this.setState({
|
||||
slideCompletionValue: value,
|
||||
slideCompletionCount: this.state.slideCompletionCount + 1})} />
|
||||
<Text>
|
||||
Completions: {this.state.slideCompletionCount} Value: {this.state.slideCompletionValue}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
slider: {
|
||||
height: 10,
|
||||
margin: 10,
|
||||
},
|
||||
text: {
|
||||
fontSize: 14,
|
||||
textAlign: 'center',
|
||||
fontWeight: '500',
|
||||
margin: 10,
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = '<Slider>';
|
||||
exports.displayName = 'SliderExample';
|
||||
exports.description = 'Slider input for numeric values';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Default settings',
|
||||
render(): ReactElement {
|
||||
return <SliderExample />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Initial value: 0.5',
|
||||
render(): ReactElement {
|
||||
return <SliderExample value={0.5} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'minimumValue: -1, maximumValue: 2',
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<SliderExample
|
||||
minimumValue={-1}
|
||||
maximumValue={2}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'step: 0.25',
|
||||
render(): ReactElement {
|
||||
return <SliderExample step={0.25} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'onSlidingComplete',
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<SlidingCompleteExample />
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Custom min/max track tint color',
|
||||
platform: 'ios',
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<SliderExample
|
||||
minimumTrackTintColor={'red'}
|
||||
maximumTrackTintColor={'green'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Custom thumb image',
|
||||
platform: 'ios',
|
||||
render(): ReactElement {
|
||||
return <SliderExample thumbImage={require('./uie_thumb_big.png')} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Custom track image',
|
||||
platform: 'ios',
|
||||
render(): ReactElement {
|
||||
return <SliderExample trackImage={require('./slider.png')} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Custom min/max track image',
|
||||
platform: 'ios',
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<SliderExample
|
||||
minimumTrackImage={require('./slider-left.png')}
|
||||
maximumTrackImage={require('./slider-right.png')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
];
|
||||
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
StyleSheet,
|
||||
Text,
|
||||
UIManager,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var ScreenshotExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
uri: undefined,
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text onPress={this.takeScreenshot} style={style.button}>
|
||||
Click to take a screenshot
|
||||
</Text>
|
||||
<Image style={style.image} source={{uri: this.state.uri}}/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
takeScreenshot() {
|
||||
UIManager
|
||||
.takeSnapshot('window', {format: 'jpeg', quality: 0.8}) // See UIManager.js for options
|
||||
.then((uri) => this.setState({uri}))
|
||||
.catch((error) => alert(error));
|
||||
}
|
||||
});
|
||||
|
||||
var style = StyleSheet.create({
|
||||
button: {
|
||||
marginBottom: 10,
|
||||
fontWeight: '500',
|
||||
},
|
||||
image: {
|
||||
flex: 1,
|
||||
height: 300,
|
||||
resizeMode: 'contain',
|
||||
backgroundColor: 'black',
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = 'Snapshot / Screenshot';
|
||||
exports.description = 'API to capture images from the screen.';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Take screenshot',
|
||||
render(): ReactElement { return <ScreenshotExample />; }
|
||||
},
|
||||
];
|
||||
@@ -1,468 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
exports.framework = 'React';
|
||||
exports.title = '<StatusBar>';
|
||||
exports.description = 'Component for controlling the status bar';
|
||||
|
||||
const colors = [
|
||||
'#ff0000',
|
||||
'#00ff00',
|
||||
'#0000ff',
|
||||
];
|
||||
|
||||
const barStyles = [
|
||||
'default',
|
||||
'light-content',
|
||||
];
|
||||
|
||||
const showHideTransitions = [
|
||||
'fade',
|
||||
'slide',
|
||||
];
|
||||
|
||||
function getValue<T>(values: Array<T>, index: number): T {
|
||||
return values[index % values.length];
|
||||
}
|
||||
|
||||
const StatusBarHiddenExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
animated: true,
|
||||
hidden: false,
|
||||
showHideTransition: getValue(showHideTransitions, 0),
|
||||
};
|
||||
},
|
||||
|
||||
_showHideTransitionIndex: 0,
|
||||
|
||||
_onChangeAnimated() {
|
||||
this.setState({animated: !this.state.animated});
|
||||
},
|
||||
|
||||
_onChangeHidden() {
|
||||
this.setState({hidden: !this.state.hidden});
|
||||
},
|
||||
|
||||
_onChangeTransition() {
|
||||
this._showHideTransitionIndex++;
|
||||
this.setState({
|
||||
showHideTransition: getValue(showHideTransitions, this._showHideTransitionIndex),
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<StatusBar
|
||||
hidden={this.state.hidden}
|
||||
showHideTransition={this.state.showHideTransition}
|
||||
animated={this.state.animated}
|
||||
/>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeHidden}>
|
||||
<View style={styles.button}>
|
||||
<Text>hidden: {this.state.hidden ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeAnimated}>
|
||||
<View style={styles.button}>
|
||||
<Text>animated (ios only): {this.state.animated ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeTransition}>
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
showHideTransition (ios only):
|
||||
'{getValue(showHideTransitions, this._showHideTransitionIndex)}'
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const StatusBarStyleExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
animated: true,
|
||||
barStyle: getValue(barStyles, this._barStyleIndex),
|
||||
};
|
||||
},
|
||||
|
||||
_barStyleIndex: 0,
|
||||
|
||||
_onChangeBarStyle() {
|
||||
this._barStyleIndex++;
|
||||
this.setState({barStyle: getValue(barStyles, this._barStyleIndex)});
|
||||
},
|
||||
|
||||
_onChangeAnimated() {
|
||||
this.setState({animated: !this.state.animated});
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<StatusBar
|
||||
animated={this.state.animated}
|
||||
barStyle={this.state.barStyle}
|
||||
/>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeBarStyle}>
|
||||
<View style={styles.button}>
|
||||
<Text>style: '{getValue(barStyles, this._barStyleIndex)}'</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeAnimated}>
|
||||
<View style={styles.button}>
|
||||
<Text>animated: {this.state.animated ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const StatusBarNetworkActivityExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
networkActivityIndicatorVisible: false,
|
||||
};
|
||||
},
|
||||
|
||||
_onChangeNetworkIndicatorVisible() {
|
||||
this.setState({
|
||||
networkActivityIndicatorVisible: !this.state.networkActivityIndicatorVisible,
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<StatusBar
|
||||
networkActivityIndicatorVisible={this.state.networkActivityIndicatorVisible}
|
||||
/>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeNetworkIndicatorVisible}>
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
networkActivityIndicatorVisible:
|
||||
{this.state.networkActivityIndicatorVisible ? 'true' : 'false'}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const StatusBarBackgroundColorExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
animated: true,
|
||||
backgroundColor: getValue(colors, 0),
|
||||
};
|
||||
},
|
||||
|
||||
_colorIndex: 0,
|
||||
|
||||
_onChangeBackgroundColor() {
|
||||
this._colorIndex++;
|
||||
this.setState({backgroundColor: getValue(colors, this._colorIndex)});
|
||||
},
|
||||
|
||||
_onChangeAnimated() {
|
||||
this.setState({animated: !this.state.animated});
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<StatusBar
|
||||
backgroundColor={this.state.backgroundColor}
|
||||
animated={this.state.animated}
|
||||
/>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeBackgroundColor}>
|
||||
<View style={styles.button}>
|
||||
<Text>backgroundColor: '{getValue(colors, this._colorIndex)}'</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeAnimated}>
|
||||
<View style={styles.button}>
|
||||
<Text>animated: {this.state.animated ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const StatusBarTranslucentExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
translucent: false,
|
||||
};
|
||||
},
|
||||
|
||||
_onChangeTranslucent() {
|
||||
this.setState({
|
||||
translucent: !this.state.translucent,
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<StatusBar
|
||||
translucent={this.state.translucent}
|
||||
/>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeTranslucent}>
|
||||
<View style={styles.button}>
|
||||
<Text>translucent: {this.state.translucent ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const StatusBarStaticIOSExample = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setHidden(true, 'slide');
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setHidden(true, 'slide')</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setHidden(false, 'fade');
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setHidden(false, 'fade')</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setBarStyle('default', true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setBarStyle('default', true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setBarStyle('light-content', true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setBarStyle('light-content', true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setNetworkActivityIndicatorVisible(true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setNetworkActivityIndicatorVisible(true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setNetworkActivityIndicatorVisible(false);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setNetworkActivityIndicatorVisible(false)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const StatusBarStaticAndroidExample = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setHidden(true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setHidden(true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setHidden(false);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setHidden(false)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setBackgroundColor('#ff00ff', true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setBackgroundColor('#ff00ff', true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setBackgroundColor('#00ff00', true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setBackgroundColor('#00ff00', true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setTranslucent(true);
|
||||
StatusBar.setBackgroundColor('rgba(0, 0, 0, 0.4)', true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setTranslucent(true) and setBackgroundColor('rgba(0, 0, 0, 0.4)', true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setTranslucent(false);
|
||||
StatusBar.setBackgroundColor('black', true);
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setTranslucent(false) and setBackgroundColor('black', true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const examples = [{
|
||||
title: 'StatusBar hidden',
|
||||
render() {
|
||||
return <StatusBarHiddenExample />;
|
||||
},
|
||||
}, {
|
||||
title: 'StatusBar style',
|
||||
render() {
|
||||
return <StatusBarStyleExample />;
|
||||
},
|
||||
platform: 'ios',
|
||||
}, {
|
||||
title: 'StatusBar network activity indicator',
|
||||
render() {
|
||||
return <StatusBarNetworkActivityExample />;
|
||||
},
|
||||
platform: 'ios',
|
||||
}, {
|
||||
title: 'StatusBar background color',
|
||||
render() {
|
||||
return <StatusBarBackgroundColorExample />;
|
||||
},
|
||||
platform: 'android',
|
||||
}, {
|
||||
title: 'StatusBar background color',
|
||||
render() {
|
||||
return <StatusBarTranslucentExample />;
|
||||
},
|
||||
platform: 'android',
|
||||
}, {
|
||||
title: 'StatusBar static API',
|
||||
render() {
|
||||
return <StatusBarStaticIOSExample />;
|
||||
},
|
||||
platform: 'ios',
|
||||
}, {
|
||||
title: 'StatusBar static API',
|
||||
render() {
|
||||
return <StatusBarStaticAndroidExample />;
|
||||
},
|
||||
platform: 'android',
|
||||
}, {
|
||||
title: 'StatusBar dimensions',
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text>Height: {StatusBar.currentHeight} pts</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
platform: 'android',
|
||||
}];
|
||||
|
||||
exports.examples = examples;
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
borderRadius: 5,
|
||||
marginBottom: 5,
|
||||
},
|
||||
button: {
|
||||
borderRadius: 5,
|
||||
backgroundColor: '#eeeeee',
|
||||
padding: 10,
|
||||
},
|
||||
title: {
|
||||
marginTop: 16,
|
||||
marginBottom: 8,
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
});
|
||||
@@ -419,7 +419,7 @@ exports.examples = [
|
||||
return (
|
||||
<View>
|
||||
<Text>
|
||||
This text contains an inline image <Image source={require('./flux.png')} style={{width: 30, height: 11, resizeMode: 'cover'}}/>. Neat, huh?
|
||||
This text contains an inline image <Image source={require('./flux.png')}/>. Neat, huh?
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -72,29 +72,6 @@ var TextEventsExample = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
class AutoExpandingTextInput extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {text: '', height: 0};
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<TextInput
|
||||
{...this.props}
|
||||
multiline={true}
|
||||
onChange={(event) => {
|
||||
this.setState({
|
||||
text: event.nativeEvent.text,
|
||||
height: event.nativeEvent.contentSize.height,
|
||||
});
|
||||
}}
|
||||
style={[styles.default, {height: Math.max(35, this.state.height)}]}
|
||||
value={this.state.text}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class RewriteExample extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -178,60 +155,6 @@ class TokenizedTextExample extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
var BlurOnSubmitExample = React.createClass({
|
||||
focusNextField(nextField) {
|
||||
this.refs[nextField].focus();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
ref="1"
|
||||
style={styles.singleLine}
|
||||
placeholder="blurOnSubmit = false"
|
||||
returnKeyType="next"
|
||||
blurOnSubmit={false}
|
||||
onSubmitEditing={() => this.focusNextField('2')}
|
||||
/>
|
||||
<TextInput
|
||||
ref="2"
|
||||
style={styles.singleLine}
|
||||
keyboardType="email-address"
|
||||
placeholder="blurOnSubmit = false"
|
||||
returnKeyType="next"
|
||||
blurOnSubmit={false}
|
||||
onSubmitEditing={() => this.focusNextField('3')}
|
||||
/>
|
||||
<TextInput
|
||||
ref="3"
|
||||
style={styles.singleLine}
|
||||
keyboardType="url"
|
||||
placeholder="blurOnSubmit = false"
|
||||
returnKeyType="next"
|
||||
blurOnSubmit={false}
|
||||
onSubmitEditing={() => this.focusNextField('4')}
|
||||
/>
|
||||
<TextInput
|
||||
ref="4"
|
||||
style={styles.singleLine}
|
||||
keyboardType="numeric"
|
||||
placeholder="blurOnSubmit = false"
|
||||
blurOnSubmit={false}
|
||||
onSubmitEditing={() => this.focusNextField('5')}
|
||||
/>
|
||||
<TextInput
|
||||
ref="5"
|
||||
style={styles.singleLine}
|
||||
keyboardType="numbers-and-punctuation"
|
||||
placeholder="blurOnSubmit = true"
|
||||
returnKeyType="done"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
multiline: {
|
||||
height: 60,
|
||||
@@ -262,13 +185,7 @@ exports.examples = [
|
||||
{
|
||||
title: 'Auto-focus',
|
||||
render: function() {
|
||||
return (
|
||||
<TextInput
|
||||
autoFocus={true}
|
||||
style={styles.singleLine}
|
||||
accessibilityLabel="I am the accessibility label for text input"
|
||||
/>
|
||||
);
|
||||
return <TextInput autoFocus={true} style={styles.singleLine} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -340,10 +257,6 @@ exports.examples = [
|
||||
return <View>{examples}</View>;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Blur on submit',
|
||||
render: function(): ReactElement { return <BlurOnSubmitExample />; },
|
||||
},
|
||||
{
|
||||
title: 'Event handling',
|
||||
render: function(): ReactElement { return <TextEventsExample />; },
|
||||
@@ -386,11 +299,6 @@ exports.examples = [
|
||||
Darker backgroundColor
|
||||
</Text>
|
||||
</TextInput>
|
||||
<TextInput
|
||||
defaultValue="Highlight Color is red"
|
||||
selectionColor={'red'}
|
||||
style={styles.singleLine}>
|
||||
</TextInput>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -410,19 +318,11 @@ exports.examples = [
|
||||
title: 'Passwords',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
defaultValue="iloveturtles"
|
||||
secureTextEntry={true}
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
<TextInput
|
||||
secureTextEntry={true}
|
||||
style={[styles.singleLine, {color: 'red'}]}
|
||||
placeholder="color is supported too"
|
||||
placeholderTextColor="red"
|
||||
/>
|
||||
</View>
|
||||
<TextInput
|
||||
defaultValue="iloveturtles"
|
||||
password={true}
|
||||
style={styles.singleLine}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -448,19 +348,25 @@ exports.examples = [
|
||||
placeholder="multiline, aligned top-left"
|
||||
placeholderTextColor="red"
|
||||
multiline={true}
|
||||
style={[styles.multiline, {textAlign: "left", textAlignVertical: "top"}]}
|
||||
textAlign="start"
|
||||
textAlignVertical="top"
|
||||
style={styles.multiline}
|
||||
/>
|
||||
<TextInput
|
||||
autoCorrect={true}
|
||||
placeholder="multiline, aligned center"
|
||||
placeholderTextColor="green"
|
||||
multiline={true}
|
||||
style={[styles.multiline, {textAlign: "center", textAlignVertical: "center"}]}
|
||||
textAlign="center"
|
||||
textAlignVertical="center"
|
||||
style={[styles.multiline]}
|
||||
/>
|
||||
<TextInput
|
||||
autoCorrect={true}
|
||||
multiline={true}
|
||||
style={[styles.multiline, {color: 'blue'}, {textAlign: "right", textAlignVertical: "bottom"}]}>
|
||||
textAlign="end"
|
||||
textAlignVertical="bottom"
|
||||
style={[styles.multiline, {color: 'blue'}]}>
|
||||
<Text style={styles.multiline}>multiline with children, aligned bottom-right</Text>
|
||||
</TextInput>
|
||||
</View>
|
||||
@@ -485,20 +391,6 @@ exports.examples = [
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Auto-expanding',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<AutoExpandingTextInput
|
||||
placeholder="height increases with content"
|
||||
enablesReturnKeyAutomatically={true}
|
||||
returnKeyType="done"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Attributed text',
|
||||
render: function() {
|
||||
|
||||
@@ -96,34 +96,7 @@ var TextEventsExample = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
class AutoExpandingTextInput extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {text: '', height: 0};
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<TextInput
|
||||
{...this.props}
|
||||
multiline={true}
|
||||
onChange={(event) => {
|
||||
this.setState({
|
||||
text: event.nativeEvent.text,
|
||||
height: event.nativeEvent.contentSize.height,
|
||||
});
|
||||
}}
|
||||
style={[styles.default, {height: Math.max(35, this.state.height)}]}
|
||||
value={this.state.text}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class RewriteExample extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {text: ''};
|
||||
@@ -153,8 +126,6 @@ class RewriteExample extends React.Component {
|
||||
}
|
||||
|
||||
class RewriteExampleInvalidCharacters extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {text: ''};
|
||||
@@ -176,8 +147,6 @@ class RewriteExampleInvalidCharacters extends React.Component {
|
||||
}
|
||||
|
||||
class TokenizedTextExample extends React.Component {
|
||||
state: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {text: 'Hello #World'};
|
||||
@@ -356,13 +325,7 @@ exports.examples = [
|
||||
{
|
||||
title: 'Auto-focus',
|
||||
render: function() {
|
||||
return (
|
||||
<TextInput
|
||||
autoFocus={true}
|
||||
style={styles.default}
|
||||
accessibilityLabel="I am the accessibility label for text input"
|
||||
/>
|
||||
);
|
||||
return <TextInput autoFocus={true} style={styles.default} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -550,25 +513,6 @@ exports.examples = [
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Colored highlight/cursor for text input',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TextInput
|
||||
style={styles.default}
|
||||
selectionColor={"green"}
|
||||
defaultValue="Highlight me"
|
||||
/>
|
||||
<TextInput
|
||||
style={styles.default}
|
||||
selectionColor={"rgba(86, 76, 205, 1)"}
|
||||
defaultValue="Highlight me"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Clear button mode',
|
||||
render: function () {
|
||||
@@ -686,20 +630,6 @@ exports.examples = [
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Auto-expanding',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<AutoExpandingTextInput
|
||||
placeholder="height increases with content"
|
||||
enablesReturnKeyAutomatically={true}
|
||||
returnKeyType="done"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Attributed text',
|
||||
render: function() {
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
TimePickerAndroid,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableWithoutFeedback,
|
||||
} = React;
|
||||
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var TimePickerAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'TimePickerAndroid',
|
||||
description: 'Standard Android time picker dialog',
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
// *Text, *Hour and *Minute are set by successCallback -- this updates the text with the time
|
||||
// picked by the user and makes it so the next time they open it the hour and minute they picked
|
||||
// before is displayed.
|
||||
return {
|
||||
isoFormatText: 'pick a time (24-hour format)',
|
||||
presetHour: 4,
|
||||
presetMinute: 4,
|
||||
presetText: 'pick a time, default: 4:04AM',
|
||||
simpleText: 'pick a time',
|
||||
};
|
||||
},
|
||||
|
||||
async showPicker(stateKey, options) {
|
||||
try {
|
||||
const {action, minute, hour} = await TimePickerAndroid.open(options);
|
||||
var newState = {};
|
||||
if (action === TimePickerAndroid.timeSetAction) {
|
||||
newState[stateKey + 'Text'] = _formatTime(hour, minute);
|
||||
newState[stateKey + 'Hour'] = hour;
|
||||
newState[stateKey + 'Minute'] = minute;
|
||||
} else if (action === TimePickerAndroid.dismissedAction) {
|
||||
newState[stateKey + 'Text'] = 'dismissed';
|
||||
}
|
||||
this.setState(newState);
|
||||
} catch ({code, message}) {
|
||||
console.warn(`Error in example '${stateKey}': `, message);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<UIExplorerPage title="TimePickerAndroid">
|
||||
<UIExplorerBlock title="Simple time picker">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'simple')}>
|
||||
<Text style={styles.text}>{this.state.simpleText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Time picker with pre-set time">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'preset', {
|
||||
hour: this.state.presetHour,
|
||||
minute: this.state.presetMinute,
|
||||
})}>
|
||||
<Text style={styles.text}>{this.state.presetText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Time picker with 24-hour time format">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.showPicker.bind(this, 'isoFormat', {
|
||||
hour: this.state.isoFormatHour,
|
||||
minute: this.state.isoFormatMinute,
|
||||
is24Hour: true,
|
||||
})}>
|
||||
<Text style={styles.text}>{this.state.isoFormatText}</Text>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns e.g. '3:05'.
|
||||
*/
|
||||
function _formatTime(hour, minute) {
|
||||
return hour + ':' + (minute < 10 ? '0' + minute : minute);
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
text: {
|
||||
color: 'black',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = TimePickerAndroidExample;
|
||||
|
||||
@@ -23,9 +23,6 @@ var {
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableOpacity,
|
||||
UIManager,
|
||||
Platform,
|
||||
TouchableNativeFeedback,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
@@ -57,7 +54,7 @@ exports.examples = [
|
||||
activeOpacity={1}
|
||||
animationVelocity={0}
|
||||
underlayColor="rgb(210, 230, 255)"
|
||||
onPress={() => console.log('custom THW text - highlight')}>
|
||||
onPress={() => console.log('custom THW text - hightlight')}>
|
||||
<View style={styles.wrapperCustom}>
|
||||
<Text style={styles.text}>
|
||||
Tap Here For Custom Highlight!
|
||||
@@ -88,28 +85,7 @@ exports.examples = [
|
||||
render: function(): ReactElement {
|
||||
return <TouchableDelayEvents />;
|
||||
},
|
||||
}, {
|
||||
title: '3D Touch / Force Touch',
|
||||
description: 'iPhone 6s and 6s plus support 3D touch, which adds a force property to touches',
|
||||
render: function(): ReactElement {
|
||||
return <ForceTouchExample />;
|
||||
},
|
||||
platform: 'ios',
|
||||
}, {
|
||||
title: 'Touchable Hit Slop',
|
||||
description: '<Touchable*> components accept hitSlop prop which extends the touch area ' +
|
||||
'without changing the view bounds.',
|
||||
render: function(): ReactElement {
|
||||
return <TouchableHitSlop />;
|
||||
},
|
||||
}, {
|
||||
title: 'Disabled Touchable*',
|
||||
description: '<Touchable*> components accept disabled prop which prevents ' +
|
||||
'any interaction with component',
|
||||
render: function(): ReactElement {
|
||||
return <TouchableDisabled />;
|
||||
},
|
||||
}];
|
||||
}];
|
||||
|
||||
var TextOnPressBox = React.createClass({
|
||||
getInitialState: function() {
|
||||
@@ -157,21 +133,18 @@ var TouchableFeedbackEvents = React.createClass({
|
||||
return (
|
||||
<View testID="touchable_feedback_events">
|
||||
<View style={[styles.row, {justifyContent: 'center'}]}>
|
||||
<TouchableOpacity
|
||||
style={styles.wrapper}
|
||||
testID="touchable_feedback_events_button"
|
||||
accessibilityLabel="touchable feedback events"
|
||||
accessibilityTraits="button"
|
||||
accessibilityComponentType="button"
|
||||
onPress={() => this._appendEvent('press')}
|
||||
onPressIn={() => this._appendEvent('pressIn')}
|
||||
onPressOut={() => this._appendEvent('pressOut')}
|
||||
onLongPress={() => this._appendEvent('longPress')}>
|
||||
<Text style={styles.button}>
|
||||
Press Me
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={styles.wrapper}
|
||||
testID="touchable_feedback_events_button"
|
||||
onPress={() => this._appendEvent('press')}
|
||||
onPressIn={() => this._appendEvent('pressIn')}
|
||||
onPressOut={() => this._appendEvent('pressOut')}
|
||||
onLongPress={() => this._appendEvent('longPress')}>
|
||||
<Text style={styles.button}>
|
||||
Press Me
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View testID="touchable_feedback_events_console" style={styles.eventLogBox}>
|
||||
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
|
||||
</View>
|
||||
@@ -196,21 +169,21 @@ var TouchableDelayEvents = React.createClass({
|
||||
return (
|
||||
<View testID="touchable_delay_events">
|
||||
<View style={[styles.row, {justifyContent: 'center'}]}>
|
||||
<TouchableOpacity
|
||||
style={styles.wrapper}
|
||||
testID="touchable_delay_events_button"
|
||||
onPress={() => this._appendEvent('press')}
|
||||
delayPressIn={400}
|
||||
onPressIn={() => this._appendEvent('pressIn - 400ms delay')}
|
||||
delayPressOut={1000}
|
||||
onPressOut={() => this._appendEvent('pressOut - 1000ms delay')}
|
||||
delayLongPress={800}
|
||||
onLongPress={() => this._appendEvent('longPress - 800ms delay')}>
|
||||
<Text style={styles.button}>
|
||||
Press Me
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={styles.wrapper}
|
||||
testID="touchable_delay_events_button"
|
||||
onPress={() => this._appendEvent('press')}
|
||||
delayPressIn={400}
|
||||
onPressIn={() => this._appendEvent('pressIn - 400ms delay')}
|
||||
delayPressOut={1000}
|
||||
onPressOut={() => this._appendEvent('pressOut - 1000ms delay')}
|
||||
delayLongPress={800}
|
||||
onLongPress={() => this._appendEvent('longPress - 800ms delay')}>
|
||||
<Text style={styles.button}>
|
||||
Press Me
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.eventLogBox} testID="touchable_delay_events_console">
|
||||
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
|
||||
</View>
|
||||
@@ -225,148 +198,6 @@ var TouchableDelayEvents = React.createClass({
|
||||
},
|
||||
});
|
||||
|
||||
var ForceTouchExample = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
force: 0,
|
||||
};
|
||||
},
|
||||
_renderConsoleText: function() {
|
||||
return View.forceTouchAvailable ?
|
||||
'Force: ' + this.state.force.toFixed(3) :
|
||||
'3D Touch is not available on this device';
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<View testID="touchable_3dtouch_event">
|
||||
<View style={styles.forceTouchBox} testID="touchable_3dtouch_output">
|
||||
<Text>{this._renderConsoleText()}</Text>
|
||||
</View>
|
||||
<View style={[styles.row, {justifyContent: 'center'}]}>
|
||||
<View
|
||||
style={styles.wrapper}
|
||||
testID="touchable_3dtouch_button"
|
||||
onStartShouldSetResponder={() => true}
|
||||
onResponderMove={(event) => this.setState({force: event.nativeEvent.force})}
|
||||
onResponderRelease={(event) => this.setState({force: 0})}>
|
||||
<Text style={styles.button}>
|
||||
Press Me
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var TouchableHitSlop = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
timesPressed: 0,
|
||||
};
|
||||
},
|
||||
onPress: function() {
|
||||
this.setState({
|
||||
timesPressed: this.state.timesPressed + 1,
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
var log = '';
|
||||
if (this.state.timesPressed > 1) {
|
||||
log = this.state.timesPressed + 'x onPress';
|
||||
} else if (this.state.timesPressed > 0) {
|
||||
log = 'onPress';
|
||||
}
|
||||
|
||||
return (
|
||||
<View testID="touchable_hit_slop">
|
||||
<View style={[styles.row, {justifyContent: 'center'}]}>
|
||||
<TouchableOpacity
|
||||
onPress={this.onPress}
|
||||
style={styles.hitSlopWrapper}
|
||||
hitSlop={{top: 30, bottom: 30, left: 60, right: 60}}
|
||||
testID="touchable_hit_slop_button">
|
||||
<Text style={styles.hitSlopButton}>
|
||||
Press Outside This View
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.logBox}>
|
||||
<Text>
|
||||
{log}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var TouchableDisabled = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<TouchableOpacity disabled={true} style={[styles.row, styles.block]}>
|
||||
<Text style={styles.disabledButton}>Disabled TouchableOpacity</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity disabled={false} style={[styles.row, styles.block]}>
|
||||
<Text style={styles.button}>Enabled TouchableOpacity</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableHighlight
|
||||
activeOpacity={1}
|
||||
disabled={true}
|
||||
animationVelocity={0}
|
||||
underlayColor="rgb(210, 230, 255)"
|
||||
style={[styles.row, styles.block]}
|
||||
onPress={() => console.log('custom THW text - highlight')}>
|
||||
<Text style={styles.disabledButton}>
|
||||
Disabled TouchableHighlight
|
||||
</Text>
|
||||
</TouchableHighlight>
|
||||
|
||||
<TouchableHighlight
|
||||
activeOpacity={1}
|
||||
animationVelocity={0}
|
||||
underlayColor="rgb(210, 230, 255)"
|
||||
style={[styles.row, styles.block]}
|
||||
onPress={() => console.log('custom THW text - highlight')}>
|
||||
<Text style={styles.button}>
|
||||
Disabled TouchableHighlight
|
||||
</Text>
|
||||
</TouchableHighlight>
|
||||
|
||||
{Platform.OS === 'android' &&
|
||||
<TouchableNativeFeedback
|
||||
style={[styles.row, styles.block]}
|
||||
onPress={() => console.log('custom TNF has been clicked')}
|
||||
background={TouchableNativeFeedback.SelectableBackground()}>
|
||||
<View>
|
||||
<Text style={[styles.button, styles.nativeFeedbackButton]}>
|
||||
Enabled TouchableNativeFeedback
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
}
|
||||
|
||||
{Platform.OS === 'android' &&
|
||||
<TouchableNativeFeedback
|
||||
disabled={true}
|
||||
style={[styles.row, styles.block]}
|
||||
onPress={() => console.log('custom TNF has been clicked')}
|
||||
background={TouchableNativeFeedback.SelectableBackground()}>
|
||||
<View>
|
||||
<Text style={[styles.disabledButton, styles.nativeFeedbackButton]}>
|
||||
Disabled TouchableNativeFeedback
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var heartImage = {uri: 'https://pbs.twimg.com/media/BlXBfT3CQAA6cVZ.png:small'};
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
@@ -385,23 +216,9 @@ var styles = StyleSheet.create({
|
||||
text: {
|
||||
fontSize: 16,
|
||||
},
|
||||
block: {
|
||||
padding: 10,
|
||||
},
|
||||
button: {
|
||||
color: '#007AFF',
|
||||
},
|
||||
disabledButton: {
|
||||
color: '#007AFF',
|
||||
opacity: 0.5,
|
||||
},
|
||||
nativeFeedbackButton: {
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
},
|
||||
hitSlopButton: {
|
||||
color: 'white',
|
||||
},
|
||||
wrapper: {
|
||||
borderRadius: 8,
|
||||
},
|
||||
@@ -409,10 +226,6 @@ var styles = StyleSheet.create({
|
||||
borderRadius: 8,
|
||||
padding: 6,
|
||||
},
|
||||
hitSlopWrapper: {
|
||||
backgroundColor: 'red',
|
||||
marginVertical: 30,
|
||||
},
|
||||
logBox: {
|
||||
padding: 20,
|
||||
margin: 10,
|
||||
@@ -428,14 +241,6 @@ var styles = StyleSheet.create({
|
||||
borderColor: '#f0f0f0',
|
||||
backgroundColor: '#f9f9f9',
|
||||
},
|
||||
forceTouchBox: {
|
||||
padding: 10,
|
||||
margin: 10,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderColor: '#f0f0f0',
|
||||
backgroundColor: '#f9f9f9',
|
||||
alignItems: 'center',
|
||||
},
|
||||
textBlock: {
|
||||
fontWeight: '500',
|
||||
color: 'blue',
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1300627E1B59179B0043FE5A /* RCTGzipTests.m */; };
|
||||
13129DD41C85F87C007D611C /* RCTModuleInitNotificationRaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13129DD31C85F87C007D611C /* RCTModuleInitNotificationRaceTests.m */; };
|
||||
1323F1891C04AB9F0091BED0 /* bunny.png in Resources */ = {isa = PBXBuildFile; fileRef = 1323F1851C04AB9F0091BED0 /* bunny.png */; };
|
||||
1323F18A1C04AB9F0091BED0 /* flux@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1323F1861C04AB9F0091BED0 /* flux@3x.png */; };
|
||||
1323F18B1C04AB9F0091BED0 /* hawk.png in Resources */ = {isa = PBXBuildFile; fileRef = 1323F1871C04AB9F0091BED0 /* hawk.png */; };
|
||||
@@ -19,7 +18,6 @@
|
||||
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; };
|
||||
134454601AAFCABD003F0779 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1344545A1AAFCAAE003F0779 /* libRCTAdSupport.a */; };
|
||||
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 134A8A251AACED6A00945AAE /* libRCTGeolocation.a */; };
|
||||
134CB92A1C85A38800265FA6 /* RCTModuleInitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 134CB9291C85A38800265FA6 /* RCTModuleInitTests.m */; };
|
||||
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A161B53CD440074A87E /* RCTShadowViewTests.m */; };
|
||||
138DEE241B9EDFB6007F4EA5 /* libRCTCameraRoll.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 138DEE091B9EDDDB007F4EA5 /* libRCTCameraRoll.a */; };
|
||||
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */; };
|
||||
@@ -29,7 +27,6 @@
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
13B6C1A31C34225900D3FAF5 /* RCTURLUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */; };
|
||||
13BCE84F1C9C209600DD7AAD /* RCTComponentPropsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BCE84E1C9C209600DD7AAD /* RCTComponentPropsTests.m */; };
|
||||
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DB03471B5D2ED500C27245 /* RCTJSONTests.m */; };
|
||||
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */; };
|
||||
143BC5A11B21E45C00462512 /* UIExplorerSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */; };
|
||||
@@ -181,7 +178,6 @@
|
||||
/* Begin PBXFileReference section */
|
||||
004D289E1AAF61C70097A701 /* UIExplorerUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIExplorerUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1300627E1B59179B0043FE5A /* RCTGzipTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGzipTests.m; sourceTree = "<group>"; };
|
||||
13129DD31C85F87C007D611C /* RCTModuleInitNotificationRaceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleInitNotificationRaceTests.m; sourceTree = "<group>"; };
|
||||
1323F1851C04AB9F0091BED0 /* bunny.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bunny.png; sourceTree = "<group>"; };
|
||||
1323F1861C04AB9F0091BED0 /* flux@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flux@3x.png"; sourceTree = "<group>"; };
|
||||
1323F1871C04AB9F0091BED0 /* hawk.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hawk.png; sourceTree = "<group>"; };
|
||||
@@ -192,7 +188,6 @@
|
||||
134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = ../../Libraries/AdSupport/RCTAdSupport.xcodeproj; sourceTree = "<group>"; };
|
||||
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
|
||||
134CB9291C85A38800265FA6 /* RCTModuleInitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleInitTests.m; sourceTree = "<group>"; };
|
||||
138D6A161B53CD440074A87E /* RCTShadowViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTShadowViewTests.m; sourceTree = "<group>"; };
|
||||
138DEE021B9EDDDB007F4EA5 /* RCTCameraRoll.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTCameraRoll.xcodeproj; path = ../../Libraries/CameraRoll/RCTCameraRoll.xcodeproj; sourceTree = "<group>"; };
|
||||
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleMethodTests.m; sourceTree = "<group>"; };
|
||||
@@ -205,7 +200,6 @@
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = UIExplorer/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = UIExplorer/main.m; sourceTree = "<group>"; };
|
||||
13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTURLUtilsTests.m; sourceTree = "<group>"; };
|
||||
13BCE84E1C9C209600DD7AAD /* RCTComponentPropsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTComponentPropsTests.m; sourceTree = "<group>"; };
|
||||
13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJSONTests.m; sourceTree = "<group>"; };
|
||||
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMethodArgumentTests.m; sourceTree = "<group>"; };
|
||||
@@ -428,12 +422,9 @@
|
||||
144D21231B2204C5006DB32B /* RCTImageUtilTests.m */,
|
||||
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */,
|
||||
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */,
|
||||
134CB9291C85A38800265FA6 /* RCTModuleInitTests.m */,
|
||||
13129DD31C85F87C007D611C /* RCTModuleInitNotificationRaceTests.m */,
|
||||
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */,
|
||||
138D6A161B53CD440074A87E /* RCTShadowViewTests.m */,
|
||||
1497CFAB1B21F5E400C1F8F2 /* RCTUIManagerTests.m */,
|
||||
13BCE84E1C9C209600DD7AAD /* RCTComponentPropsTests.m */,
|
||||
143BC57E1B21E18100462512 /* Info.plist */,
|
||||
14D6D7101B220EB3001FB087 /* libOCMock.a */,
|
||||
14D6D7011B220AE3001FB087 /* OCMock */,
|
||||
@@ -886,15 +877,12 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1497CFB01B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m in Sources */,
|
||||
13BCE84F1C9C209600DD7AAD /* RCTComponentPropsTests.m in Sources */,
|
||||
144D21241B2204C5006DB32B /* RCTImageUtilTests.m in Sources */,
|
||||
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.m in Sources */,
|
||||
1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */,
|
||||
1497CFAF1B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m in Sources */,
|
||||
1497CFAE1B21F5E400C1F8F2 /* RCTJSCExecutorTests.m in Sources */,
|
||||
13129DD41C85F87C007D611C /* RCTModuleInitNotificationRaceTests.m in Sources */,
|
||||
1497CFAD1B21F5E400C1F8F2 /* RCTBridgeTests.m in Sources */,
|
||||
134CB92A1C85A38800265FA6 /* RCTModuleInitTests.m in Sources */,
|
||||
1497CFB11B21F5E400C1F8F2 /* RCTEventDispatcherTests.m in Sources */,
|
||||
1497CFB31B21F5E400C1F8F2 /* RCTUIManagerTests.m in Sources */,
|
||||
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */,
|
||||
@@ -1028,7 +1016,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.react.uiapp;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.internal.uiexplorer.local;
|
||||
PRODUCT_NAME = UIExplorer;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WARNING_CFLAGS = (
|
||||
@@ -1054,7 +1042,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.react.uiapp;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.internal.uiexplorer.local;
|
||||
PRODUCT_NAME = UIExplorer;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WARNING_CFLAGS = (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
version = "1.8">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
@@ -51,10 +51,10 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -90,11 +90,11 @@
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
@@ -113,10 +113,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTJavaScriptLoader.h"
|
||||
#import "RCTLinkingManager.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@interface AppDelegate() <RCTBridgeDelegate>
|
||||
@@ -24,22 +23,15 @@
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
_bridge = [[RCTBridge alloc] initWithDelegate:self
|
||||
launchOptions:launchOptions];
|
||||
|
||||
// Appetizer.io params check
|
||||
NSDictionary *initProps = nil;
|
||||
NSString *_routeUri = [[NSUserDefaults standardUserDefaults] stringForKey:@"route"];
|
||||
if (_routeUri) {
|
||||
initProps = @{@"exampleFromAppetizeParams":
|
||||
[NSString stringWithFormat:@"rnuiexplorer://example/%@Example", _routeUri]};
|
||||
}
|
||||
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:_bridge
|
||||
moduleName:@"UIExplorerApp"
|
||||
initialProperties:initProps];
|
||||
initialProperties:nil];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
@@ -88,14 +80,6 @@
|
||||
return sourceURL;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
|
||||
{
|
||||
return [RCTLinkingManager application:application openURL:url
|
||||
sourceApplication:sourceApplication annotation:annotation];
|
||||
}
|
||||
|
||||
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
||||
withBlock:(RCTSourceLoadBlock)loadCallback
|
||||
{
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "uie_comment_highlighted@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 403 B |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "uie_comment_normal@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 420 B After Width: | Height: | Size: 420 B |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "uie_thumb_normal@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 850 B After Width: | Height: | Size: 850 B |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "uie_thumb_selected@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -18,28 +18,10 @@
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>com.reactjs.ios</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>rnuiexplorer</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>You need to add NSLocationWhenInUseUsageDescription key in Info.plist to enable geolocation, otherwise it is going to *fail silently*!</string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
@@ -56,5 +38,11 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/-->
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
export type UIExplorerListWithFilterAction = {
|
||||
type: 'UIExplorerListWithFilterAction',
|
||||
filter: ?string;
|
||||
};
|
||||
|
||||
export type UIExplorerExampleAction = {
|
||||
type: 'UIExplorerExampleAction',
|
||||
openExample: string;
|
||||
};
|
||||
|
||||
import type {BackAction} from 'NavigationRootContainer';
|
||||
|
||||
export type UIExplorerAction = BackAction | UIExplorerListWithFilterAction | UIExplorerExampleAction;
|
||||
|
||||
function ExampleListWithFilter(filter: ?string): UIExplorerListWithFilterAction {
|
||||
return {
|
||||
type: 'UIExplorerListWithFilterAction',
|
||||
filter,
|
||||
};
|
||||
}
|
||||
|
||||
function ExampleAction(openExample: string): UIExplorerExampleAction {
|
||||
return {
|
||||
type: 'UIExplorerExampleAction',
|
||||
openExample,
|
||||
};
|
||||
}
|
||||
|
||||
const UIExplorerActions = {
|
||||
ExampleListWithFilter,
|
||||
ExampleAction,
|
||||
};
|
||||
|
||||
module.exports = UIExplorerActions;
|
||||
@@ -16,157 +16,86 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
BackAndroid,
|
||||
Dimensions,
|
||||
DrawerLayoutAndroid,
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
ToolbarAndroid,
|
||||
View,
|
||||
StatusBar,
|
||||
} = React;
|
||||
const {
|
||||
RootContainer: NavigationRootContainer,
|
||||
} = NavigationExperimental;
|
||||
const UIExplorerExampleList = require('./UIExplorerExampleList');
|
||||
const UIExplorerList = require('./UIExplorerList');
|
||||
const UIExplorerNavigationReducer = require('./UIExplorerNavigationReducer');
|
||||
const UIExplorerStateTitleMap = require('./UIExplorerStateTitleMap');
|
||||
const URIActionMap = require('./URIActionMap');
|
||||
var UIExplorerList = require('./UIExplorerList.android');
|
||||
|
||||
var DRAWER_WIDTH_LEFT = 56;
|
||||
|
||||
type Props = {
|
||||
exampleFromAppetizeParams: string,
|
||||
};
|
||||
|
||||
type State = {
|
||||
initialExampleUri: ?string,
|
||||
};
|
||||
|
||||
class UIExplorerApp extends React.Component {
|
||||
_handleOpenInitialExample: Function;
|
||||
state: State;
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this._handleOpenInitialExample = this._handleOpenInitialExample.bind(this);
|
||||
this.state = {
|
||||
initialExampleUri: props.exampleFromAppetizeParams,
|
||||
var UIExplorerApp = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
example: this._getUIExplorerHome(),
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount() {
|
||||
BackAndroid.addEventListener('hardwareBackPress', this._handleBackButtonPress.bind(this));
|
||||
}
|
||||
_getUIExplorerHome: function() {
|
||||
return {
|
||||
title: 'UIExplorer',
|
||||
component: this._renderHome(),
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
// There's a race condition if we try to navigate to the specified example
|
||||
// from the initial props at the same time the navigation logic is setting
|
||||
// up the initial navigation state. This hack adds a delay to avoid this
|
||||
// scenario. So after the initial example list is shown, we then transition
|
||||
// to the initial example.
|
||||
setTimeout(this._handleOpenInitialExample, 500);
|
||||
}
|
||||
componentWillMount: function() {
|
||||
BackAndroid.addEventListener('hardwareBackPress', this._handleBackButtonPress);
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
persistenceKey="UIExplorerStateNavState"
|
||||
ref={navRootRef => { this._navigationRootRef = navRootRef; }}
|
||||
reducer={UIExplorerNavigationReducer}
|
||||
renderNavigation={this._renderApp.bind(this)}
|
||||
linkingActionMap={URIActionMap}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_handleOpenInitialExample() {
|
||||
if (this.state.initialExampleUri) {
|
||||
const exampleAction = URIActionMap(this.state.initialExampleUri);
|
||||
if (exampleAction && this._navigationRootRef) {
|
||||
this._navigationRootRef.handleNavigation(exampleAction);
|
||||
}
|
||||
}
|
||||
this.setState({initialExampleUri: null});
|
||||
}
|
||||
|
||||
_renderApp(navigationState, onNavigate) {
|
||||
if (!navigationState) {
|
||||
return null;
|
||||
}
|
||||
render: function() {
|
||||
return (
|
||||
<DrawerLayoutAndroid
|
||||
drawerPosition={DrawerLayoutAndroid.positions.Left}
|
||||
drawerWidth={Dimensions.get('window').width - DRAWER_WIDTH_LEFT}
|
||||
keyboardDismissMode="on-drag"
|
||||
onDrawerOpen={() => {
|
||||
this._overrideBackPressForDrawerLayout = true;
|
||||
}}
|
||||
onDrawerClose={() => {
|
||||
this._overrideBackPressForDrawerLayout = false;
|
||||
}}
|
||||
ref={(drawer) => { this.drawer = drawer; }}
|
||||
renderNavigationView={this._renderDrawerContent.bind(this, onNavigate)}
|
||||
statusBarBackgroundColor="#589c90">
|
||||
{this._renderNavigation(navigationState, onNavigate)}
|
||||
renderNavigationView={this._renderNavigationView}>
|
||||
{this._renderNavigation()}
|
||||
</DrawerLayoutAndroid>
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_renderDrawerContent(onNavigate) {
|
||||
_renderNavigationView: function() {
|
||||
return (
|
||||
<View style={styles.drawerContentWrapper}>
|
||||
<UIExplorerExampleList
|
||||
list={UIExplorerList}
|
||||
displayTitleRow={true}
|
||||
disableSearch={true}
|
||||
onNavigate={(action) => {
|
||||
this.drawer && this.drawer.closeDrawer();
|
||||
onNavigate(action);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<UIExplorerList
|
||||
onSelectExample={this.onSelectExample}
|
||||
isInDrawer={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_renderNavigation(navigationState, onNavigate) {
|
||||
if (navigationState.externalExample) {
|
||||
var Component = UIExplorerList.Modules[navigationState.externalExample];
|
||||
return (
|
||||
<Component
|
||||
onExampleExit={() => {
|
||||
onNavigate(NavigationRootContainer.getBackAction());
|
||||
}}
|
||||
ref={(example) => { this._exampleRef = example; }}
|
||||
/>
|
||||
);
|
||||
onSelectExample: function(example) {
|
||||
this.drawer.closeDrawer();
|
||||
if (example.title === this._getUIExplorerHome().title) {
|
||||
example = this._getUIExplorerHome();
|
||||
}
|
||||
const {stack} = navigationState;
|
||||
const title = UIExplorerStateTitleMap(stack.children[stack.index]);
|
||||
const index = stack.children.length <= 1 ? 1 : stack.index;
|
||||
this.setState({
|
||||
example: example,
|
||||
});
|
||||
},
|
||||
|
||||
if (stack && stack.children[index]) {
|
||||
const {key} = stack.children[index];
|
||||
const ExampleModule = UIExplorerList.Modules[key];
|
||||
const ExampleComponent = UIExplorerExampleList.makeRenderable(ExampleModule);
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ToolbarAndroid
|
||||
logo={require('image!launcher_icon')}
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
onIconClicked={() => this.drawer.openDrawer()}
|
||||
style={styles.toolbar}
|
||||
title={title}
|
||||
_renderHome: function() {
|
||||
var onSelectExample = this.onSelectExample;
|
||||
return React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerList
|
||||
onSelectExample={onSelectExample}
|
||||
isInDrawer={false}
|
||||
/>
|
||||
<ExampleComponent
|
||||
ref={(example) => { this._exampleRef = example; }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_renderNavigation: function() {
|
||||
var Component = this.state.example.component;
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ToolbarAndroid
|
||||
@@ -174,41 +103,23 @@ class UIExplorerApp extends React.Component {
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
onIconClicked={() => this.drawer.openDrawer()}
|
||||
style={styles.toolbar}
|
||||
title={title}
|
||||
/>
|
||||
<UIExplorerExampleList
|
||||
list={UIExplorerList}
|
||||
{...stack.children[0]}
|
||||
title={this.state.example.title}
|
||||
/>
|
||||
<Component />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_handleBackButtonPress() {
|
||||
if (this._overrideBackPressForDrawerLayout) {
|
||||
// This hack is necessary because drawer layout provides an imperative API
|
||||
// with open and close methods. This code would be cleaner if the drawer
|
||||
// layout provided an `isOpen` prop and allowed us to pass a `onDrawerClose` handler.
|
||||
this.drawer && this.drawer.closeDrawer();
|
||||
_handleBackButtonPress: function() {
|
||||
if (this.state.example.title !== this._getUIExplorerHome().title) {
|
||||
this.onSelectExample(this._getUIExplorerHome());
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
this._exampleRef &&
|
||||
this._exampleRef.handleBackAction &&
|
||||
this._exampleRef.handleBackAction()
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (this._navigationRootRef) {
|
||||
return this._navigationRootRef.handleNavigation(
|
||||
NavigationRootContainer.getBackAction()
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
@@ -216,10 +127,6 @@ const styles = StyleSheet.create({
|
||||
backgroundColor: '#E9EAED',
|
||||
height: 56,
|
||||
},
|
||||
drawerContentWrapper: {
|
||||
paddingTop: StatusBar.currentHeight,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
@@ -23,188 +16,133 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const UIExplorerList = require('./UIExplorerList.ios');
|
||||
const UIExplorerExampleList = require('./UIExplorerExampleList');
|
||||
const UIExplorerNavigationReducer = require('./UIExplorerNavigationReducer');
|
||||
const UIExplorerStateTitleMap = require('./UIExplorerStateTitleMap');
|
||||
const URIActionMap = require('./URIActionMap');
|
||||
|
||||
const {
|
||||
var React = require('react-native');
|
||||
var UIExplorerList = require('./UIExplorerList.ios');
|
||||
var {
|
||||
AppRegistry,
|
||||
NavigationExperimental,
|
||||
SnapshotViewIOS,
|
||||
NavigatorIOS,
|
||||
StyleSheet,
|
||||
View,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View
|
||||
} = React;
|
||||
|
||||
const {
|
||||
CardStack: NavigationCardStack,
|
||||
Header: NavigationHeader,
|
||||
RootContainer: NavigationRootContainer,
|
||||
} = NavigationExperimental;
|
||||
var UIExplorerApp = React.createClass({
|
||||
|
||||
import type { NavigationSceneRendererProps } from 'NavigationTypeDefinition';
|
||||
|
||||
import type { UIExplorerNavigationState } from './UIExplorerNavigationReducer';
|
||||
|
||||
import type { UIExplorerExample } from './UIExplorerList.ios';
|
||||
|
||||
type Props = {
|
||||
exampleFromAppetizeParams: string,
|
||||
};
|
||||
|
||||
type State = {
|
||||
initialExampleUri: ?string,
|
||||
};
|
||||
|
||||
class UIExplorerApp extends React.Component {
|
||||
_navigationRootRef: ?NavigationRootContainer;
|
||||
_renderNavigation: Function;
|
||||
_renderOverlay: Function;
|
||||
_renderScene: Function;
|
||||
_renderCard: Function;
|
||||
_renderTitleComponent: Function;
|
||||
_handleOpenInitialExample: Function;
|
||||
state: State;
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this._handleOpenInitialExample = this._handleOpenInitialExample.bind(this);
|
||||
this.state = {
|
||||
initialExampleUri: props.exampleFromAppetizeParams,
|
||||
getInitialState: function() {
|
||||
return {
|
||||
openExternalExample: (null: ?React.Component),
|
||||
};
|
||||
}
|
||||
componentWillMount() {
|
||||
this._renderNavigation = this._renderNavigation.bind(this);
|
||||
this._renderOverlay = this._renderOverlay.bind(this);
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
this._renderTitleComponent = this._renderTitleComponent.bind(this);
|
||||
}
|
||||
componentDidMount() {
|
||||
// There's a race condition if we try to navigate to the specified example
|
||||
// from the initial props at the same time the navigation logic is setting
|
||||
// up the initial navigation state. This hack adds a delay to avoid this
|
||||
// scenario. So after the initial example list is shown, we then transition
|
||||
// to the initial example.
|
||||
setTimeout(this._handleOpenInitialExample, 500);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
persistenceKey="UIExplorerState"
|
||||
reducer={UIExplorerNavigationReducer}
|
||||
ref={navRootRef => { this._navigationRootRef = navRootRef; }}
|
||||
renderNavigation={this._renderNavigation}
|
||||
linkingActionMap={URIActionMap}
|
||||
/>
|
||||
);
|
||||
}
|
||||
_handleOpenInitialExample() {
|
||||
if (this.state.initialExampleUri) {
|
||||
const exampleAction = URIActionMap(this.state.initialExampleUri);
|
||||
if (exampleAction && this._navigationRootRef) {
|
||||
this._navigationRootRef.handleNavigation(exampleAction);
|
||||
}
|
||||
}
|
||||
this.setState({initialExampleUri: null});
|
||||
}
|
||||
_renderNavigation(navigationState: UIExplorerNavigationState, onNavigate: Function) {
|
||||
if (!navigationState) {
|
||||
return null;
|
||||
}
|
||||
if (navigationState.externalExample) {
|
||||
var Component = UIExplorerList.Modules[navigationState.externalExample];
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.openExternalExample) {
|
||||
var Example = this.state.openExternalExample;
|
||||
return (
|
||||
<Component
|
||||
<Example
|
||||
onExampleExit={() => {
|
||||
onNavigate(NavigationRootContainer.getBackAction());
|
||||
this.setState({ openExternalExample: null, });
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
const {stack} = navigationState;
|
||||
|
||||
return (
|
||||
<NavigationCardStack
|
||||
navigationState={stack}
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
renderOverlay={this._renderOverlay}
|
||||
renderScene={this._renderScene}
|
||||
initialRoute={{
|
||||
title: 'UIExplorer',
|
||||
component: UIExplorerList,
|
||||
passProps: {
|
||||
onExternalExampleRequested: (example) => {
|
||||
this.setState({ openExternalExample: example, });
|
||||
},
|
||||
}
|
||||
}}
|
||||
itemWrapperStyle={styles.itemWrapper}
|
||||
tintColor="#008888"
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
_renderOverlay(props: NavigationSceneRendererProps): ReactElement {
|
||||
return (
|
||||
<NavigationHeader
|
||||
{...props}
|
||||
renderTitleComponent={this._renderTitleComponent}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderTitleComponent(props: NavigationSceneRendererProps): ReactElement {
|
||||
return (
|
||||
<NavigationHeader.Title>
|
||||
{UIExplorerStateTitleMap(props.scene.navigationState)}
|
||||
</NavigationHeader.Title>
|
||||
);
|
||||
}
|
||||
|
||||
_renderScene(props: NavigationSceneRendererProps): ?ReactElement {
|
||||
const state = props.scene.navigationState;
|
||||
if (state.key === 'AppList') {
|
||||
return (
|
||||
<UIExplorerExampleList
|
||||
list={UIExplorerList}
|
||||
style={styles.exampleContainer}
|
||||
{...state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const Example = UIExplorerList.Modules[state.key];
|
||||
if (Example) {
|
||||
const Component = UIExplorerExampleList.makeRenderable(Example);
|
||||
return (
|
||||
<View style={styles.exampleContainer}>
|
||||
<Component />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
exampleContainer: {
|
||||
flex: 1,
|
||||
paddingTop: NavigationHeader.HEIGHT,
|
||||
itemWrapper: {
|
||||
backgroundColor: '#eaeaea',
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('SetPropertiesExampleApp', () => require('./SetPropertiesExampleApp'));
|
||||
AppRegistry.registerComponent('RootViewSizeFlexibilityExampleApp', () => require('./RootViewSizeFlexibilityExampleApp'));
|
||||
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
||||
|
||||
// Register suitable examples for snapshot tests
|
||||
UIExplorerList.ComponentExamples.concat(UIExplorerList.APIExamples).forEach((Example: UIExplorerExample) => {
|
||||
const ExampleModule = Example.module;
|
||||
if (ExampleModule.displayName) {
|
||||
var Snapshotter = React.createClass({
|
||||
render: function() {
|
||||
var Renderable = UIExplorerExampleList.makeRenderable(ExampleModule);
|
||||
return (
|
||||
<SnapshotViewIOS>
|
||||
<Renderable />
|
||||
</SnapshotViewIOS>
|
||||
);
|
||||
},
|
||||
});
|
||||
AppRegistry.registerComponent(ExampleModule.displayName, () => Snapshotter);
|
||||
bigContainer: {
|
||||
flex: 1,
|
||||
height: 60,
|
||||
backgroundColor: 'gray',
|
||||
},
|
||||
smallContainer: {
|
||||
flex: 1,
|
||||
height: 40,
|
||||
backgroundColor: 'gray',
|
||||
},
|
||||
center: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
whiteText: {
|
||||
color: 'white',
|
||||
}
|
||||
});
|
||||
|
||||
var SetPropertiesExampleApp = React.createClass({
|
||||
|
||||
render: function() {
|
||||
var wrapperStyle = {
|
||||
backgroundColor: this.props.color,
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={wrapperStyle}>
|
||||
<Text>
|
||||
Embedded React Native view
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var RootViewSizeFlexibilityExampleApp = React.createClass({
|
||||
|
||||
getInitialState: function () {
|
||||
return { toggled: false };
|
||||
},
|
||||
|
||||
_onPressButton: function() {
|
||||
this.setState({ toggled: !this.state.toggled });
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var viewStyle = this.state.toggled ? styles.bigContainer : styles.smallContainer;
|
||||
|
||||
return (
|
||||
<TouchableHighlight onPress={this._onPressButton}>
|
||||
<View style={viewStyle}>
|
||||
<View style={styles.center}>
|
||||
<Text style={styles.whiteText}>
|
||||
React Native Button
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('SetPropertiesExampleApp', () => SetPropertiesExampleApp);
|
||||
AppRegistry.registerComponent('RootViewSizeFlexibilityExampleApp', () => RootViewSizeFlexibilityExampleApp);
|
||||
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
||||
UIExplorerList.registerComponents();
|
||||
|
||||
module.exports = UIExplorerApp;
|
||||
|
||||
@@ -1,218 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const UIExplorerActions = require('./UIExplorerActions');
|
||||
const {
|
||||
ListView,
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
const createExamplePage = require('./createExamplePage');
|
||||
const {
|
||||
Container: NavigationContainer,
|
||||
} = NavigationExperimental;
|
||||
|
||||
import type {
|
||||
UIExplorerExample,
|
||||
} from './UIExplorerList.ios'
|
||||
|
||||
const ds = new ListView.DataSource({
|
||||
rowHasChanged: (r1, r2) => r1 !== r2,
|
||||
sectionHeaderHasChanged: (h1, h2) => h1 !== h2,
|
||||
});
|
||||
|
||||
class UIExplorerExampleList extends React.Component {
|
||||
constuctor(props: {
|
||||
disableTitleRow: ?boolean,
|
||||
onNavigate: Function,
|
||||
filter: ?string,
|
||||
list: {
|
||||
ComponentExamples: Array<UIExplorerExample>,
|
||||
APIExamples: Array<UIExplorerExample>,
|
||||
},
|
||||
style: ?any,
|
||||
}) {
|
||||
|
||||
}
|
||||
render(): ?ReactElement {
|
||||
const filterText = this.props.filter || '';
|
||||
const filterRegex = new RegExp(String(filterText), 'i');
|
||||
const filter = (example) => filterRegex.test(example.module.title);
|
||||
|
||||
const dataSource = ds.cloneWithRowsAndSections({
|
||||
components: this.props.list.ComponentExamples.filter(filter),
|
||||
apis: this.props.list.APIExamples.filter(filter),
|
||||
});
|
||||
return (
|
||||
<View style={[styles.listContainer, this.props.style]}>
|
||||
{this._renderTitleRow()}
|
||||
{this._renderTextInput()}
|
||||
<ListView
|
||||
style={styles.list}
|
||||
dataSource={dataSource}
|
||||
renderRow={this._renderExampleRow.bind(this)}
|
||||
renderSectionHeader={this._renderSectionHeader}
|
||||
keyboardShouldPersistTaps={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
keyboardDismissMode="on-drag"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_renderTitleRow(): ?ReactElement {
|
||||
if (!this.props.displayTitleRow) {
|
||||
return null;
|
||||
}
|
||||
return this._renderRow(
|
||||
'UIExplorer',
|
||||
'React Native Examples',
|
||||
'home_key',
|
||||
() => {
|
||||
this.props.onNavigate(
|
||||
UIExplorerActions.ExampleListWithFilter('')
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_renderTextInput(): ?ReactElement {
|
||||
if (this.props.disableSearch) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<View style={styles.searchRow}>
|
||||
<TextInput
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
clearButtonMode="always"
|
||||
onChangeText={text => {
|
||||
this.props.onNavigate(UIExplorerActions.ExampleListWithFilter(text));
|
||||
}}
|
||||
placeholder="Search..."
|
||||
style={[styles.searchTextInput, this.props.searchTextInputStyle]}
|
||||
testID="explorer_search"
|
||||
value={this.props.filter}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_renderSectionHeader(data: any, section: string): ?ReactElement {
|
||||
return (
|
||||
<Text style={styles.sectionHeader}>
|
||||
{section.toUpperCase()}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
_renderExampleRow(example: {key: string, module: Object}): ?ReactElement {
|
||||
return this._renderRow(
|
||||
example.module.title,
|
||||
example.module.description,
|
||||
example.key,
|
||||
() => this._handleRowPress(example.key)
|
||||
);
|
||||
}
|
||||
|
||||
_renderRow(title: string, description: string, key: ?string, handler: ?Function): ?ReactElement {
|
||||
return (
|
||||
<View key={key || title}>
|
||||
<TouchableHighlight onPress={handler}>
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowTitleText}>
|
||||
{title}
|
||||
</Text>
|
||||
<Text style={styles.rowDetailText}>
|
||||
{description}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<View style={styles.separator} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_handleRowPress(exampleKey: string): void {
|
||||
this.props.onNavigate(UIExplorerActions.ExampleAction(exampleKey))
|
||||
}
|
||||
}
|
||||
|
||||
function makeRenderable(example: any): ReactClass<any> {
|
||||
return example.examples ?
|
||||
createExamplePage(null, example) :
|
||||
example;
|
||||
}
|
||||
|
||||
UIExplorerExampleList = NavigationContainer.create(UIExplorerExampleList);
|
||||
UIExplorerExampleList.makeRenderable = makeRenderable;
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
listContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
list: {
|
||||
backgroundColor: '#eeeeee',
|
||||
},
|
||||
sectionHeader: {
|
||||
padding: 5,
|
||||
fontWeight: '500',
|
||||
fontSize: 11,
|
||||
},
|
||||
group: {
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
row: {
|
||||
backgroundColor: 'white',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 15,
|
||||
paddingVertical: 8,
|
||||
},
|
||||
separator: {
|
||||
height: StyleSheet.hairlineWidth,
|
||||
backgroundColor: '#bbbbbb',
|
||||
marginLeft: 15,
|
||||
},
|
||||
rowTitleText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
rowDetailText: {
|
||||
fontSize: 15,
|
||||
color: '#888888',
|
||||
lineHeight: 20,
|
||||
},
|
||||
searchRow: {
|
||||
backgroundColor: '#eeeeee',
|
||||
padding: 10,
|
||||
},
|
||||
searchTextInput: {
|
||||
backgroundColor: 'white',
|
||||
borderColor: '#cccccc',
|
||||
borderRadius: 3,
|
||||
borderWidth: 1,
|
||||
paddingLeft: 8,
|
||||
height: 35,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = UIExplorerExampleList;
|
||||
@@ -15,181 +15,97 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
var UIExplorerListBase = require('./UIExplorerListBase');
|
||||
|
||||
export type UIExplorerExample = {
|
||||
key: string;
|
||||
module: React.Component;
|
||||
var COMPONENTS = [
|
||||
require('./ImageExample'),
|
||||
require('./ListViewExample'),
|
||||
require('./ProgressBarAndroidExample'),
|
||||
require('./ScrollViewSimpleExample'),
|
||||
require('./SwitchExample'),
|
||||
require('./RefreshControlExample'),
|
||||
require('./PickerAndroidExample'),
|
||||
require('./PullToRefreshViewAndroidExample.android'),
|
||||
require('./TextExample.android'),
|
||||
require('./TextInputExample.android'),
|
||||
require('./ToolbarAndroidExample'),
|
||||
require('./TouchableExample'),
|
||||
require('./ViewExample'),
|
||||
require('./ViewPagerAndroidExample.android'),
|
||||
require('./WebViewExample'),
|
||||
];
|
||||
|
||||
var APIS = [
|
||||
require('./AccessibilityAndroidExample.android'),
|
||||
require('./AlertExample').AlertExample,
|
||||
require('./BorderExample'),
|
||||
require('./CameraRollExample'),
|
||||
require('./ClipboardExample'),
|
||||
require('./GeolocationExample'),
|
||||
require('./IntentAndroidExample.android'),
|
||||
require('./LayoutEventsExample'),
|
||||
require('./LayoutExample'),
|
||||
require('./NetInfoExample'),
|
||||
require('./PanResponderExample'),
|
||||
require('./PointerEventsExample'),
|
||||
require('./TimerExample'),
|
||||
require('./ToastAndroidExample.android'),
|
||||
require('./XHRExample'),
|
||||
];
|
||||
|
||||
type Props = {
|
||||
onSelectExample: Function,
|
||||
isInDrawer: bool,
|
||||
};
|
||||
|
||||
var ComponentExamples: Array<UIExplorerExample> = [
|
||||
{
|
||||
key: 'SliderExample',
|
||||
module: require('./SliderExample'),
|
||||
},
|
||||
{
|
||||
key: 'ImageExample',
|
||||
module: require('./ImageExample'),
|
||||
},
|
||||
{
|
||||
key: 'ListViewExample',
|
||||
module: require('./ListViewExample'),
|
||||
},
|
||||
{
|
||||
key: 'ModalExample',
|
||||
module: require('./ModalExample'),
|
||||
},
|
||||
{
|
||||
key: 'PickerAndroidExample',
|
||||
module: require('./PickerAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'ProgressBarAndroidExample',
|
||||
module: require('./ProgressBarAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'RefreshControlExample',
|
||||
module: require('./RefreshControlExample'),
|
||||
},
|
||||
{
|
||||
key: 'ScrollViewSimpleExample',
|
||||
module: require('./ScrollViewSimpleExample'),
|
||||
},
|
||||
{
|
||||
key: 'StatusBarExample',
|
||||
module: require('./StatusBarExample'),
|
||||
},
|
||||
{
|
||||
key: 'SwitchExample',
|
||||
module: require('./SwitchExample'),
|
||||
},
|
||||
{
|
||||
key: 'TextExample',
|
||||
module: require('./TextExample'),
|
||||
},
|
||||
{
|
||||
key: 'TextInputExample',
|
||||
module: require('./TextInputExample'),
|
||||
},
|
||||
{
|
||||
key: 'ToolbarAndroidExample',
|
||||
module: require('./ToolbarAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'TouchableExample',
|
||||
module: require('./TouchableExample'),
|
||||
},
|
||||
{
|
||||
key: 'ViewExample',
|
||||
module: require('./ViewExample'),
|
||||
},
|
||||
{
|
||||
key: 'ViewPagerAndroidExample',
|
||||
module: require('./ViewPagerAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'WebViewExample',
|
||||
module: require('./WebViewExample'),
|
||||
},
|
||||
];
|
||||
class UIExplorerList extends React.Component {
|
||||
props: Props;
|
||||
|
||||
const APIExamples = [
|
||||
{
|
||||
key: 'AccessibilityAndroidExample',
|
||||
module: require('./AccessibilityAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'AlertExample',
|
||||
module: require('./AlertExample').AlertExample,
|
||||
},
|
||||
{
|
||||
key: 'AppStateExample',
|
||||
module: require('./AppStateExample'),
|
||||
},
|
||||
{
|
||||
key: 'BorderExample',
|
||||
module: require('./BorderExample'),
|
||||
},
|
||||
{
|
||||
key: 'CameraRollExample',
|
||||
module: require('./CameraRollExample'),
|
||||
},
|
||||
{
|
||||
key: 'ClipboardExample',
|
||||
module: require('./ClipboardExample'),
|
||||
},
|
||||
{
|
||||
key: 'DatePickerAndroidExample',
|
||||
module: require('./DatePickerAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'GeolocationExample',
|
||||
module: require('./GeolocationExample'),
|
||||
},
|
||||
{
|
||||
key: 'ImageEditingExample',
|
||||
module: require('./ImageEditingExample'),
|
||||
},
|
||||
{
|
||||
key: 'LayoutEventsExample',
|
||||
module: require('./LayoutEventsExample'),
|
||||
},
|
||||
{
|
||||
key: 'LinkingExample',
|
||||
module: require('./LinkingExample'),
|
||||
},
|
||||
{
|
||||
key: 'LayoutExample',
|
||||
module: require('./LayoutExample'),
|
||||
},
|
||||
{
|
||||
key: 'NavigationExperimentalExample',
|
||||
module: require('./NavigationExperimental/NavigationExperimentalExample'),
|
||||
},
|
||||
{
|
||||
key: 'NetInfoExample',
|
||||
module: require('./NetInfoExample'),
|
||||
},
|
||||
{
|
||||
key: 'PanResponderExample',
|
||||
module: require('./PanResponderExample'),
|
||||
},
|
||||
{
|
||||
key: 'PointerEventsExample',
|
||||
module: require('./PointerEventsExample'),
|
||||
},
|
||||
{
|
||||
key: 'TimePickerAndroidExample',
|
||||
module: require('./TimePickerAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'TimerExample',
|
||||
module: require('./TimerExample'),
|
||||
},
|
||||
{
|
||||
key: 'ToastAndroidExample',
|
||||
module: require('./ToastAndroidExample'),
|
||||
},
|
||||
{
|
||||
key: 'VibrationExample',
|
||||
module: require('./VibrationExample'),
|
||||
},
|
||||
{
|
||||
key: 'XHRExample',
|
||||
module: require('./XHRExample'),
|
||||
},
|
||||
];
|
||||
render() {
|
||||
return (
|
||||
<UIExplorerListBase
|
||||
components={COMPONENTS}
|
||||
apis={APIS}
|
||||
searchText=""
|
||||
renderAdditionalView={this.renderAdditionalView.bind(this)}
|
||||
onPressRow={this.onPressRow.bind(this)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const Modules = {};
|
||||
renderAdditionalView(renderRow, renderTextInput): React.Component {
|
||||
if (this.props.isInDrawer) {
|
||||
var homePage = renderRow({
|
||||
title: 'UIExplorer',
|
||||
description: 'List of examples',
|
||||
}, -1);
|
||||
return (
|
||||
<View>
|
||||
{homePage}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return renderTextInput(styles.searchTextInput);
|
||||
}
|
||||
|
||||
APIExamples.concat(ComponentExamples).forEach(Example => {
|
||||
Modules[Example.key] = Example.module;
|
||||
onPressRow(example: any) {
|
||||
var Component = UIExplorerListBase.makeRenderable(example);
|
||||
this.props.onSelectExample({
|
||||
title: Component.title,
|
||||
component: Component,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
searchTextInput: {
|
||||
padding: 2,
|
||||
},
|
||||
});
|
||||
|
||||
const UIExplorerList = {
|
||||
APIExamples,
|
||||
ComponentExamples,
|
||||
Modules,
|
||||
};
|
||||
|
||||
module.exports = UIExplorerList;
|
||||
|
||||
@@ -15,255 +15,148 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
export type UIExplorerExample = {
|
||||
key: string;
|
||||
module: Object;
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
Settings,
|
||||
SnapshotViewIOS,
|
||||
StyleSheet,
|
||||
} = React;
|
||||
|
||||
import type { NavigationContext } from 'NavigationContext';
|
||||
|
||||
var UIExplorerListBase = require('./UIExplorerListBase');
|
||||
|
||||
var COMPONENTS = [
|
||||
require('./ActivityIndicatorIOSExample'),
|
||||
require('./DatePickerIOSExample'),
|
||||
require('./ImageExample'),
|
||||
require('./LayoutEventsExample'),
|
||||
require('./ListViewExample'),
|
||||
require('./ListViewGridLayoutExample'),
|
||||
require('./ListViewPagingExample'),
|
||||
require('./MapViewExample'),
|
||||
require('./ModalExample'),
|
||||
require('./Navigator/NavigatorExample'),
|
||||
require('./NavigatorIOSColorsExample'),
|
||||
require('./NavigatorIOSExample'),
|
||||
require('./PickerIOSExample'),
|
||||
require('./ProgressViewIOSExample'),
|
||||
require('./RefreshControlExample'),
|
||||
require('./ScrollViewExample'),
|
||||
require('./SegmentedControlIOSExample'),
|
||||
require('./SliderIOSExample'),
|
||||
require('./SwitchExample'),
|
||||
require('./TabBarIOSExample'),
|
||||
require('./TextExample.ios'),
|
||||
require('./TextInputExample.ios'),
|
||||
require('./TouchableExample'),
|
||||
require('./TransparentHitTestExample'),
|
||||
require('./ViewExample'),
|
||||
require('./WebViewExample'),
|
||||
];
|
||||
|
||||
var APIS = [
|
||||
require('./AccessibilityIOSExample'),
|
||||
require('./ActionSheetIOSExample'),
|
||||
require('./AdSupportIOSExample'),
|
||||
require('./AlertIOSExample'),
|
||||
require('./AnimatedExample'),
|
||||
require('./AnimatedGratuitousApp/AnExApp'),
|
||||
require('./AppStateIOSExample'),
|
||||
require('./AsyncStorageExample'),
|
||||
require('./BorderExample'),
|
||||
require('./BoxShadowExample'),
|
||||
require('./CameraRollExample'),
|
||||
require('./ClipboardExample'),
|
||||
require('./GeolocationExample'),
|
||||
require('./LayoutExample'),
|
||||
require('./NetInfoExample'),
|
||||
require('./PanResponderExample'),
|
||||
require('./PointerEventsExample'),
|
||||
require('./PushNotificationIOSExample'),
|
||||
require('./RCTRootViewIOSExample'),
|
||||
require('./StatusBarIOSExample'),
|
||||
require('./TimerExample'),
|
||||
require('./TransformExample'),
|
||||
require('./VibrationIOSExample'),
|
||||
require('./XHRExample.ios'),
|
||||
require('./ImageEditingExample'),
|
||||
];
|
||||
|
||||
type Props = {
|
||||
navigator: {
|
||||
navigationContext: NavigationContext,
|
||||
push: (route: {title: string, component: ReactClass<any,any,any>}) => void,
|
||||
},
|
||||
onExternalExampleRequested: Function,
|
||||
};
|
||||
|
||||
var ComponentExamples: Array<UIExplorerExample> = [
|
||||
{
|
||||
key: 'ActivityIndicatorIOSExample',
|
||||
module: require('./ActivityIndicatorIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'DatePickerIOSExample',
|
||||
module: require('./DatePickerIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'ImageExample',
|
||||
module: require('./ImageExample'),
|
||||
},
|
||||
{
|
||||
key: 'LayoutEventsExample',
|
||||
module: require('./LayoutEventsExample'),
|
||||
},
|
||||
{
|
||||
key: 'ListViewExample',
|
||||
module: require('./ListViewExample'),
|
||||
},
|
||||
{
|
||||
key: 'ListViewGridLayoutExample',
|
||||
module: require('./ListViewGridLayoutExample'),
|
||||
},
|
||||
{
|
||||
key: 'ListViewPagingExample',
|
||||
module: require('./ListViewPagingExample'),
|
||||
},
|
||||
{
|
||||
key: 'MapViewExample',
|
||||
module: require('./MapViewExample'),
|
||||
},
|
||||
{
|
||||
key: 'ModalExample',
|
||||
module: require('./ModalExample'),
|
||||
},
|
||||
{
|
||||
key: 'NavigatorExample',
|
||||
module: require('./Navigator/NavigatorExample'),
|
||||
},
|
||||
{
|
||||
key: 'NavigatorIOSColorsExample',
|
||||
module: require('./NavigatorIOSColorsExample'),
|
||||
},
|
||||
{
|
||||
key: 'NavigatorIOSExample',
|
||||
module: require('./NavigatorIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'PickerIOSExample',
|
||||
module: require('./PickerIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'ProgressViewIOSExample',
|
||||
module: require('./ProgressViewIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'RefreshControlExample',
|
||||
module: require('./RefreshControlExample'),
|
||||
},
|
||||
{
|
||||
key: 'ScrollViewExample',
|
||||
module: require('./ScrollViewExample'),
|
||||
},
|
||||
{
|
||||
key: 'SegmentedControlIOSExample',
|
||||
module: require('./SegmentedControlIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'SliderExample',
|
||||
module: require('./SliderExample'),
|
||||
},
|
||||
{
|
||||
key: 'StatusBarExample',
|
||||
module: require('./StatusBarExample'),
|
||||
},
|
||||
{
|
||||
key: 'SwitchExample',
|
||||
module: require('./SwitchExample'),
|
||||
},
|
||||
{
|
||||
key: 'TabBarIOSExample',
|
||||
module: require('./TabBarIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'TextExample',
|
||||
module: require('./TextExample.ios'),
|
||||
},
|
||||
{
|
||||
key: 'TextInputExample',
|
||||
module: require('./TextInputExample.ios'),
|
||||
},
|
||||
{
|
||||
key: 'TouchableExample',
|
||||
module: require('./TouchableExample'),
|
||||
},
|
||||
{
|
||||
key: 'TransparentHitTestExample',
|
||||
module: require('./TransparentHitTestExample'),
|
||||
},
|
||||
{
|
||||
key: 'ViewExample',
|
||||
module: require('./ViewExample'),
|
||||
},
|
||||
{
|
||||
key: 'WebViewExample',
|
||||
module: require('./WebViewExample'),
|
||||
},
|
||||
];
|
||||
class UIExplorerList extends React.Component {
|
||||
props: Props;
|
||||
|
||||
var APIExamples: Array<UIExplorerExample> = [
|
||||
{
|
||||
key: 'AccessibilityIOSExample',
|
||||
module: require('./AccessibilityIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'ActionSheetIOSExample',
|
||||
module: require('./ActionSheetIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'AdSupportIOSExample',
|
||||
module: require('./AdSupportIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'AlertIOSExample',
|
||||
module: require('./AlertIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'AnimatedExample',
|
||||
module: require('./AnimatedExample'),
|
||||
},
|
||||
{
|
||||
key: 'AnExApp',
|
||||
module: require('./AnimatedGratuitousApp/AnExApp'),
|
||||
},
|
||||
{
|
||||
key: 'AppStateIOSExample',
|
||||
module: require('./AppStateIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'AppStateExample',
|
||||
module: require('./AppStateExample'),
|
||||
},
|
||||
{
|
||||
key: 'AsyncStorageExample',
|
||||
module: require('./AsyncStorageExample'),
|
||||
},
|
||||
{
|
||||
key: 'BorderExample',
|
||||
module: require('./BorderExample'),
|
||||
},
|
||||
{
|
||||
key: 'BoxShadowExample',
|
||||
module: require('./BoxShadowExample'),
|
||||
},
|
||||
{
|
||||
key: 'CameraRollExample',
|
||||
module: require('./CameraRollExample'),
|
||||
},
|
||||
{
|
||||
key: 'ClipboardExample',
|
||||
module: require('./ClipboardExample'),
|
||||
},
|
||||
{
|
||||
key: 'GeolocationExample',
|
||||
module: require('./GeolocationExample'),
|
||||
},
|
||||
{
|
||||
key: 'ImageEditingExample',
|
||||
module: require('./ImageEditingExample'),
|
||||
},
|
||||
{
|
||||
key: 'LayoutExample',
|
||||
module: require('./LayoutExample'),
|
||||
},
|
||||
{
|
||||
key: 'LinkingExample',
|
||||
module: require('./LinkingExample'),
|
||||
},
|
||||
{
|
||||
key: 'NavigationExperimentalExample',
|
||||
module: require('./NavigationExperimental/NavigationExperimentalExample'),
|
||||
},
|
||||
{
|
||||
key: 'NavigationExperimentalLegacyNavigatorExample',
|
||||
module: require('./NavigationExperimental/LegacyNavigator/LegacyNavigatorExample'),
|
||||
},
|
||||
{
|
||||
key: 'NetInfoExample',
|
||||
module: require('./NetInfoExample'),
|
||||
},
|
||||
{
|
||||
key: 'PanResponderExample',
|
||||
module: require('./PanResponderExample'),
|
||||
},
|
||||
{
|
||||
key: 'PointerEventsExample',
|
||||
module: require('./PointerEventsExample'),
|
||||
},
|
||||
{
|
||||
key: 'PushNotificationIOSExample',
|
||||
module: require('./PushNotificationIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'RCTRootViewIOSExample',
|
||||
module: require('./RCTRootViewIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'SnapshotExample',
|
||||
module: require('./SnapshotExample'),
|
||||
},
|
||||
{
|
||||
key: 'StatusBarIOSExample',
|
||||
module: require('./StatusBarIOSExample'),
|
||||
},
|
||||
{
|
||||
key: 'TimerExample',
|
||||
module: require('./TimerExample'),
|
||||
},
|
||||
{
|
||||
key: 'TransformExample',
|
||||
module: require('./TransformExample'),
|
||||
},
|
||||
{
|
||||
key: 'VibrationExample',
|
||||
module: require('./VibrationExample'),
|
||||
},
|
||||
{
|
||||
key: 'XHRExample',
|
||||
module: require('./XHRExample.ios'),
|
||||
},
|
||||
];
|
||||
render() {
|
||||
return (
|
||||
<UIExplorerListBase
|
||||
components={COMPONENTS}
|
||||
apis={APIS}
|
||||
searchText={Settings.get('searchText')}
|
||||
renderAdditionalView={this.renderAdditionalView.bind(this)}
|
||||
search={this.search.bind(this)}
|
||||
onPressRow={this.onPressRow.bind(this)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const Modules = {};
|
||||
renderAdditionalView(renderRow: Function, renderTextInput: Function): React.Component {
|
||||
return renderTextInput(styles.searchTextInput);
|
||||
}
|
||||
|
||||
APIExamples.concat(ComponentExamples).forEach(Example => {
|
||||
Modules[Example.key] = Example.module;
|
||||
search(text: mixed) {
|
||||
Settings.set({searchText: text});
|
||||
}
|
||||
|
||||
_openExample(example: any) {
|
||||
if (example.external) {
|
||||
this.props.onExternalExampleRequested(example);
|
||||
return;
|
||||
}
|
||||
|
||||
var Component = UIExplorerListBase.makeRenderable(example);
|
||||
this.props.navigator.push({
|
||||
title: Component.title,
|
||||
component: Component,
|
||||
});
|
||||
}
|
||||
|
||||
onPressRow(example: any) {
|
||||
this._openExample(example);
|
||||
}
|
||||
|
||||
// Register suitable examples for snapshot tests
|
||||
static registerComponents() {
|
||||
COMPONENTS.concat(APIS).forEach((Example) => {
|
||||
if (Example.displayName) {
|
||||
var Snapshotter = React.createClass({
|
||||
render: function() {
|
||||
var Renderable = UIExplorerListBase.makeRenderable(Example);
|
||||
return (
|
||||
<SnapshotViewIOS>
|
||||
<Renderable />
|
||||
</SnapshotViewIOS>
|
||||
);
|
||||
},
|
||||
});
|
||||
AppRegistry.registerComponent(Example.displayName, () => Snapshotter);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
searchTextInput: {
|
||||
height: 30,
|
||||
},
|
||||
});
|
||||
|
||||
const UIExplorerList = {
|
||||
APIExamples,
|
||||
ComponentExamples,
|
||||
Modules,
|
||||
};
|
||||
|
||||
module.exports = UIExplorerList;
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ListView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
var createExamplePage = require('./createExamplePage');
|
||||
|
||||
var ds = new ListView.DataSource({
|
||||
rowHasChanged: (r1, r2) => r1 !== r2,
|
||||
sectionHeaderHasChanged: (h1, h2) => h1 !== h2,
|
||||
});
|
||||
|
||||
class UIExplorerListBase extends React.Component {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = {
|
||||
dataSource: ds.cloneWithRowsAndSections({
|
||||
components: [],
|
||||
apis: [],
|
||||
}),
|
||||
searchText: this.props.searchText || '',
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.search(this.state.searchText);
|
||||
}
|
||||
|
||||
render() {
|
||||
var topView = this.props.renderAdditionalView &&
|
||||
this.props.renderAdditionalView(this.renderRow.bind(this), this.renderTextInput.bind(this));
|
||||
|
||||
return (
|
||||
<View style={styles.listContainer}>
|
||||
{topView}
|
||||
<ListView
|
||||
style={styles.list}
|
||||
dataSource={this.state.dataSource}
|
||||
renderRow={this.renderRow.bind(this)}
|
||||
renderSectionHeader={this._renderSectionHeader}
|
||||
keyboardShouldPersistTaps={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
keyboardDismissMode="on-drag"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderTextInput(searchTextInputStyle: any) {
|
||||
return (
|
||||
<View style={styles.searchRow}>
|
||||
<TextInput
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
clearButtonMode="always"
|
||||
onChangeText={this.search.bind(this)}
|
||||
placeholder="Search..."
|
||||
style={[styles.searchTextInput, searchTextInputStyle]}
|
||||
testID="explorer_search"
|
||||
value={this.state.searchText}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_renderSectionHeader(data: any, section: string) {
|
||||
return (
|
||||
<Text style={styles.sectionHeader}>
|
||||
{section.toUpperCase()}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
renderRow(example: any, i: number) {
|
||||
return (
|
||||
<View key={i}>
|
||||
<TouchableHighlight onPress={() => this.onPressRow(example)}>
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowTitleText}>
|
||||
{example.title}
|
||||
</Text>
|
||||
<Text style={styles.rowDetailText}>
|
||||
{example.description}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<View style={styles.separator} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
search(text: mixed): void {
|
||||
this.props.search && this.props.search(text);
|
||||
|
||||
var regex = new RegExp(String(text), 'i');
|
||||
var filter = (component) => regex.test(component.title);
|
||||
|
||||
this.setState({
|
||||
dataSource: ds.cloneWithRowsAndSections({
|
||||
components: this.props.components.filter(filter),
|
||||
apis: this.props.apis.filter(filter),
|
||||
}),
|
||||
searchText: text,
|
||||
});
|
||||
}
|
||||
|
||||
onPressRow(example: any): void {
|
||||
this.props.onPressRow && this.props.onPressRow(example);
|
||||
}
|
||||
|
||||
static makeRenderable(example: any): ReactClass<any, any, any> {
|
||||
return example.examples ?
|
||||
createExamplePage(null, example) :
|
||||
example;
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
listContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
list: {
|
||||
backgroundColor: '#eeeeee',
|
||||
},
|
||||
sectionHeader: {
|
||||
padding: 5,
|
||||
fontWeight: '500',
|
||||
fontSize: 11,
|
||||
},
|
||||
group: {
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
row: {
|
||||
backgroundColor: 'white',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 15,
|
||||
paddingVertical: 8,
|
||||
},
|
||||
separator: {
|
||||
height: StyleSheet.hairlineWidth,
|
||||
backgroundColor: '#bbbbbb',
|
||||
marginLeft: 15,
|
||||
},
|
||||
rowTitleText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
rowDetailText: {
|
||||
fontSize: 15,
|
||||
color: '#888888',
|
||||
lineHeight: 20,
|
||||
},
|
||||
searchRow: {
|
||||
backgroundColor: '#eeeeee',
|
||||
paddingTop: 75,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
searchTextInput: {
|
||||
backgroundColor: 'white',
|
||||
borderColor: '#cccccc',
|
||||
borderRadius: 3,
|
||||
borderWidth: 1,
|
||||
paddingLeft: 8,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = UIExplorerListBase;
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
// $FlowFixMe : This is a platform-forked component, and flow seems to only run on iOS?
|
||||
const UIExplorerList = require('./UIExplorerList');
|
||||
const {
|
||||
NavigationExperimental,
|
||||
} = React;
|
||||
const {
|
||||
Reducer: NavigationReducer,
|
||||
} = NavigationExperimental;
|
||||
const StackReducer = NavigationReducer.StackReducer;
|
||||
|
||||
import type {NavigationState} from 'NavigationTypeDefinition';
|
||||
|
||||
import type {UIExplorerAction} from './UIExplorerActions';
|
||||
|
||||
export type UIExplorerNavigationState = {
|
||||
externalExample: ?string;
|
||||
stack: NavigationState;
|
||||
};
|
||||
|
||||
const UIExplorerStackReducer = StackReducer({
|
||||
getPushedReducerForAction: (action, lastState) => {
|
||||
if (action.type === 'UIExplorerExampleAction' && UIExplorerList.Modules[action.openExample]) {
|
||||
if (lastState.children.find(child => child.key === action.openExample)) {
|
||||
// The example is already open, we should avoid pushing examples twice
|
||||
return null;
|
||||
}
|
||||
return (state) => state || {key: action.openExample};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getReducerForState: (initialState) => (state) => state || initialState,
|
||||
initialState: {
|
||||
key: 'UIExplorerMainStack',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'AppList'},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
function UIExplorerNavigationReducer(lastState: ?UIExplorerNavigationState, action: any): UIExplorerNavigationState {
|
||||
if (!lastState) {
|
||||
return {
|
||||
externalExample: null,
|
||||
stack: UIExplorerStackReducer(null, action),
|
||||
};
|
||||
}
|
||||
if (action.type === 'UIExplorerListWithFilterAction') {
|
||||
return {
|
||||
externalExample: null,
|
||||
stack: {
|
||||
key: 'UIExplorerMainStack',
|
||||
index: 0,
|
||||
children: [
|
||||
{
|
||||
key: 'AppList',
|
||||
filter: action.filter,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
if (action.type === 'BackAction' && lastState.externalExample) {
|
||||
return {
|
||||
...lastState,
|
||||
externalExample: null,
|
||||
};
|
||||
}
|
||||
if (action.type === 'UIExplorerExampleAction') {
|
||||
const ExampleModule = UIExplorerList.Modules[action.openExample];
|
||||
if (ExampleModule && ExampleModule.external) {
|
||||
return {
|
||||
...lastState,
|
||||
externalExample: action.openExample,
|
||||
};
|
||||
}
|
||||
}
|
||||
const newStack = UIExplorerStackReducer(lastState.stack, action);
|
||||
if (newStack !== lastState.stack) {
|
||||
return {
|
||||
externalExample: null,
|
||||
stack: newStack,
|
||||
}
|
||||
}
|
||||
return lastState;
|
||||
}
|
||||
|
||||
module.exports = UIExplorerNavigationReducer;
|
||||
@@ -37,9 +37,9 @@ var UIExplorerPage = React.createClass({
|
||||
var ContentWrapper;
|
||||
var wrapperProps = {};
|
||||
if (this.props.noScroll) {
|
||||
ContentWrapper = (View: ReactClass<any>);
|
||||
ContentWrapper = (View: ReactClass<any, any, any>);
|
||||
} else {
|
||||
ContentWrapper = (ScrollView: ReactClass<any>);
|
||||
ContentWrapper = (ScrollView: ReactClass<any, any, any>);
|
||||
wrapperProps.automaticallyAdjustContentInsets = !this.props.title;
|
||||
wrapperProps.keyboardShouldPersistTaps = true;
|
||||
wrapperProps.keyboardDismissMode = 'interactive';
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// $FlowFixMe : This is a platform-forked component, and flow seems to only run on iOS?
|
||||
const UIExplorerList = require('./UIExplorerList');
|
||||
|
||||
import type {NavigationState} from 'NavigationTypeDefinition';
|
||||
|
||||
function StateTitleMap(state: NavigationState): string {
|
||||
if (UIExplorerList.Modules[state.key]) {
|
||||
return UIExplorerList.Modules[state.key].title
|
||||
}
|
||||
if (state.key === 'AppList') {
|
||||
return 'UIExplorer';
|
||||
}
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
module.exports = StateTitleMap;
|
||||
@@ -24,12 +24,8 @@
|
||||
#define RUN_RUNLOOP_WHILE(CONDITION) \
|
||||
{ \
|
||||
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:5]; \
|
||||
while ((CONDITION)) { \
|
||||
while ((CONDITION) && [timeout timeIntervalSinceNow] > 0) { \
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; \
|
||||
if ([timeout timeIntervalSinceNow] <= 0) { \
|
||||
XCTFail(@"Runloop timed out before condition was met"); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -41,8 +37,6 @@
|
||||
|
||||
@implementation TestExecutor
|
||||
|
||||
@synthesize valid = _valid;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)setUp {}
|
||||
@@ -57,7 +51,7 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (BOOL)isValid
|
||||
{
|
||||
return _valid;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)flushedQueue:(RCTJavaScriptCallback)onComplete
|
||||
@@ -100,33 +94,7 @@ RCT_EXPORT_MODULE()
|
||||
onComplete(nil);
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
_valid = NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// Define a module that is not explicitly registered with RCT_EXPORT_MODULE
|
||||
@interface UnregisteredTestModule : NSObject <RCTBridgeModule>
|
||||
|
||||
@property (nonatomic, assign) BOOL testMethodCalled;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UnregisteredTestModule
|
||||
|
||||
@synthesize methodQueue = _methodQueue;
|
||||
|
||||
+ (NSString *)moduleName
|
||||
{
|
||||
return @"UnregisteredTestModule";
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(testMethod)
|
||||
{
|
||||
_testMethodCalled = YES;
|
||||
}
|
||||
- (void)invalidate {}
|
||||
|
||||
@end
|
||||
|
||||
@@ -136,7 +104,6 @@ RCT_EXPORT_METHOD(testMethod)
|
||||
__weak TestExecutor *_jsExecutor;
|
||||
|
||||
BOOL _testMethodCalled;
|
||||
UnregisteredTestModule *_unregisteredTestModule;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -150,9 +117,8 @@ RCT_EXPORT_MODULE(TestModule)
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
_unregisteredTestModule = [UnregisteredTestModule new];
|
||||
_bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
moduleProvider:^{ return @[self, _unregisteredTestModule]; }
|
||||
moduleProvider:^{ return @[self]; }
|
||||
launchOptions:nil];
|
||||
|
||||
_bridge.executorClass = [TestExecutor class];
|
||||
@@ -162,7 +128,7 @@ RCT_EXPORT_MODULE(TestModule)
|
||||
[_bridge invalidate];
|
||||
[_bridge setUp];
|
||||
|
||||
_jsExecutor = _bridge.batchedBridge.javaScriptExecutor;
|
||||
_jsExecutor = [_bridge.batchedBridge valueForKey:@"javaScriptExecutor"];
|
||||
XCTAssertNotNil(_jsExecutor);
|
||||
}
|
||||
|
||||
@@ -173,8 +139,10 @@ RCT_EXPORT_MODULE(TestModule)
|
||||
_testMethodCalled = NO;
|
||||
|
||||
[_bridge invalidate];
|
||||
RUN_RUNLOOP_WHILE(_jsExecutor.isValid);
|
||||
_bridge = nil;
|
||||
|
||||
RUN_RUNLOOP_WHILE(_jsExecutor != nil);
|
||||
XCTAssertNotNil(_jsExecutor);
|
||||
}
|
||||
|
||||
- (void)testHookRegistration
|
||||
@@ -236,37 +204,6 @@ RCT_EXPORT_MODULE(TestModule)
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testCallUnregisteredModuleMethod
|
||||
{
|
||||
NSString *injectedStuff;
|
||||
RUN_RUNLOOP_WHILE(!(injectedStuff = _jsExecutor.injectedStuff[@"__fbBatchedBridgeConfig"]));
|
||||
XCTAssertNotNil(injectedStuff);
|
||||
|
||||
__block NSNumber *testModuleID = nil;
|
||||
__block NSNumber *testMethodID = nil;
|
||||
|
||||
NSArray *remoteModuleConfig = RCTJSONParse(injectedStuff, NULL)[@"remoteModuleConfig"];
|
||||
[remoteModuleConfig enumerateObjectsUsingBlock:^(id moduleConfig, NSUInteger i, __unused BOOL *stop) {
|
||||
if ([moduleConfig isKindOfClass:[NSArray class]] && [moduleConfig[0] isEqualToString:@"UnregisteredTestModule"]) {
|
||||
testModuleID = @(i);
|
||||
testMethodID = @([moduleConfig[1] indexOfObject:@"testMethod"]);
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
XCTAssertNotNil(testModuleID);
|
||||
XCTAssertNotNil(testMethodID);
|
||||
|
||||
NSArray *args = @[];
|
||||
NSArray *buffer = @[@[testModuleID], @[testMethodID], @[args]];
|
||||
|
||||
[_bridge.batchedBridge handleBuffer:buffer];
|
||||
|
||||
dispatch_sync(_unregisteredTestModule.methodQueue, ^{
|
||||
XCTAssertTrue(_unregisteredTestModule.testMethodCalled);
|
||||
});
|
||||
}
|
||||
|
||||
- (void)DISABLED_testBadArgumentsCount
|
||||
{
|
||||
//NSArray *bufferWithMissingArgument = @[@[@1], @[@0], @[@[@1234, @5678, @"stringy", @{@"a": @1}/*, @42*/]], @[], @1234567];
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTViewManager.h"
|
||||
#import "RCTView.h"
|
||||
|
||||
#define RUN_RUNLOOP_WHILE(CONDITION) \
|
||||
{ \
|
||||
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:5]; \
|
||||
while ((CONDITION)) { \
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; \
|
||||
if ([timeout timeIntervalSinceNow] <= 0) { \
|
||||
XCTFail(@"Runloop timed out before condition was met"); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
@interface RCTUIManager ()
|
||||
|
||||
- (void)createView:(NSNumber *)reactTag
|
||||
viewName:(NSString *)viewName
|
||||
rootTag:(NSNumber *)rootTag
|
||||
props:(NSDictionary *)props;
|
||||
|
||||
- (void)updateView:(nonnull NSNumber *)reactTag
|
||||
viewName:(NSString *)viewName
|
||||
props:(NSDictionary *)props;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTPropsTestView : UIView
|
||||
|
||||
@property (nonatomic, assign) NSInteger integerProp;
|
||||
@property (nonatomic, strong) id objectProp;
|
||||
@property (nonatomic, assign) CGPoint structProp;
|
||||
@property (nonatomic, copy) NSString *customProp;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTPropsTestView
|
||||
@end
|
||||
|
||||
@interface RCTPropsTestViewManager : RCTViewManager
|
||||
@end
|
||||
|
||||
@implementation RCTPropsTestViewManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
RCTPropsTestView *view = [RCTPropsTestView new];
|
||||
view.integerProp = 57;
|
||||
view.objectProp = @9;
|
||||
view.structProp = CGPointMake(5, 6);
|
||||
view.customProp = @"Hello";
|
||||
return view;
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(integerProp, NSInteger)
|
||||
RCT_EXPORT_VIEW_PROPERTY(objectProp, NSNumber)
|
||||
RCT_EXPORT_VIEW_PROPERTY(structProp, CGPoint)
|
||||
RCT_CUSTOM_VIEW_PROPERTY(customProp, NSString, RCTPropsTestView)
|
||||
{
|
||||
view.customProp = json ? [RCTConvert NSString:json] : defaultView.customProp;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTComponentPropsTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTComponentPropsTests
|
||||
{
|
||||
RCTBridge *_bridge;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
_bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
moduleProvider:nil
|
||||
launchOptions:nil];
|
||||
}
|
||||
|
||||
- (void)testSetProps
|
||||
{
|
||||
__block RCTPropsTestView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
NSDictionary *props = @{@"integerProp": @58,
|
||||
@"objectProp": @10,
|
||||
@"structProp": @{@"x": @7, @"y": @8},
|
||||
@"customProp": @"Goodbye"};
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTPropsTestView" rootTag:nil props:props];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
view = (RCTPropsTestView *)viewRegistry[@2];
|
||||
XCTAssertEqual(view.integerProp, 58);
|
||||
XCTAssertEqualObjects(view.objectProp, @10);
|
||||
XCTAssertTrue(CGPointEqualToPoint(view.structProp, CGPointMake(7, 8)));
|
||||
XCTAssertEqualObjects(view.customProp, @"Goodbye");
|
||||
}];
|
||||
[uiManager setNeedsLayout];
|
||||
});
|
||||
|
||||
RUN_RUNLOOP_WHILE(view == nil);
|
||||
}
|
||||
|
||||
- (void)testResetProps
|
||||
{
|
||||
__block RCTPropsTestView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
NSDictionary *props = @{@"integerProp": @58,
|
||||
@"objectProp": @10,
|
||||
@"structProp": @{@"x": @7, @"y": @8},
|
||||
@"customProp": @"Goodbye"};
|
||||
|
||||
NSDictionary *resetProps = @{@"integerProp": [NSNull null],
|
||||
@"objectProp": [NSNull null],
|
||||
@"structProp": [NSNull null],
|
||||
@"customProp": [NSNull null]};
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTPropsTestView" rootTag:nil props:props];
|
||||
[uiManager updateView:@2 viewName:@"RCTPropsTestView" props:resetProps];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
view = (RCTPropsTestView *)viewRegistry[@2];
|
||||
XCTAssertEqual(view.integerProp, 57);
|
||||
XCTAssertEqualObjects(view.objectProp, @9);
|
||||
XCTAssertTrue(CGPointEqualToPoint(view.structProp, CGPointMake(5, 6)));
|
||||
XCTAssertEqualObjects(view.customProp, @"Hello");
|
||||
}];
|
||||
[uiManager setNeedsLayout];
|
||||
});
|
||||
|
||||
RUN_RUNLOOP_WHILE(view == nil);
|
||||
}
|
||||
|
||||
- (void)testResetBackgroundColor
|
||||
{
|
||||
__block RCTView *view;
|
||||
RCTUIManager *uiManager = _bridge.uiManager;
|
||||
NSDictionary *props = @{@"backgroundColor": @0xffffffff};
|
||||
NSDictionary *resetProps = @{@"backgroundColor": [NSNull null]};
|
||||
|
||||
dispatch_async(uiManager.methodQueue, ^{
|
||||
[uiManager createView:@2 viewName:@"RCTView" rootTag:nil props:props];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
view = (RCTView *)viewRegistry[@2];
|
||||
XCTAssertEqualObjects(view.backgroundColor, [RCTConvert UIColor:@0xffffffff]);
|
||||
}];
|
||||
[uiManager updateView:@2 viewName:@"RCTView" props:resetProps];
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *_uiManager, __unused NSDictionary<NSNumber *,UIView *> *viewRegistry) {
|
||||
view = (RCTView *)viewRegistry[@2];
|
||||
XCTAssertNil(view.backgroundColor);
|
||||
}];
|
||||
[uiManager setNeedsLayout];
|
||||
});
|
||||
|
||||
RUN_RUNLOOP_WHILE(view == nil);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -17,51 +17,28 @@
|
||||
|
||||
#import <OCMock/OCMock.h>
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
|
||||
@interface RCTTestEvent : NSObject <RCTEvent>
|
||||
@property (atomic, assign, readwrite) BOOL canCoalesce;
|
||||
@interface RCTTestEvent : RCTBaseEvent
|
||||
|
||||
@property (nonatomic, assign) BOOL canCoalesce;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTTestEvent
|
||||
{
|
||||
NSDictionary<NSString *, id> *_body;
|
||||
}
|
||||
|
||||
@synthesize viewTag = _viewTag;
|
||||
@synthesize eventName = _eventName;
|
||||
@synthesize coalescingKey = _coalescingKey;
|
||||
|
||||
- (instancetype)initWithViewTag:(NSNumber *)viewTag
|
||||
eventName:(NSString *)eventName
|
||||
body:(NSDictionary<NSString *, id> *)body
|
||||
coalescingKey:(uint16_t)coalescingKey
|
||||
- (instancetype)initWithViewTag:(NSNumber *)viewTag eventName:(NSString *)eventName body:(NSDictionary<NSString *, id> *)body
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_viewTag = viewTag;
|
||||
_eventName = eventName;
|
||||
_body = body;
|
||||
_canCoalesce = YES;
|
||||
_coalescingKey = coalescingKey;
|
||||
if (self = [super initWithViewTag:viewTag eventName:eventName body:body]) {
|
||||
self.canCoalesce = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent
|
||||
{
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
+ (NSString *)moduleDotMethod
|
||||
{
|
||||
return @"RCTDeviceEventEmitter.emit";
|
||||
}
|
||||
|
||||
- (NSArray *)arguments
|
||||
{
|
||||
return @[_eventName, _body];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTEventDispatcherTests : XCTestCase
|
||||
@@ -83,8 +60,7 @@
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
_bridge = [OCMockObject mockForClass:[RCTBatchedBridge class]];
|
||||
|
||||
_bridge = [OCMockObject mockForClass:[RCTBridge class]];
|
||||
_eventDispatcher = [RCTEventDispatcher new];
|
||||
[_eventDispatcher setValue:_bridge forKey:@"bridge"];
|
||||
|
||||
@@ -92,8 +68,7 @@
|
||||
_body = @{ @"foo": @"bar" };
|
||||
_testEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:_eventName
|
||||
body:_body
|
||||
coalescingKey:0];
|
||||
body:_body];
|
||||
|
||||
_JSMethod = [[_testEvent class] moduleDotMethod];
|
||||
}
|
||||
@@ -101,86 +76,49 @@
|
||||
- (void)testLegacyEventsAreImmediatelyDispatched
|
||||
{
|
||||
[[_bridge expect] enqueueJSCall:_JSMethod
|
||||
args:[_testEvent arguments]];
|
||||
args:@[_eventName, _body]];
|
||||
|
||||
[_eventDispatcher sendDeviceEventWithName:_eventName body:_body];
|
||||
|
||||
[_bridge verify];
|
||||
}
|
||||
|
||||
- (void)testNonCoalescingEventIsImmediatelyDispatched
|
||||
- (void)testNonCoalescingEventsAreImmediatelyDispatched
|
||||
{
|
||||
_testEvent.canCoalesce = NO;
|
||||
|
||||
[[_bridge expect] dispatchBlock:OCMOCK_ANY queue:RCTJSThread];
|
||||
[[_bridge expect] enqueueJSCall:_JSMethod
|
||||
args:@[_eventName, _body]];
|
||||
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
|
||||
[_bridge verify];
|
||||
}
|
||||
|
||||
- (void)testCoalescingEventIsImmediatelyDispatched
|
||||
- (void)testCoalescedEventShouldBeDispatchedOnFrameUpdate
|
||||
{
|
||||
_testEvent.canCoalesce = YES;
|
||||
|
||||
[[_bridge expect] dispatchBlock:OCMOCK_ANY queue:RCTJSThread];
|
||||
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
|
||||
[_bridge verify];
|
||||
}
|
||||
|
||||
- (void)testMultipleEventsResultInOnlyOneDispatchAfterTheFirstOne
|
||||
{
|
||||
[[_bridge expect] dispatchBlock:OCMOCK_ANY queue:RCTJSThread];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_bridge verify];
|
||||
}
|
||||
|
||||
- (void)testRunningTheDispatchedBlockResultInANewOneBeingEnqueued
|
||||
{
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_bridge verify];
|
||||
|
||||
|
||||
// eventsEmittingBlock would be called when js is no longer busy, which will result in emitting events
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit"
|
||||
args:[_testEvent arguments]];
|
||||
eventsEmittingBlock();
|
||||
[_bridge verify];
|
||||
args:@[_eventName, _body]];
|
||||
|
||||
[(id<RCTFrameUpdateObserver>)_eventDispatcher didUpdateFrame:nil];
|
||||
|
||||
[[_bridge expect] dispatchBlock:OCMOCK_ANY queue:RCTJSThread];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
[_bridge verify];
|
||||
}
|
||||
|
||||
- (void)testBasicCoalescingReturnsLastEvent
|
||||
{
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit"
|
||||
args:[_testEvent arguments]];
|
||||
|
||||
RCTTestEvent *ignoredEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:_eventName
|
||||
body:@{ @"other": @"body" }
|
||||
coalescingKey:0];
|
||||
body:@{ @"other": @"body" }];
|
||||
|
||||
[_eventDispatcher sendEvent:ignoredEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
eventsEmittingBlock();
|
||||
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit"
|
||||
args:@[_eventName, _body]];
|
||||
|
||||
[(id<RCTFrameUpdateObserver>)_eventDispatcher didUpdateFrame:nil];
|
||||
|
||||
[_bridge verify];
|
||||
}
|
||||
@@ -189,60 +127,19 @@
|
||||
{
|
||||
NSString *firstEventName = RCTNormalizeInputEventName(@"firstEvent");
|
||||
RCTTestEvent *firstEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:firstEventName
|
||||
body:_body
|
||||
coalescingKey:0];
|
||||
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit"
|
||||
args:[firstEvent arguments]];
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit"
|
||||
args:[_testEvent arguments]];
|
||||
|
||||
eventName:firstEventName
|
||||
body:_body];
|
||||
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
[_eventDispatcher sendEvent:_testEvent];
|
||||
eventsEmittingBlock();
|
||||
|
||||
[_bridge verify];
|
||||
}
|
||||
|
||||
- (void)testSameEventTypesWithDifferentCoalesceKeysDontCoalesce
|
||||
{
|
||||
NSString *eventName = RCTNormalizeInputEventName(@"firstEvent");
|
||||
RCTTestEvent *firstEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:eventName
|
||||
body:_body
|
||||
coalescingKey:0];
|
||||
RCTTestEvent *secondEvent = [[RCTTestEvent alloc] initWithViewTag:nil
|
||||
eventName:eventName
|
||||
body:_body
|
||||
coalescingKey:1];
|
||||
|
||||
__block dispatch_block_t eventsEmittingBlock;
|
||||
[[_bridge expect] dispatchBlock:[OCMArg checkWithBlock:^(dispatch_block_t block) {
|
||||
eventsEmittingBlock = block;
|
||||
return YES;
|
||||
}] queue:RCTJSThread];
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit"
|
||||
args:[firstEvent arguments]];
|
||||
args:@[firstEventName, _body]];
|
||||
|
||||
[[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit"
|
||||
args:[secondEvent arguments]];
|
||||
args:@[_eventName, _body]];
|
||||
|
||||
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
[_eventDispatcher sendEvent:secondEvent];
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
[_eventDispatcher sendEvent:secondEvent];
|
||||
[_eventDispatcher sendEvent:secondEvent];
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
[_eventDispatcher sendEvent:firstEvent];
|
||||
|
||||
eventsEmittingBlock();
|
||||
[(id<RCTFrameUpdateObserver>)_eventDispatcher didUpdateFrame:nil];
|
||||
|
||||
[_bridge verify];
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#import "RCTImageLoader.h"
|
||||
|
||||
typedef BOOL (^RCTImageURLLoaderCanLoadImageURLHandler)(NSURL *requestURL);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageURLLoaderLoadImageURLHandler)(NSURL *imageURL, CGSize size, CGFloat scale, RCTResizeMode resizeMode, RCTImageLoaderProgressBlock progressHandler, RCTImageLoaderCompletionBlock completionHandler);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageURLLoaderLoadImageURLHandler)(NSURL *imageURL, CGSize size, CGFloat scale, UIViewContentMode resizeMode, RCTImageLoaderProgressBlock progressHandler, RCTImageLoaderCompletionBlock completionHandler);
|
||||
|
||||
@interface RCTConcreteImageURLLoader : NSObject <RCTImageURLLoader>
|
||||
|
||||
@@ -26,7 +26,7 @@ typedef RCTImageLoaderCancellationBlock (^RCTImageURLLoaderLoadImageURLHandler)(
|
||||
@end
|
||||
|
||||
typedef BOOL (^RCTImageDataDecoderCanDecodeImageDataHandler)(NSData *imageData);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageDataDecoderDecodeImageDataHandler)(NSData *imageData, CGSize size, CGFloat scale, RCTResizeMode resizeMode, RCTImageLoaderCompletionBlock completionHandler);
|
||||
typedef RCTImageLoaderCancellationBlock (^RCTImageDataDecoderDecodeImageDataHandler)(NSData *imageData, CGSize size, CGFloat scale, UIViewContentMode resizeMode, RCTImageLoaderCompletionBlock completionHandler);
|
||||
|
||||
@interface RCTConcreteImageDecoder : NSObject <RCTImageDataDecoder>
|
||||
|
||||
|
||||