Compare commits

...
605 Commits
Author SHA1 Message Date
James Ide 56563f13b3 [0.11.4] Add iOS stubs for Android modules 2015-09-28 12:21:57 -07:00
James Ide 0a08879d70 [Android/iOS] Add .iOS.js stubs for Android components 2015-09-28 12:20:28 -07:00
James Ide b890969b1e [0.11.3] Add Android exports 2015-09-28 05:02:28 -07:00
James Ide 3bc5b180b1 [Android] Export Android-specific modules 2015-09-28 05:01:55 -07:00
James Ide 5fbe29903b [0.11.2] displayName fixes + Android bundled 2015-09-24 11:44:24 -07:00
Martin Konicek 7cc3ba99e0 Add Android code to the 0.11-stable branch.
Cherry-picked https://github.com/facebook/react-native/commit/42eb5464fd8a65ed84b799de5d4dc225349449be
2015-09-24 13:55:23 +01:00
James Ide 77167b02ee [0.11.1]
- Added react.displayName to the packager.
2015-09-22 15:42:55 -07:00
James Ide aed1c76576 [Packager] Bump the cache breakers for the react.displayName transform 2015-09-22 15:42:28 -07:00
Ben Alpert 8187e9153c [ReactNative] Enable displayName transformer in open source 2015-09-22 15:41:54 -07:00
Martin Konicek c98a6fbde1 [0.11] Bump pod version 2015-09-15 21:24:16 +01:00
James Ide e1032e1d09 [0.11.0] 2015-09-14 18:23:33 -07:00
Amjad Masad 0c2f3fe145 Refactor DependencyResolver into request/response
Reviewed By: @martinbigio

Differential Revision: D2425842

Conflicts:
	packager/react-packager/src/Bundler/index.js
	packager/react-packager/src/DependencyResolver/DependencyGraph/__tests__/DependencyGraph-test.js
2015-09-11 18:11:58 -07:00
Amjad Masad 329f059ba9 [react-packager] Support platform extensions in image requires
Summary:
We don't currently support platform extensions in asset modules.
This adds supports for it:

```
require('./a.png');
```

Will require 'a.ios.png' if it exists and 'a.png' if it doesn't.
2015-09-11 18:01:53 -07:00
James Ide 2d8ec5eca7 [npm] Update to stacktrace-parser@0.1.3 and ws@0.8.0 to satisfy io.js 3 / Node 4
Summary:
The previous version of stacktrace-parser 0.1.2 had an line in its package.json file that required Node <= 2.x. That line was removed, so it no longer warns on io.js 3.x or Node 4.x.

Similarly, ws 0.8.0 was published with support for the new V8, so it compiles with io.js 3.x and therefore should work with Node 4.x.

Updated the Travis file as well to run on io.js 3.x.

Fixes #2258, #2455

Closes https://github.com/facebook/react-native/pull/2398
Github Author: James Ide <ide@jameside.com>
2015-09-08 13:30:57 -07:00
Martin Konicek 6edb671e2d 0.11.0-rc 2015-08-26 17:28:18 +01:00
Martin Konicek 6d78b75a10 Update CONTRIBUTING.md 2015-08-26 17:04:53 +01:00
Martin Konicek a0c3b426de Update react-native-cli/CONTRIBUTING.md 2015-08-26 16:35:03 +01:00
Martin Konicek 9576657b57 Update react-native-cli/CONTRIBUTING.md 2015-08-26 16:04:48 +01:00
Martin Konicek dd9bbb4bca Update react-native-cli/CONTRIBUTING.md 2015-08-26 16:02:43 +01:00
Martin Konicek 57adecc36e Merge pull request #2443 from mkonicek/Updates_Wed_26_Aug
Updates from Wed 26 Aug
2015-08-26 14:23:12 +01:00
Martin Konicek 5526533f51 Updates from Wed 26 Aug 2015-08-26 14:04:01 +01:00
Felix Oghină 626f828d54 [reactnative] remove platform option from oss packager 2015-08-26 04:49:41 -08:00
Andrei Coman a8f11d7115 [ReactNative] Add TouchableNativeFeedback to OSS 2015-08-26 01:31:52 -08:00
Amjad Masad 074069e465 [react-packager] Cleanup socket interface code 2015-08-25 17:36:08 -08:00
Amjad Masad 2b7dd4650f [react-native] bump create server timeout 2015-08-25 17:13:13 -08:00
Andy Street 162d12cfa4 [ReactNative][SyncDiff] Allow renderToHardwareTextureAndroid to be used outside of setNativeProps 2015-08-25 16:55:51 -08:00
Andy Street 504fa60168 [ReactNative][SyncDiff] AutoSync 2015-08-25 14:54:10 -08:00
Martin Konicek 0203f87ea3 Add chalk mock 2015-08-25 22:02:19 +01:00
Martin Konicek 2f6e7336cb Merge pull request #2435 from mkonicek/Updates_Tue_25_Aug_trois
Updates from Tuesday 25 August

JS test failure fix will follow.
2015-08-25 19:58:36 +01:00
Martin Konicek 19f922aa80 [cli] Fix iOS app template 2015-08-25 19:25:17 +01:00
Martin Konicek 480b5c9e2e [website] Fix website generation 2015-08-25 19:23:41 +01:00
Martin Konicek da7ac11c53 Updates from Tue 25 Aug 2015-08-25 19:21:59 +01:00
Martin Konicek 4f87ec5ce7 [ReactNative] Unbreak OSS packager JS tests 2015-08-25 10:18:39 -08:00
Natansh Verma 8d65367fbc Revert "[packager] Unbreak Bundler test" 2015-08-25 09:53:45 -08:00
Amjad Masad 54026024cc [react-packager] Expose a socket interface
Summary:
Buck (our build system) currently starts multiple packager instances for each target and may build multiple targets in parallel. This means we're paying startup costs and are duplicating the work. This enables us to start one instance of the packager and connect to it via socket to do all the work that needs to be done.

The way this is structured:

1. SocketServer: A server that listens on a socket path that is generated based on the server options
2. SocketClient: Interfaces with the server and exposes the operations that we support as methods
3. SocketInterface: Integration point and responsible for forking off the server
2015-08-25 09:37:08 -08:00
Alexey Lang 2d2252cd50 Use native initialAppState to init app_state for AppStateIOS. 2015-08-25 09:32:28 -08:00
Martin Konicek 245a5b8e8c [packager] Unbreak Bundler test 2015-08-25 09:24:42 -08:00
Matt Mahoney 36c1064033 [rn] Pass props when creating a view in RCTViewManager 2015-08-25 08:08:17 -08:00
Krzysztof Magiera 27a67c2434 [ReactNative] Respect --assets-dest in "download from server" mode 2015-08-25 07:22:05 -08:00
Martin Konicek 5f8c0613fe [ReactNative] Temporarily disable flow in TabBarItemIOS 2015-08-25 07:16:35 -08:00
Nick Lockwood 8497b5a66f Fixed tab bar snapshot test 2015-08-25 06:36:43 -08:00
Nick Lockwood 65a3c07cfe Fixed tab bar icon scale
Summary:
TabBarItemIOS supports setting the scale for base64-encoded images using an optional scale parameter, however this was broken due to the JS code only passing the uri, not the whole source object, to the native side.

(See: https://github.com/facebook/react-native/issues/2413)
2015-08-25 05:26:14 -08:00
Pieter De Baets 371aeceb72 Small perf improvement to RCTPerfStats and RCTBridgeModuleNameForClass 2015-08-25 04:48:39 -08:00
Nick Lockwood 072390ec5c Fixed SampleAppTests 2015-08-25 04:41:12 -08:00
Alex Akers 9aefd6bd6e Add keyboard-observing notifications 2015-08-25 03:49:13 -08:00
Tadeu Zagallo fe0143eb20 [ReactNative] Update JS profiler to be compatible with Android
Summary:
Use nativeTraceBeginSection and nativeTraceEndSection with a more dynamic signature
to be compatible with Android.
2015-08-25 02:25:29 -08:00
Nick Lockwood 4382c0e8f4 Fixed redbox rotation
Summary:
Added autoresizing constraints to the redbox layout so that it resizes correctly when the screen is rotated.
2015-08-25 02:20:26 -08:00
Nick Lockwood 88e0bbc469 Ran Convert > To Modern Objective C Syntax 2015-08-25 01:08:49 -08:00
Jing Chen a57353b2b4 [react-native] Make flow warn on timeout instead of redbox 2015-08-24 19:51:14 -08:00
Ben Alpert 75df3b537a Don't report failures to npm
Summary:
This suppresses this output from npm:

```
npm ERR! Failed at the react-native@0.9.0 start script './packager/packager.sh'.
npm ERR! This is most likely a problem with the react-native package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     ./packager/packager.sh
npm ERR! You can get their info via:
npm ERR!     npm owner ls react-native
```

We don't seem to have any automated scripts that rely on the exit code of npm start (or even call it at all).
Closes https://github.com/facebook/react-native/pull/2415
Github Author: Ben Alpert <balpert@fb.com>
2015-08-24 19:32:27 -08:00
Martín Bigio 9ba4697f02 [react-packager] Fix OSS tests 2015-08-24 18:49:05 -08:00
Amjad Masad a008704b51 [react-packager] Add bser to be used in a socket server implementation 2015-08-24 17:04:32 -08:00
Amjad Masad eb248e0b58 [react-packager] Implement transformer progress bar
Summary:
The transform step in currently the longest one in the bundling process. This adds a progress bar to track the transform progress.

{F23096660}
2015-08-24 16:09:34 -08:00
Amjad Masad 8c5626cd87 [react-packager] check in the progress module 2015-08-24 16:09:33 -08:00
Justin Spahr-Summers 94671df753 [JSCLegacyProfiler] Use generic iOS SDK instead of pinning to 8.3
Summary:
The path to the iOS 8.3 SDK does not exist when only Xcode 6.4 is installed. This uses a more general folder name, which (at least) the 8.4 SDK symlinks to.

I haven't verified this on Xcode 6.3, so I'd appreciate it if someone could confirm that this path exists there too! :)
2015-08-24 13:42:34 -08:00
Martin Konicek bb708769d4 [ReactNative] Fix sample apps 2015-08-24 11:48:10 -08:00
Andrei Coman ed0ca71be0 [SyncDiff] [react_native] Revamp text input example for oss 2015-08-22 14:23:30 -08:00
Andrei Coman 127b3292c1 [SyncDiff] [react_native] Add more oss examples 2015-08-22 03:34:33 -08:00
Andrei Coman 8cc7f7f99a [SyncDiff] [react_native] Add toolbar example to oss 2015-08-22 02:14:38 -08:00
Tim Yung af8a6a44b2 RN: Expose React.unstable_batchedUpdates
Summary:
Per @spicyj in facebook/relay#127, this exposes `unstable_batchedUpdates` in React Native the same way it is exposed in `ReactDOM`.
2015-08-21 15:24:56 -08:00
Christopher Chedeau 4b420cc095 Merge pull request #2399 from ide/nvm
[Travis] Put $PWD in front of nvm  (fixes npm install)
2015-08-21 14:58:19 -07:00
Andrei Coman 52abc759ff [SyncDiff] [react_native] Add TextExample to UIExplorer 2015-08-21 14:34:46 -07:00
Christopher Chedeau f3a165db4f [Logs] Name fs step
Summary:
There are two fs steps and it wasn't clear why. This now puts the right label:

```
[9:38:25 PM] <START> Building in-memory fs for JavaScript
[9:38:27 PM] <END>   Building in-memory fs for JavaScript (2030ms)
[9:38:27 PM] <START> Building in-memory fs for Assets
[9:38:27 PM] <END>   Building in-memory fs for Assets (615ms)
```
2015-08-21 14:29:05 -07:00
Pieter De Baets eab390aecb Cleanup bridge init, measure native module init time 2015-08-21 12:32:25 -07:00
James Ide f8f68176d5 [Travis] Put $PWD in front of nvm (fixes npm install)
There was a problem where NVM_DIR wasn't correctly configured, which meant that `npm install` was using whatever version of Node was on the system (0.12 in this case) despite having run `nvm use iojs-v2`. Fixing up NVM_DIR fixes the `npm install` errors and builds the native npm packages for the right version of Node.
2015-08-21 11:37:11 -07:00
Alex Kotliarskyi 8d07df4a22 [ReactNative] Unbreak debugger 2015-08-21 11:20:17 -07:00
Alexey Lang 3643c127a8 Fix fuzziness images in UIExplorer <Image> sample. 2015-08-21 10:58:47 -07:00
Martin Bigio 677f96c60e [react-packager] unbreak tests 2015-08-21 09:38:37 -07:00
Martín Bigio 320a9207f4 [react-packager] Avoid referring Module like objects in BundlesLayout
Summary:
The `BundlesLayout` will be used as a persistent index. As such, it would be easier to avoid having dependencies to `Module`, `Package`, `Asset`, etc. We're not using that information for now and if we happen to need to use it we could always fetch it using the `ModuleCache`.
2015-08-21 08:13:58 -07:00
Martin Konicek 934e7b9afd [ReactNative][oss] Make package.json in consistent with github 2015-08-21 08:09:21 -07:00
Martín Bigio d2f82b1dfd [react-packager] Move async dependencies to System.import
Summary:
We've decided to move the syntax for asynchronously requiring async dependencies. The new syntax works better with promises and therefore withe async/await as well. The new syntax looks like this: `System.import('moduleA').then(moduleA => {...});` or if you're using async/await you could simply do:
  let moduleA = await System.import('moduleA');
  new moduleA().someFunction();

If you need to require multiple dependencies just do:
  Promise
    .all([System.import('moduleA'), System.import('moduleB')])
    .then((moduleA, moduleB) => {...})

or the equivalent using async/await
2015-08-21 07:56:19 -07:00
Dorota Kapturkiewicz f128269da7 [ReactNative] make radiobutton work with accessibility 2015-08-21 07:23:04 -07:00
Nick Lockwood c27e5198e2 Add doc comment for mainScrollView 2015-08-21 04:00:03 -07:00
Bill Fisher debca6d24f [ReactNative] Pass events through to touchable handlers
Summary:
We want to be able to access the touch data within our components' event handlers, so we need to thread the event object all the way through to them.
2015-08-21 03:03:32 -07:00
Nick Lockwood 2cd02d94ff Converted RCTRedBox to a bridge module 2015-08-21 02:53:55 -07:00
Harrison Harnisch 46c6cde947 UI CPU and memory utilization graphs in Chrome debugging mode
Summary:
Chrome debugging UI is currently only showing connection state and logs in the console, leaving room for plenty of interesting information.

I've pushed the UI (using the same convention set by FPS -- UI/JS) CPU and memory utilization data over the debug Websocket and tapped into the existing stream of JS calls that get ran in V8.

The number of JS calls in a time interval is counted for all sub calls in a batch
https://github.com/hharnisc/react-native/blob/master/packager/debugger.html#L150

The last 5 batches of JS calls are displayed in a list format.

<img width="951" alt="screen shot 2015-07-19 at 7 34 00 pm" src="https://cloud.githubusercontent.com/assets/1388079/8769257/edc42f70-2e4d-11e5-8813-e86ef530a446.png">

Charts are created with [Chart.JS](https://github.com/nnnick/Chart.js) (MIT licensed).
Closes https://github.com/facebook/react-native/pull/2050
Github Author: Harrison Harnisch <hharnisc@gmail.com>
2015-08-21 02:11:45 -07:00
Amjad Masad 6debfce374 [react-native] Update graceful-fs and use it in _build_bundle.js 2015-08-20 23:58:51 -07:00
Eric Vicenti 6f17dba39b [ReactNative] Remove POPAnimation
Summary:
Thanks to @vjeux' work on Animated, we have transitioned away from POPAnimation entirely
2015-08-20 22:24:28 -07:00
Emily Janzer 4b28a847e6 [android] fix crash if breadcrumb refs don't exist 2015-08-20 19:08:16 -07:00
Amjad Masad 3bfa90e433 [react-packager] Fix error in template string and bump timeout
Summary:
Fix error in the template string (no plus, thinks it's a function).
And bump the timeout to 30 seconds because a file is taking more than 10 seconds `js/RKJSModules/Libraries/FBComponents/FBFed/FeedStoryFragments.js`
2015-08-20 15:29:38 -07:00
Christopher Chedeau febc03a38b [Logs] Don't print flow error twice
Summary:
Flow errors are already throwing an exception in js, no need to also console.error in the packager
2015-08-20 14:05:47 -07:00
Andy Street a0168a8c62 [ReactNative] [SyncDiff] Create new non-coalesceable event for when native should take the responder lock 2015-08-20 13:56:23 -07:00
Martín Bigio c1f90c1ecf [react-packager] Integration test for runServerHere.sh 2015-08-20 12:00:06 -07:00
Spencer Ahrens 5f91d404e1 [RN] Fix Animated tests 2015-08-20 10:28:49 -07:00
Martín Bigio 5de0796126 [react-packager] Introduce bundle IDs and keep track of parent/child
Summary:
Since JS doesn't have the guarantee that once a bundle is loaded it will stay in memory (and this is something we actually don't want to enforce to keep memmory usage low), we need to keep track of parent/child relationships on the packager to pass it down to native. As part of this diff, we also introduced an ID for each bundle. The ID for a child bundle is shynthetized as the bundleID of the parent module + an index which gets incremented every time a new bundle is created. For instance given this tree:

       a,b
    c       f
  d   e       g

the ID for `d` will be `bundle.0.1.2`, the one for e will be `bundle.0.1.3` and the one for `g` will be `bundle.0.5.6`. This information will be useful to figure out which bundles need to be loaded when a `require.ensure` is re-written.
2015-08-20 10:19:09 -07:00
Dorota Kapturkiewicz ed9b8c8b3b [ReactNative] Disable accessibility of RootView when dialog appears. Apply it for AdsManager. 2015-08-20 10:16:13 -07:00
Christopher Chedeau 1ca1a44a07 [Logs] Remove already registered warning 2015-08-20 09:46:10 -07:00
Dorota Kapturkiewicz b888e8db40 [ReactNative] make sending accessibility events from JS possible and fix dialog 2015-08-20 08:41:22 -07:00
Martin Konicek 0b5952a454 [ReactNative][oss] Open source NetworkingModule 2015-08-20 07:19:34 -07:00
Alexsander Akers ee82a195f7 Set padding on ModalFullscreenView to offset status bar frame 2015-08-20 07:10:34 -07:00
Tadeu Zagallo 81fdf3e532 [ReactNative] Change RCTProfile API to be compatible with systrace 2015-08-20 00:47:23 -07:00
Christopher Chedeau 16ddb1962a [ReactNative] Remove warning for <Image source={require('./image.jpg')} />
Summary:
require('./image.jpg') returns a number and therefore the propType is wrong. Adding it to the propType to fix the warning and dealing with flow which is completely broken for this.
2015-08-19 22:53:25 -07:00
Spencer Ahrens 059e605e49 [RN] Mark some internal animated stuff as protected 2015-08-19 21:16:38 -07:00
Christopher Chedeau cf617640f3 [OpenSource] Fix 2048
Summary:
There were two issues:
(1) it was using /Users/sahrens as a path
(2) needed to remove RCTAnimationExperimental which doesn't exist anymore and add RCTWebSocket
2015-08-19 20:23:20 -07:00
Christopher Chedeau dd7945ae37 [OpenSource] Fix TicTacToe
Summary:
Needed to link RCTWebSocketManager to the project as instructed by the following issue:
https://github.com/facebook/react-native/issues/2256
2015-08-19 20:05:13 -07:00
Jing Chen cc96962e3d [react-native] Revert D2346396 to bring back JS stack traces 2015-08-19 18:07:15 -07:00
Amjad Masad ec82ffa52b [react-packger] Add a timeout on transform jobs
Summary:
There's been a case where Babel can hang indefinitely on a file parse/transform. Possibly related to https://github.com/babel/babel/issues/2211

This adds a timeout to transform jobs and throws an error informing the user of the offending file. The timeout interval defaults to 10 seconds, but can be changed via an option.
2015-08-19 17:42:28 -07:00
Alex Kotliarskyi c5c25c15ea [RN] Show only file name in RedBox 2015-08-19 17:35:25 -07:00
Amjad Masad 24689006ab [react-packager] Remove unnecessary 'chalk' module mock 2015-08-19 17:28:18 -07:00
Amjad Masad e76e60f88d [react-packager] Make the fs mock async 2015-08-19 17:17:15 -07:00
Ben Alpert 5a2d2007a4 [React Native] Fix infinite loop in css-layout
Summary:
Manual pick of https://github.com/facebook/css-layout/commit/9001a3d2 since we're still lagging behind the upstream. Fixes #1378.
2015-08-19 16:39:35 -07:00
Martin Bigio d9bd445940 Unbreak Catalyst 2015-08-19 16:25:14 -07:00
Amjad Masad b4100b8332 [react-packager] Wait for haste map before accepting any requests
Summary:
D2319999 introduced a regression where we stopped waiting for the "build haste map" step to finish before we accept any requests. This makes sure that we block on that.

Need to unbreak with this, but will follow up with a test to catch this in the future.
2015-08-19 16:17:37 -07:00
Tim Yung 966a3bbc66 RN: Style Tweaks to Chrome Debugger UI 2015-08-19 16:00:03 -07:00
Abhishek Sood 5fc2d67ee5 Revert "@build-break" 2015-08-19 15:21:16 -07:00
Abhishek Sood d64ac20119 Revert "[ReactNative] Open source NetworkingModule" 2015-08-19 15:20:09 -07:00
Ben Alpert 0f3ea9fb8c [ReactNative] Fix switching to null event listener 2015-08-19 15:02:25 -07:00
Martín Bigio f4c7bb1103 [react-packager] Fix bug on Bundles Layout algorithm
Summary:
The layout algorithm wasn't getting deep into the sync dependencies recursively to async dependencies.
2015-08-19 14:20:38 -07:00
Abhishek Sood 1aa29ceaf2 @build-break 2015-08-19 14:12:22 -07:00
Martin Konicek 9c32a7a940 [ReactNative] Prepare for putting RN Android OSS files in 2015-08-19 12:13:56 -07:00
Martin Konicek ade571065e [ReactNative] Open source NetworkingModule 2015-08-19 11:47:10 -07:00
Martin Konicek 3d0cd480d2 [ReactNative] Naming: RCTSwitch -> AndroidSwitch 2015-08-19 10:28:28 -07:00
James Ide deaef94471 [Podspec] Remove AnimationExperimental subspec and fix Image subspec
Summary:
AnimationExperimental is gone; remove it. The Image subspec now depends on the networking code, so we have to pull in those files. These changes were necessary to publish 0.10.0-rc to CocoaPods, so would be convenient to get them into master for 0.11.

Fixes #2354
Closes https://github.com/facebook/react-native/pull/2341
Github Author: James Ide <ide@jameside.com>
2015-08-19 09:59:49 -07:00
Nick Lockwood 26c4be62c8 Fixed test flakiness due to a race condition with RCTRedBox
Summary:
The test runner relied on checking the current error message in the RCTRedbox, which is a singleton (yay, shared mutable state!). This lead to some tests that worked individually but failed when run together due to error messages in RCTRedBox left over from previous tests.

I've replaced the call to -[RCTRedBox currentErrorMessage] by injecting a custom logging function to intercept the errors at source, which is a much more reliable solution.
2015-08-19 03:41:31 -07:00
Alex Kotliarskyi b18d73b568 [RN] Unbreak packager 2015-08-18 18:29:32 -07:00
Martín Bigio 291c8ff9ec [react-packager] Modernize Activity to ES6 2015-08-18 15:25:18 -07:00
Martín Bigio 51596f8674 [react-packager] Modernize AssetServer to ES6 2015-08-18 14:38:40 -07:00
Christopher Chedeau ede5fa7b39 Merge pull request #2374 from foghina/cli_contributing
[cli] add docs on how to contribute to the CLI
2015-08-18 11:22:08 -07:00
Krzysztof Magiera 67746fea2f [ReactNative] Use FbHttp for handling http requests from React Native. 2015-08-18 09:12:40 -07:00
Felix Oghină 621a2c486f [cli] add docs on how to contribute to the CLI 2015-08-18 15:56:26 +01:00
Nick Lockwood 76a9baaf2f Fixed bug where method calls containing struct arguments would fail silently
Summary:
The arg block for handling structs did not return a value, which was being intepreted as failure. This diff returns YES for success, and also adds an error log for this case so future regressions won't fail silently.
2015-08-18 07:35:26 -07:00
Felix Oghină e0e6fbfa8c Merge pull request #2373 from foghina/fix_e2e
[e2e] fix e2e tests
2015-08-18 12:10:54 +01:00
Felix Oghină 3b7bffa2a1 [e2e] fix e2e tests
* use new _flowconfig in generator template
* increase sinopia max_body_size
* remove breaking `cd` command from e2e-test.sh
2015-08-18 11:51:03 +01:00
Natthu Bharambe a4e64196bc Update GLOBAL.process instead of over-writing during initialization. 2015-08-17 16:47:10 -07:00
Ben Alpert 65692b7235 [ReactNative] Don't redbox for React warnings when not using Chrome executor 2015-08-17 16:02:10 -07:00
Nick Lockwood 8d1e02b8bd Convert alloc/init to new to please linter 2015-08-17 08:46:00 -07:00
Dorota Kapturkiewicz 869ff92dbc [ReactNative] add importantForAccessibility to accessibility sample app 2015-08-17 07:17:44 -07:00
Mike Armstrong bce7b9c638 generalise handling of uniforms and samplers 2015-08-17 07:13:17 -07:00
Pieter De Baets 65713992c4 Let native modules know when root views get added and removed 2015-08-17 07:12:06 -07:00
James Ide 12d5f0d6f4 [Views] Change rasterization scale to the main screen's scale
Summary:
`view.screen` can be nil if the view has not yet been added to the view hierarchy (e.g. new view), so we should use `[UIScreen mainScreen]` instead.

In the future, if we need to support multiple screens, one possible fix is to set the rasterization scale in didMoveToWindow/Superview. For now we have just one screen, though.
Closes https://github.com/facebook/react-native/pull/2334
Github Author: James Ide <ide@jameside.com>
2015-08-17 06:54:55 -07:00
Felix Oghină f0dd9fb358 Merge pull request #2298 from foghina/yo
[cli] convert project generation to use yeoman
2015-08-17 13:51:24 +01:00
Pieter De Baets 261f9434e5 Avoid dispatch_async in RCTRootView when bridge has already started
Summary:
There's no good reason for initialProperties to be mutable after the RCTRootView has been created. Passing it in through the constructor means we can skip one dispatch_async.
2015-08-17 05:34:25 -07:00
Ludo Fardel 8460db57bc Make flow check async 2015-08-17 03:13:16 -07:00
Amjad Masad ca38908423 [react-packager] In production resolve __DEV__ to NODE_ENV === 'development' 2015-08-15 17:07:41 -07:00
Amjad Masad 3388d8fe79 [reat-packager] Switch platform resolution based on query param
Summary:
Currently the platform selection is controlled by the blacklist. However, since we want to use the same server instance for cross-platform development, we need this to be controlled per request.

One outstanding issue, is that the DependencyGraph class wasn't designed that way and it doesn't have a per-request state. This means that with the current design race conditions is possible. If we got a request for a different platfrom while processing the previous request, we may change the outcome of the previous request.

To fix this a larger refactor is needed. I'll follow up a diff to do that.

Finally, so I don't break the universe like last time, I'll leave it up to the RN guys to update the call sites.
2015-08-15 13:28:18 -07:00
Amjad Masad 9eb5151bd2 [react-native] Set NODE_ENV and use node-env-inline plugin
Summary:
This sets NODE_ENV based on the value of the `dev` option when bundling the apps. This would then be inlined by the node-env-inline babel plugin. And finally -- if unreachable -- will be dead-code-eliminated by uglify.

This is not used in development because we set NODE_ENV to the value of __DEV__, which can be switched via a query param. However, the plugin has minimal overhead and to avoid complexity in the transformers I just enabled it by default.
2015-08-15 13:25:09 -07:00
Amjad Masad 9d96d00163 [react-native] Check in babel-plugin to inline __DEV__
Summary:
This plugin resolves __DEV__ to the value of `NODE_ENV === 'development'`. This can then be evaluated and dead code can be removed by uglifyjs.
2015-08-15 13:17:48 -07:00
James Ide 758ec76cb6 Merge pull request #2340 from chentsulin/patch-1
Add npm version badge
2015-08-14 20:55:09 -07:00
C. T. Lin 05b17a811e Add npm version badge 2015-08-15 11:42:33 +08:00
Christoph Pojer 5786a05e9e Merge pull request #2339 from ide/jest
[jest] Update jest-cli version to 0.5
2015-08-14 16:13:33 -07:00
Alex Kotliarskyi 324d154cf7 [ReactNative] Add ability to listen for Packager events 2015-08-14 14:28:45 -08:00
James Ide 5153ce0a03 [jest] Update jest-cli version to 0.5
npm install will get a little nicer since it can read from npm instead of always having to redownload from github.
2015-08-14 14:49:37 -07:00
Martín Bigio 3be2b1d966 [react-packager] Modernize Server to ES6 2015-08-14 12:34:23 -08:00
Martín Bigio 0623371814 [react-packager] Cache in which bundle is each module
Summary:
Not that at the moment a module can be present in multiple bundles, so the new API will return only one of them. In the near future we'll impose the invariant that a module can only be present in a single bundle so this API will return the exact bundle in which it is.
2015-08-14 12:30:30 -08:00
Martín Bigio 76e37c4423 [react-packager] Modernize Server-test by using ES6 features 2015-08-14 12:23:02 -08:00
Amjad Masad 8bd1cb8cce [react-native] Add babel-plugin-node-env-inline plugin
Summary:
Check in the `process.env.NODE_ENV` inline plugin. This will be used in conjuction with uglifyjs to eliminate dead code resulting from environment checks.
2015-08-14 10:46:05 -08:00
Alexsander Akers 91c8362176 Rename RCTReachability to RCTNetInfo 2015-08-14 08:20:01 -08:00
Nick Lockwood decf35c271 Fixed log prefixes to provide more context for prop binding errors 2015-08-14 08:01:34 -08:00
Nick Lockwood 3f5fcadbd5 Fix null values in network requests 2015-08-14 05:16:02 -08:00
Alexsander Akers 96277ca3f5 Add HSL/HSLA support 2015-08-14 04:48:20 -08:00
Alexsander Akers 0f14933948 Enable transparent modal presentation with <Modal />
Summary:
Enable transparent modal backgrounds using `UIModalPresentationCustom` modal presentation style.
2015-08-14 04:47:12 -08:00
Alexsander Akers dc01ecbc98 Remove now useless comment 2015-08-14 04:46:26 -08:00
Alex Akers 5c0805b071 Fix failing UIExplorer test (after isValid removal) 2015-08-14 04:27:27 -08:00
Dorota Kapturkiewicz a2c51b3b28 [ReactNative] expose importantForAccessibility to JS 2015-08-14 03:28:22 -08:00
Andrei Coman e9735556f6 [ReactNative] Sync [react_native] Fix keyboard behavior for android 2015-08-14 02:58:37 -08:00
Pieter De Baets fa07736ee1 Remove isValid from RCTInvalidating
Summary:
We only actually use it on RCTBridge and RCTJavaScriptExecutor, so add it to these interfaces explicitly
2015-08-14 01:57:18 -08:00
Zack Gomez f5d68f6ecb [ReactNative] Fix pixel rounding
Summary:
Too many rounds, we only want/need one.
2015-08-13 18:04:49 -08:00
Amjad Masad bc28a35bda [react-packager] Use module objects across the codebase (rid of getPlainObject etc)
Summary:
Instead of using plain objects and having to convert to and from them we just use the `Module` class across the codebase.
This seems cleaner and can enforce the type as opposed to fuzzy objects.
2015-08-13 15:52:31 -08:00
Amjad Masad 7bfc1baf7f [react-packager] Upgrade uglifyjs for Max call stack bug
Summary:
We're hitting an issue with large code size and `Maximum call stack size exceeded` error. https://github.com/mishoo/UglifyJS2/issues/414
We're seeing on inconsistently failing on landcastle.
2015-08-13 14:35:13 -08:00
Amjad Masad abce124198 [react-packager] Remove horribly outdated example_project
Summary:
Removes some old unused code.
2015-08-13 13:02:52 -08:00
Martín Bigio 5cad2e9370 [react-packager] Introduce Bundler
Summary:
Introduce a Bundler capable of generating the layout of modules for a given entry point. The current algorithm is the most trivial we could come up with: (1)it puts all the sync dependencies into the same bundle and (2) each group of async  dependencies with all their dependencies into a separate bundle. For async dependencies we do this recursivelly, meaning that async dependencies could have async dependencies which will end up on separate bundles as well.

The output of of the layout is an array of bundles. Each bundle is just an array for now with the dependencies in the order the requires where processed. Using this information we should be able to generate the actual bundles by using the `/path/to/entry/point.bundle` endpoint. We might change the structure of this json in the future, for instance to account for parent/child bundles relationships.

The next step will be to improve this algorithm to avoid repeating quite a bit dependencies across bundles.
2015-08-13 12:57:55 -08:00
Pieter De Baets c084793e91 Fix ModalFullScreenView's window not dismissing after being removed 2015-08-13 08:55:40 -08:00
Martino Luca 41a88c3eb1 Fixing typos in imports 2015-08-13 08:36:06 -08:00
Alex Akers f552495e7f Fix NavigatorIOS freeze when pushing before initialization completes
Summary:
This freezes the app in the UIExplorer because we try to push a new view controller onto the screen before the navigator finishes loading. This was exacerbated by @tadeuzagallo's diff that made the loading even faster. Hehe
2015-08-13 08:24:24 -08:00
Nick Lockwood 7232b1bbc7 Fixed image clipping / resizing logic 2015-08-13 08:13:55 -08:00
Alex Akers 672b77f355 Perform clip update on RCTScrollView in increments of 50 pt
Summary:
This diff removes calls to `-updateClippedSubviews` by only re-clipping when the scroll view moves by a certain number of pixels.

leeway = 50pt => 46.9% of calls removed
leeway = 10pt => 13.2% " " "
2015-08-13 07:56:41 -08:00
Tadeu Zagallo c9f5d229db Merge pull request #2323 from tadeuzagallo/Updates_Thu_13_Aug
Updates thu 13 aug
2015-08-13 14:50:09 +01:00
Tadeu Zagallo 12492d8d94 [ReactNative][Travis] Attempt to fix tests 2015-08-13 14:39:01 +01:00
Tadeu Zagallo b9dc29bcb3 [ReactNative] Fix SampleApp xcodeproj configuration
Summary:
Make SampleApp scheme shared.
2015-08-13 05:29:28 -08:00
Tadeu Zagallo eeb0adca43 [ReactNative][Website] Move bluebird to depencies instead of devDependencies 2015-08-13 14:10:56 +01:00
Tadeu Zagallo 28fb229266 [ReactNative] Fix e2e tests 2015-08-13 13:50:04 +01:00
Tadeu Zagallo 4daca092d2 [ReactNative][Website] Fix tests 2015-08-13 13:31:50 +01:00
Nick Lockwood 0487c55c25 Removed unnecessary overhead in RCTConvert functions 2015-08-13 04:08:17 -08:00
Nick Lockwood 1d072076db Reduce +[UIImage imageNamed:] overhead 2015-08-13 03:33:04 -08:00
Amjad Masad 7750db05e6 [react-packager] Set a lifetime on workers to avoid memory leaks 2015-08-12 19:26:26 -08:00
James Ide 08d1bc8c9f [TextInput] Fix multiline TextInput so text and cursor stay in bounds
Summary:
With a multiline TextInput, the text is initially rendered correctly but once you try to edit it, the cursor slides off the top of the view and out of its bounds. Also if the TextInput is scrollable, you can scroll the text out of the bounds of the view, which looks buggy unless you clip the overflow. This occurs because the top content inset is applied to the RCTTextView instead of the UITextView's text container.

This diff fixes both bugs by applying the vertical insets to the UITextView's textContainerInset instead of the RCTTextView's frame (which is a wrapper around a real UITextView).

The left inset is still applied to the frame because there is a bug with the text rendering when the left textContainerInset is negative: the initial text doesn't show up until you focus the text view. The bug doesn't occur when setting the right textContainerInset, so I apply this workaround to only the left inset.

Closes https://github.com/facebook/react-native/pull/2297
Github Author: James Ide <ide@jameside.com>
2015-08-12 14:50:42 -08:00
Martín Bigio cfcf604b3d [react-packager] Introduce require.ensure
Summary:
This is the first step to add support for splitting the JS bundle into multiple ones. This diff adds support for keeping track of the async dependencies each module has. To do so we introduce the following syntax:

  require.ensure(['dep1', 'dep2, ..., 'depN'], callback);

Where the callback function is asynchronously invoked once all the indicated modules are loaded.

Internally, the packager keeps track of every set of async dependencies a module has. So for instance if a module looks like this:
  require.ensure(['dep1'], () => {...});
  require.ensure(['dep2'], () => {...});

the `Module` object will keep track of each set of dependencies separately (because we might want to put them on separate bundles).
2015-08-12 12:23:42 -08:00
Amjad Masad 309326db2e [react-packager] Rename 'Package' to 'Bundle'
Summary:
The word Package is overloaded, it may mean npm package, or may mean a collection of bundles. Neither is what we mean. We mean `bundle`.

This renames it and modernize some of the Bundler code.
2015-08-12 12:09:01 -08:00
Martin Konicek c483db1b88 [ReactNative] Open source ProgressBarAndroid, remove example from the RN launcher 2015-08-12 12:02:17 -08:00
James Ide abdd0e09b3 [npm] Upgrade to stacktrace-parser 0.1.2, which supports io.js
Summary:
stacktrace-parser used to list only Node 0.10 under its list of supported engines. This new version includes Node 1.x and 2.x (i.e. io.js) as well, which addresses the warning during `npm install`.

There's no problem with using the older version of stacktrace-parser; this just clears the warning.

Closes https://github.com/facebook/react-native/pull/1738
Github Author: James Ide <ide@jameside.com>
2015-08-12 11:12:59 -08:00
Nick Lockwood a86e6b76fb Fixed fuzzer app and ensured that React does not crash when fuzzed 2015-08-12 06:14:36 -08:00
Felix Oghină f83675d191 [cli] convert project generation to use yeoman 2015-08-12 12:04:27 +01:00
Nick Lockwood 39230000de Fix ReactART 2015-08-11 22:44:45 -08:00
Alex Kotliarskyi 1e1efce69b Add .watchmanconfig
Summary:
This file tells watchman to watch this folder if "root_restrict_files"
is turned on.

Fixes #2042
Closes https://github.com/facebook/react-native/pull/2263
Github Author: Alex Kotliarskyi <alex.frantic@gmail.com>
2015-08-11 16:39:49 -08:00
Martín Bigio 70624dc347 [react-packager] Fix Cache-test 2015-08-11 11:27:15 -08:00
Chace Liang eb402d8c7d [e2e] Fix TouchableHighlight in e2e test 2015-08-11 10:53:50 -08:00
Christopher Chedeau 5ebe0ed717 Bust jest caching and fix tests 2015-08-11 11:02:19 -07:00
Nick Lockwood a5e9f83a0a Implemented lazy parsing of method signatures to improve TTI 2015-08-11 08:49:13 -08:00
Adam Roth 57a6a02dff [CameraRoll] Image orientation fix for #1845
Summary:
PR for #1845

Use ALAssetOrientationUp for image orientation.

Originally committed at https://github.com/facebook/react-native/commit/b34a85f4da87c62656ca9d29c5085a46e768d147
Closes https://github.com/facebook/react-native/pull/2214
Github Author: Adam Roth <adamjroth@gmail.com>
2015-08-11 08:44:57 -08:00
Christopher Chedeau 0d636a017d Updates from Tue 11 Aug 2015-08-11 08:42:07 -07:00
Nick Lockwood 4d817245f7 Fix crash when using alert() polyfill due to null callback 2015-08-11 07:31:19 -08:00
Tadeu Zagallo e2d9ddce4c [ReactNative] Fix cast warning in RCTProfile
Summary:
Buck is more strict than our current xcodeproj configuration is keeps warning
about this implicit cast, it's quite annoying.
2015-08-11 06:49:39 -08:00
Nick Lockwood 48af214216 Simplified event registration
Summary:
Our events all follow a common pattern, so there's no good reason why the configuration should be so verbose. This diff eliminates that redundancy, and gives us the freedom to simplify the underlying mechanism in future without further churning the call sites.
2015-08-11 06:41:04 -08:00
Yusef Napora 2fe1ac2a83 [Image] Fix invalid CGContext when one dimension of destination Image size == 0
Summary:
Addresses #1534

When an image has a known width, but a height of 0 (which can happen if `flex: 1` is set on the `Image` element), `RCTDownloadManager` attempts to scale it to an invalid size, which results in a `NULL` `CGContextRef` and some scary warnings from UIKit:

```
 <Error>: CGContextTranslateCTM: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.
```

This adds a check for zero width or height to the `RCTClipRect` function.  If either dimension is zero, it is calculated based on the aspect ratio of the source image.  This ensures that we don't try to create an invalid `CGContextRef`, and that images with an unknown dimension are still scaled, blended, etc.
Closes https://github.com/facebook/react-native/pull/2278
Github Author: Yusef Napora <yusef@napora.org>
2015-08-11 06:30:34 -08:00
Tom Hastjarjanto 2424a215e0 [Image] Fix default Image functionality
Summary:
In the latest 0.9.0-rc of React Native, the default image won't load due to a typo and a missing condition in `setImage`. This PR contains fixes for both of them.
Closes https://github.com/facebook/react-native/pull/2269
Github Author: Tom Hastjarjanto <tom@intellicode.nl>
2015-08-11 05:19:04 -08:00
Nick Lockwood f5d8e4d6e0 Fixed a strongSelf that was accidentally marked as __weak 2015-08-11 04:46:56 -08:00
Nick Lockwood 68f1a223fb Fixed bug when updaing props for RCTNetworkImageView 2015-08-11 04:19:28 -08:00
Evan Solomon 51ccdfa36a [Babel] Upgrade babel and regenerator to the latest version
Summary:
See https://github.com/babel/babel/commit/c0fd4c1f9e0b18231f585c4fa793e4cb0e01aed1
Closes https://github.com/facebook/react-native/pull/1753
Github Author: Evan Solomon <evan@evanalyze.com>

@allow-crlf-text
2015-08-10 20:37:39 -08:00
Dave Sibiski e163df3567 Adds process.env.NODE_ENV polyfill
Summary:
There are many libraries that use `NODE_ENV` to check whether the code is running in
"production" mode or not. This allows those library authors to not have to add conditionals
for React Native.

One such library is Redux: https://github.com/gaearon/react-redux/pull/40

Thanks to @brentvatne for providing the solution via this tweet (via his phone in the airport 😉): https://twitter.com/notbrent/status/630440250951749632

/cc @vjeux @gaearon @zpao @amasad
Closes https://github.com/facebook/react-native/pull/2279
Github Author: Dave Sibiski <dsibiski@gmail.com>
2015-08-10 19:51:05 -08:00
Martín Bigio a303a42e28 [react-packager] Add more granular Activity logging 2015-08-10 16:25:04 -08:00
Martín Bigio 2afeb8fbe6 [react-packager] Promote Cache to top level
Summary:
The cache is only used for JSTransformer at the moment. We're doing IO and some computation to get each module's name, whether is a haste or node module and it's dependencies. This work happens on startup so by caching this value we shouldbe able to reduce the start up time. Lets promote the Cache to the Packager level to be able to use it by any of the components of the packager. For now, on this diff we'll start using it to cache the mentioned fields.

Also we had to introduce the concept of fields in the cache as manually merging the date we had for each path is not possible as we're using promisses all around. With the new API, each field is a promise.

@amasad and I did some manual testing to measure the impact of this change and looks like it's saves 1 second when building the haste map (which represents 50% of the time). Overall this reduces 1 second of start up time which was currently about 8s on my mac book pro.
2015-08-10 16:25:03 -08:00
Christopher Chedeau 56059e92df Merge pull request #2288 from ide/iojs-docs
[docs] remove instructions to install node/io.js with brew
2015-08-10 15:46:36 -07:00
Nick Lockwood 5d20b9065d Fix RKHTTPRequestHandler crash 2015-08-10 13:46:47 -08:00
James Ide fd4e75644f [docs] remove instructions to install node/io.js with brew
nvm is way better than homebrew for managing node installations:

 - can install multiple versions
 - can choose which version of node to install
 - easy to clean up under ~/.nvm
 - there are still some rough edges with /usr/local on El Cap -- nvm avoids those altogether
2015-08-10 14:31:48 -07:00
Nick Lockwood 6e2e02ab08 Merge pull request #2281 from jacob-israel-turner/patch-2
Grammar
2015-08-10 22:00:03 +01:00
Nick Tuckett f309540f69 [react_native] JS files from D2327386: Simplified unimplemented SliderIOS on Android 2015-08-10 08:33:39 -08:00
Nick Lockwood b489c9aa43 Fixed perf issue due to use of regex in +[RCTConvert NSURL:] 2015-08-10 07:13:36 -08:00
Jacob Turner 5b5cadeb30 Grammar 2015-08-10 14:34:27 +01:00
Dorota Kapturkiewicz 59b974eafb [ReactNative] make AdsManager floater and TouchableHighlight accessible 2015-08-10 04:41:09 -08:00
Christopher Chedeau 50d5f86bf8 Merge pull request #2273 from vjeux/fix_az
[Website] Fix a-z order in props
2015-08-08 10:28:39 -07:00
Christopher Chedeau c1a0a72275 [Website] Fix a-z order in props 2015-08-08 10:28:05 -07:00
Nick Lockwood 94caefa9c2 Converted RCTDevLoadingView to a module and fixed url display when using delegate 2015-08-08 03:31:49 -08:00
Nick Lockwood b82ac9bf07 Reverted to pre-init of queues to fix UIExplorer tests. 2015-08-08 01:47:43 -08:00
Alex Kotliarskyi e21fb91786 [ReactNative] Show banner promoting DevTools
Summary:
When React DevTools is not installed, React prints a tiny warning to the console.
However, in debugger.html we have a lot of free space we could use to promote
React DevTools more actively.
2015-08-07 15:23:22 -08:00
Philipp von Weitershausen 0f5190e9f3 [React Native] Provide a way to get a list of registered apps in AppRegistry 2015-08-07 11:05:25 -08:00
Tadeu Zagallo 331e4a96e9 [ReactNative] Preload ModuleData queue
Summary:
The module's methodQueue wasn't being created when accessing the modules directly
on the bridge, without going through JS. Preload the queue for now to fix internal
breakages, but I'll figure out a better way to keep it lazy afterwards.
2015-08-07 11:05:09 -08:00
Ben Alpert 2d66e10ec4 [ReactNative] Delay sending touches to JS until dependent (native) gesture recognizers fail
Summary:
Previously, JS touches were being interpreted simultaneously with native gesture recognizers.
2015-08-07 10:56:26 -08:00
Alexander Kotliarskyi 3aec8ee72d Merge pull request #2267 from frantic/hide-npm-output
Hide npm output when doing react-native init
2015-08-07 11:37:49 -07:00
Felix Oghină 205a2c0bfc [react_native] JS files from D2318945: Implement a slider for React Native Android 2015-08-07 10:15:52 -08:00
Alex Kotliarskyi 2ddf3d942d Hide npm output when doing react-native init 2015-08-07 10:59:59 -07:00
Christopher Chedeau a91f44d7fd Merge pull request #2264 from vjeux/platform_props
[Website] Platform-specific props
2015-08-07 10:39:04 -07:00
Christopher Chedeau 6e9ceaa348 [Website] Platform-specific props
We are annotating platform-specific props with a special @platform tag in the docblocks. This pull request adds a little [ios] tag before the name and sorts the props such as generic ones are before platform-specific ones.
2015-08-07 10:31:07 -07:00
Tadeu Zagallo 6cd0709bc0 [ReactNative] Parellelise bridge startup
Summary:
Parallelise the bridge startup so we don't keep waiting for the source to load.
2015-08-07 06:48:30 -08:00
Nick Lockwood 3cef3010e6 Fix RCTAssert logic 2015-08-07 06:11:49 -08:00
Andy Street 1d452f3e4d [ReactNative] Remove testID from root view 2015-08-07 05:23:40 -08:00
Tj c933087567 CMD+R should post a refresh notification.
Summary:
For the sake of consistency, `cmd+r` should just post a refresh notification. This way other tools can also observe and react to the refresh without ugly hacks.
Closes https://github.com/facebook/react-native/pull/2175
Github Author: Tj <tfallon@mail.depaul.edu>
2015-08-07 04:39:21 -08:00
Vladislav Alexeev 9edad17a15 Use Dynamic Text Size Multipliers from Wilde in ReactNative Module 2015-08-07 03:18:20 -08:00
Nick Lockwood ffa7dbcbf1 Fixed onLayout redbox issue 2015-08-07 02:58:48 -08:00
Jason Zhekov a8211e32d2 Fix typo
Summary:
Closes https://github.com/facebook/react-native/pull/2055
Github Author: Jason Zhekov <jasssonpet@gmail.com>
2015-08-06 20:22:24 -08:00
Nick Lockwood deba13f698 Refactor RCTUIManager
Summary:
Moved the view creation & property binding logic out of RCTUIManager into a separate RCTComponentData class - this follows the pattern used with the bridge.

I've also updated the property  binding to use pre-allocated blocks for setting the values, which is more efficient than the previous system that re-contructed the selectors each time it was called. This should improve view update performance significantly.
2015-08-06 15:49:35 -08:00
James Ide 3309f6da80 Merge pull request #2252 from ide/iojs-docs
[Docs] Update setup instructions to install io.js 2.x instead of latest
2015-08-06 14:24:15 -07:00
James Ide 554f23276b [Docs] Update setup instructions to install io.js 2.x instead of latest
The ws module has not been updated to work with 3.x quite yet.
2015-08-06 14:22:45 -07:00
Martín Bigio aefdf82cdc [JSAppServer] Don't keep track of not found packages 2015-08-06 11:34:56 -08:00
Andrei Coman 327f84b967 [ReactNative] Sync [react_native] Implement TextInput editable 2015-08-06 11:07:06 -08:00
Tadeu Zagallo 48548fedbf [ReactNative] Fix RCTTextField crash on iOS7
Summary:
RCTTextField was its own delegate, that was causing a stall on the main thread,
see more here:
http://stackoverflow.com/questions/19758025/uitextfield-delegate-jumping-to-100-cpu-usage-and-crashing-upon-using-keyboard
2015-08-06 09:56:17 -08:00
Andrei Coman 0d981c06de [ReactNative] Sync [react_native] Text Input missing letters fix 2015-08-06 04:59:09 -08:00
Hedger Wang 8463625bd9 [Navigation]: Add a method to map the stack routes to an array.
Summary:
Add a method to map the stack routes to an array.
2015-08-06 02:01:59 -08:00
Thomas Aylott a6ff11f1d2 [react-packager] Fixes stack traces
Summary:
TransformErrors weren't showing stack traces, making it hard to debug problems in transformer code.
2015-08-05 12:46:30 -08:00
James Ide d4eac3ddca [RFC][Rendering] Add shouldRasterizeIOS to View components
Summary:
Exposes the `shouldRasterize` property. Fixes #1986.
Closes https://github.com/facebook/react-native/pull/2226
Github Author: James Ide <ide@jameside.com>
2015-08-04 15:37:38 -08:00
Tj d8f43105ed [ListView] Fix RCTScrollView stickyHeader touch passing.
Summary:
Point must be converted to the stickyHeader's coordinate space and then passed to the stickyHeaders hitTest:withEvent: method in order to be correctly routed to any subviews of the stickyHeader.

This resolves this [issue](https://github.com/facebook/react-native/issues/2075).
Closes https://github.com/facebook/react-native/pull/2224
Github Author: Tj <tfallon@Tjs-MBP.local>
2015-08-04 17:10:19 -08:00
Nick Lockwood f165bbaf4e Use +[RCTConvert NSURL:] everywhere instead of +[NSURL URLWithString:]
Summary:
RCTConvert's URL: method gracefully handles unescaped urls, local file urls, urls containing unicode, etc. URLWithString doesn't.
2015-08-04 16:26:16 -08:00
Hedger Wang 222594cb44 [Navigator] A method subtract to compute the diff between stack mutation.
Summary:
When mutation of a stack happens, we'd like to compute the diff of the stacks (before and after) so that
we can know which routes are removed in the new stack.

This diff adds a new method `substract` which does what we need.
2015-08-04 16:16:17 -08:00
Nick Lockwood 274769fd8c Added Unicode URL test 2015-08-04 15:37:05 -08:00
Nick Lockwood 9f81d6726c Merge pull request #2227 from harrykiselev/patch-1
Fix link to Apple Developer account registration.
2015-08-04 22:16:26 +01:00
Harry V. Kiselev 01deb0b03d Fix link to Apple Developer account registration. 2015-08-05 00:07:42 +03:00
Brent Vatne 257bbb5255 [Docs] Add newsletter to top-level header 2015-08-04 13:47:52 -07:00
Alex Akers bb883bfb61 Update offscreen image fix with window checking
Summary:
2015-08-04 08:05:12 -08:00
James Ide eab7b00cee [JSContext] Define ContextExecutor.setContextName for debugging
Summary:
Add a method that lets JS set the name of the JSContext for debugging purposes. I check `JSGlobalContextSetName` since it is not available on iOS 7.

Closes https://github.com/facebook/react-native/pull/2144
Github Author: James Ide <ide@jameside.com>
2015-08-04 06:08:14 -08:00
James Ide 47e1d1aef8 [Async] Enable async/await and update UIExplorer and tests
Summary:
- Enables async/await in .babelrc and transformer.js
- Adds regenerator to package.json. Users still need to explicitly require the regenerator runtime -- this is so that you only pay for what you use.
- Update AsyncStorage examples in UIExplorer to use async/await
- Update promise tests in UIExplorer to use async/await in addition to the promise API

Closes https://github.com/facebook/react-native/pull/1765
Github Author: James Ide <ide@jameside.com>
2015-08-04 05:35:13 -08:00
Amjad Masad 18452940f0 [react-packager] Add support for platform in the resolver
Summary:
Teach the resolver about platform-based resolution. The platform extension is inferred from the entry point.
It works for haste modules, as well as node-based resolution.
2015-08-03 18:29:20 -08:00
Christopher Chedeau afdeefc864 [Animated] Remove rebound dependency
Summary:
We already reimplement the spring computation, we were only using rebound for the tension/friction conversion. Turns out that it is quite small so we can just embed it. I'm doing this as I'm preparing for doing a web version of the feature and I'm trying to minimize the number of dependencies.

https://github.com/facebook/rebound-js/blob/master/rebound.js#L932
2015-08-03 15:24:40 -08:00
Nick Lockwood 6a4b83c16f Fixed retain cycle that caused RCTModuleMethods to leak
Summary:
Some of the log statements inside argument blocks in RCTModuleMethod were directly accessing ivars, thereby causing a retain cycle that retained the class. I've fixed this by making the access explicit via weakSelf.
2015-08-03 08:46:52 -08:00
Martin Konicek c63992437b [ReactNative] LayoutAnimation docs
Summary:
Improve https://facebook.github.io/react-native/docs/layoutanimation.html
2015-08-03 07:52:31 -08:00
=?UTF-8?q?=E9=9A=90=E9=A3=8E?= 44ce9194a2 Profiling will not work if the bundleURL has no port.
Summary:
If the bundleURL has no port(default 80) , the profile request URL will be `<scheme>://<host>:<null>/profile`, that will not work. So we should decide if the port exsits first.
Closes https://github.com/facebook/react-native/pull/2131
Github Author: =?UTF-8?q?=E9=9A=90=E9=A3=8E?= <yinfeng.fcx@alibaba-inc.com>
2015-08-03 07:51:33 -08:00
Alex Akers 3e21f39a77 Remove rendered RCTText contents when moving offscreen
Summary:
When an `RCTText` instance moves offscreen (possibly due to parent clipping), we unset the layer's contents until it comes onscreen again.
2015-08-03 05:43:16 -08:00
Alex Akers e9f69bc2e4 Reorganize SampleApp
Summary:
2015-08-03 03:32:03 -08:00
Dorota Kapturkiewicz e3ed572c01 [ReactNative] accessibility test app 2015-08-03 01:42:35 -08:00
Brent Vatne e2a2472af4 Merge pull request #2194 from ide/animation-docs
[Docs] Remove sections on AnimationExperimental and Pop
2015-08-02 16:16:13 -07:00
Brent Vatne 5222be0edf [Docs] Fix typo in docs index 2015-08-02 16:14:50 -07:00
James Ide 0b5e229ed2 Merge pull request #2205 from muan/title
[Docs] Add dynamic page title
2015-08-02 15:04:03 -07:00
Mu-An Chiou 129d1548a8 Add dynamic page title
Currently all the pages have the same title, making it hard to
tell which page is while when user has multiple tabs opened.
This adds 'title' to Site so a page title can be passed in and
prepended to the default title
2015-08-02 22:07:53 +08:00
James Ide bc56eb1439 Merge pull request #2201 from threepointone/patch-1
doc typo
2015-08-01 12:34:42 -07:00
Sunil Pai 5a918227f2 doc typo
match member names
2015-08-01 23:43:29 +05:30
Nick Lockwood 95d1fd142e Fixed null argument errors for timers and layout animations 2015-08-01 06:40:27 -08:00
Philipp von Weitershausen 3e79838a31 [React Native] sync JS for D2287297 2015-07-31 21:31:46 -08:00
Kevin Gozali ee8b50c955 [ReactNative] fix up XMLHttpRequest failures 2015-07-31 21:31:45 -08:00
James Ide 4a93d23af2 [Docs] Remove sections on AnimationExperimental and Pop
AnimationExperimental has been removed and Pop has been superseded by Animated.
2015-07-31 17:17:22 -07:00
Philipp von Weitershausen d858d0c4e0 [ReactNative][Android] JS for D2294884: Allow XHR to send native files, as HTTP body or via multipart FormData 2015-07-31 15:50:49 -08:00
Brent Vatne f41663a2df [WebView] Replace RKWebView with RCTWebView in log message
Summary:
Easy merge, just a small change in log message
Closes https://github.com/facebook/react-native/pull/2061
Github Author: Brent Vatne <brentvatne@gmail.com>
2015-07-31 13:49:14 -08:00
Nick Lockwood 1fb26d4319 Cleanup 2015-07-31 11:33:22 -08:00
Krzysztof Magiera b807c51bbe [ReactNative] Fix TextInput Focus issue 2015-07-31 11:03:41 -08:00
Vladislav Alexeev 53fb5b6cee Dynamic Text Sizes for Text component
Summary:
Dynamic Text Sizes for Text component.
Text gains new prop - allowFontScaling (false by default).
There is also AccessibilityManager module that allows you to tune multipliers per each content size category.
2015-07-31 07:42:41 -08:00
Nick Lockwood 407eb4ce85 NSNumber arguments must now be nonnull
Summary:
The bridge implementation on React Android does not currently support boxed numeric/boolean types (the equivalent of NSNumber arguments on iOS), nor does Java support Objective-C's nil messaging system that transparently casts nil to zero, false, etc for primitive types.

To avoid platform incompatibilities, we now treat all primitive arguments as non-nullable rather than silently converting NSNull -> nil -> 0/false.

We also now enforce that NSNumber * objects must be explicitly marked as `nonnull` (this restriction may be lifted in future if/when Android supports boxed numbers).

Other object types are still assumed to be nullable unless specifically annotated with `nonnull`.
2015-07-31 06:57:08 -08:00
Eric Vicenti 41dd6fe6ea [ReactNative][Navigator] Fix disabled scene height change
Summary:
Disabling the scene this way would make the scene height go to zero and mess up the scroll position. By setting the bottom to the same distance, the view does not get resized and the scroll position is preserved through a scene disable cycle.
2015-07-30 12:58:45 -08:00
Christopher Chedeau b10a1549c6 Merge pull request #2179 from vjeux/fix_flow
Install flow from npm/flow-bin instead of brew
2015-07-30 13:39:22 -07:00
Christopher Chedeau c627600ef3 Try to fix flow 2015-07-30 13:24:14 -07:00
Alex Akers f2b3057a7c Fix border width precedence issue 2015-07-30 06:18:17 -08:00
Felix Oghina 90b80e375c [reactnative] add launchAndroidPackager.command 2015-07-30 03:35:29 -08:00
Tadeu Zagallo cf22111cee [ReactNative] Prevent RCTDevLoadingView from creating UIWindow on unit tests
Summary:
`RCTDevLoadingView` was being created from a constructor function and creating
a `UIWindow` when the bridge started loading. The `UIWindow` was crashing on
the unit tests since there's no host app.
2015-07-30 03:10:53 -08:00
Dorota Kapturkiewicz 8a272bc873 [ReactNative] implement accessibilityLiveRegion and accessibilityComponentType 2015-07-30 01:40:37 -08:00
Gabe Levi d8a13ec3d5 [Flow] Deploy v0.14.0 2015-07-29 20:29:44 -08:00
Philipp von Weitershausen 4bfeeaa90d [ReactNative] Improve Flow definitions and code comments in XHR FormData polyfill 2015-07-29 20:03:57 -08:00
Zack Gomez 60c8abcc70 Revert "[ReactNative] revert "prevent ScrollView content offset from changing during layout"" 2015-07-29 17:23:18 -08:00
Hedger Wang 4b16e4d550 [Navigator]: Add a method keyOf to NavigationRouteStack.
Summary:
# Summary

Add a method `keyOf` to NavigationRouteStack.

The method `keyOf` returns a key that is associated with the route.
The a route is added to a stack, the stack creats an unique key for it and
will keep the key for the route until the route is rmeoved from the stack.

The stack also passes the keys to its derived stack (the new stack created by the
mutation API such as `push`, `pop`...etc).

The key for the route persists until the initial stack and its derived stack no longer
contains this route.

# Why Do We Need This?

Navigator has needs to use an unique key to manage the scenes rendered.
The problem is that `route` itself isn't a very reliable thing to be used as the key.

Consider this example:

```
// `scene_1` animates into the viewport.
navigator.push('scene_1');

setTimeout(() => {
 // `scene_1` animates off the viewport.
 navigator.pop();
}, 100);

setTimeout(() => {
 // Should we bring in a new scene or bring back the one that was previously popped?
 navigator.push('scene_1');
}, 200);

```

Because we currently use `route` itself as a key for the scene, we'd have to block a route
until its scene is completely off the components tree even the route itself is no longer
in the stack otherwise we'd see strange animation of jumping scenes.

# What's Next

We're hoping that we can build pure reactive view for NavigationRouteStack easily.
The naive implementation of  NavigationRouteStackView may look like this:

```
class NavigationRouteStackView {
  constructor() {
    this.state = {
      staleScenes: {},
    };
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.stack !== this.props.stack) {
      var stale;
      var staleScenes = {...this.state.staleScenes};
      this.props.stack.forEach((route, index, key) => {
        if (nextProps.stack.keyOf(route) !== key) {
          stale = true;
          staleScenes[key] = {route, index, key, stale};
        }
      });
      if (stale) {
        this.setState({
          staleScenes,
        });
      }
    }
  }

  render() {
    var scenes = [];

    this.props.stack.forEach((route, index, key) => {
      scenes.push({route, index, key});
    });

    Object.keys(this.state.staleScenes).forEach(key => {
      scenes.push(this.state.staleScenes[key]);
    });

    scenes.sort(stableSortByIndex);

    return <View>{scenes.map(renderScene)}</View>;
  }
}

```
2015-07-29 16:55:21 -08:00
Christopher Chedeau fc9150c674 Merge pull request #2169 from ide/iojs-docs
[Docs] Explain more about nvm in the io.js setup docs
2015-07-29 17:40:41 -07:00
James Ide de13b59dd2 [Docs] Explain more about nvm in the io.js setup docs
Clarify that io.js is the modern version of Node and explain a little more about how to get set up with nvm, and that it lets you switch between multiple io.js/node versions.
2015-07-29 17:29:18 -07:00
Philipp von Weitershausen 37636fc59a [React Native] open source ImageEditingManager native module 2015-07-29 15:57:48 -08:00
James Ide 0f32bea634 Merge pull request #2143 from milieu/patch-1
Fix broken links in docs/Testing.md
2015-07-29 13:55:22 -07:00
Hedger Wang 809a2dc1d6 [Navigator: Prevent user from over-popping the routes.
Summary:
If user taps the back button quickly, the app crashes becuase "pop"
internally only checks `this.state.presentedIndex` which does not
always update when transtion happens.

This diff addresses this issue.
2015-07-29 11:42:34 -08:00
Jing Chen 8416691719 [events] Move start point of EventsDashboard to work with early boot 2015-07-29 10:47:13 -08:00
Pieter De Baets d6de865236 Cleanup AppRegistry types
Summary:
Found some missing/wrong types when playing around with the AppRegistry for routing work in the main app.
2015-07-29 09:55:24 -08:00
Dorota Kapturkiewicz e073fdc4c7 [ReactNative] add accessibilityComponentType 2015-07-29 09:20:23 -08:00
Felix Oghina dfa43f0ce5 [react_native] JS files from D2282690: make back button work in launcher app 2015-07-29 06:35:46 -08:00
Nick Lockwood 95b9dd3a88 Added support for method argument nullability
Summary:
This diff adds support for enforcing nullability in the arguments for exported methods.

We previously supported use of the nullable/nonnull attributes on method arguments, but didn't do anything to ensure that they were respected.

Now, if an argument is marked as nonnull, and a null value is sent for that argument, it will display a redbox.

In future, nonnull will be assumed by default, but for now we assume that un-annotated arguments can be null (to avoid breaking existing code).
2015-07-29 05:50:27 -08:00
Ben Alpert e0ea046092 [ReactNative] Fix ResponderEventPlugin after React upgrade 2015-07-29 02:47:55 -08:00
Kevin Gozali 87ce2d635b [ReactNative] revert "prevent ScrollView content offset from changing during layout" 2015-07-28 19:39:56 -08:00
Kevin Gozali f1b22e87f1 [madman] version mobile configs disk caching 2015-07-28 18:11:34 -08:00
Tadeu Zagallo 127f7095dc [ReactNative] Add RCTBridgeDelegate
Summary:
Add a new bridge delegate protocol to allow a more flexible bridge configuration.

For now it just support the pre-existent configurations + providing the JavaScript
source to the bridge, that should allow pre-loading sources.
2015-07-28 15:57:02 -08:00
Zack Gomez 068f396c9b [ReactNative] prevent ScrollView content offset from changing during layout
Summary:
-[UIScrollView setFrame:] changes the content offset, which we want to do manually.  Preserve the old offset during layout.
2015-07-28 14:36:27 -08:00
Nick Lockwood b812b0ee2e Added unit tests for RCTModuleMethod parsing, and fixed some edge cases 2015-07-28 13:07:52 -08:00
Alex Kotliarskyi e964e741ef [RN] Add loading view for development mode
Summary:
It's very useful to know where the app is being loaded from and
can help debug various issues.
2015-07-28 11:17:06 -08:00
Martin Konicek 5164aa290b Merge pull request #2138 from mkonicek/master
[docs] Make it clear which Guides are platform-specific
2015-07-28 17:42:12 +01:00
Alex Akers 7d19ff3dcb Add <Modal /> component
Summary:
Create Modal component that can be used to present content modally.
2015-07-28 07:21:50 -08:00
Tadeu Zagallo f53c95c743 [ReactNative] Proxy bundleURL on RCTBatchedBridge
Summary:
Fixes #2126

`RCTBatchedBridge` didn't implement `bundleURL`, that was available on the public
bridge interface, so it'd always be `nil`, and setting it would just be ignored.
2015-07-28 05:59:45 -08:00
Martin Konicek 7fcd85cc53 Merge pull request #2145 from facebook/404-fix
Adding 404.js to catch 404s on website
2015-07-28 14:38:26 +01:00
Matthew Johnston 7a806f6d89 Update 404.js 2015-07-28 14:34:47 +01:00
Matthew Johnston 379444515b Adding 404.js to catch 404s on website 2015-07-28 14:22:13 +01:00
Meredith Leu f502e17cc7 Fix broken links 2015-07-27 18:34:12 -07:00
Alexander Kotliarskyi 757d6d204a Merge pull request #2136 from frantic/updates-2015-07-27
Updates 2015 07 27
2015-07-27 15:10:57 -07:00
Nick Lockwood 1d852624fd Refactored RCTImageDownloader to use RCTNetworking instead of a separate download system 2015-07-27 13:47:52 -08:00
Alex Kotliarskyi 62b7920b9d More updates 2015-07-27 14:47:32 -07:00
Ben Alpert 3cff9be3d1 [ReactNative] Update project template .flowconfig 2015-07-27 13:41:55 -08:00
Bill Fisher 3b83853713 [ReactNative] fix onMoveShouldSetPanResponderCapture
Summary:
Typo in implementation prevented onMoveShouldSetPanResponderCapture from working.
2015-07-27 12:06:40 -08:00
Rui Chen 842ce51099 [Treehouse RN] Make smoothScrollTo works by not calling it twice 2015-07-27 11:25:28 -08:00
Alex Kotliarskyi 9649e7cc8d More updates 2015-07-27 12:24:01 -07:00
Alex Kotliarskyi 58a403d3c8 [ReactNative] Pin babel version
Summary:
Currently minor version babel updates add and remove transforms, but internal
version is checked in and pinned to 5.6.4. Until we figure out how to update
internal deps systematically, we need to make sure OSS edition of RN matches
internal, otherwise we get test failures due to package version mismatches.
2015-07-27 11:20:22 -08:00
Christopher Chedeau 18e6094cab [ReactNative] Add overflow to the whitelisted Image props
Summary:
For some reason we're now spamming the logs everytime we render an Image because overflow is not defined in the whitelist. overflow: 'hidden' is needed for network images with cover mode.

The way we currently define those is not optimal where we try to factor as many things as possible into distinct propTypes. However for Text we're not even using this but we are getting all the ones from View (which many do not apply) and remove some that aren't needed.

It may be useful to cleanup this in the future but in the short term, it's better to remove this warning that doesn't have much value anyway.
2015-07-27 11:06:27 -08:00
Martin Konicek 33e62f71f4 [ReactNative] CameraRoll docs
Summary:
In preparation for open sourcing React Native for Android, document which parts of the `CameraRoll` API are platform-specific.

Renders like this: http://imgur.com/rbpXHKf

We should improve docs generation for `@param`s.
2015-07-27 09:46:35 -08:00
Martin Konicek b7253dc604 [ReactNative] PixelRatio docs
Summary:
Update docs for `PixelRatio` in preparation for open sourcing React Native for Android.

See http://stackoverflow.com/questions/11581649/about-android-image-and-asset-sizes
2015-07-27 09:40:08 -08:00
Martin Konicek 01911e5e06 [docs] Make it clear which Guides are platform-specific
This is in preparation for open sourcing React Native for Android.
Also add hyphens to URLs for consistency. This can break people's
browser bookmarks but it's better to be consistent and we can
redirect to docs: https://github.com/facebook/react-native/issues/2137

Test plan: Ran the website locally using `cd website; npm start`
and checked all pages render correctly.
http://i.imgur.com/RrPNgRr.png

Will update "Getting Started", "Tutorial", "Debugging" and
"Testing" separately.
2015-07-27 18:17:54 +01:00
Nick Lockwood 09bb761b25 Fixed RCTDownloadTaskWrapper crash on iOS7
Summary:
This is a quick fix for the RCTDownloadTaskWrapper crashing on iOS 7. The issue was that the object returned by -[NSURLSession downloadTaskWithURL:] on iOS was not actually a subclass of NSURLSessionTask, so the category that adds associated blocks was not working. I've fixed that by making it a category on NSObject instead.
2015-07-27 09:02:38 -08:00
Alex Kotliarskyi 2eb401a496 Updates from 2015-07-27 2015-07-27 10:01:30 -07:00
Nick Lockwood 7996c32211 Unregistered modules will now only error when called, not on bridge init
Summary:
Occasionally people create RCTBridgeModule subclasses or base classes that are not intended to be accessed from JS, and so they don't export them. This was previously flagged as an error by the system. I've now downgraded this error to a warning at startup, and deferred the redbox error until the module is directly accessed by native or JS code.
2015-07-27 08:58:47 -08:00
Nick Lockwood 2c5290946b Converted RCTImageLoader to be a bridge module 2015-07-27 08:52:20 -08:00
Alex Akers d178e27939 Fix UIExplorer freezing / persistence 2015-07-27 08:35:34 -08:00
Nick Lockwood f9abb5aae2 Fixed missing redbox at startup
Summary:
Fixed bug where redbox errors thrown during startup would be dismissed as soon as JS loaded, so they would never be seen.
2015-07-27 07:23:08 -08:00
Nick Lockwood 0e5422f36c Fixed text highlight alignment when text has nonzero padding.
Summary:
Previously the text highlight overlay did not take padding into account in its positioning, so it would be misaligned for padded text. This fixes that.
2015-07-27 07:11:29 -08:00
Martin Konicek c3d194d1f8 [ReactNative] TextInput docs 2015-07-27 06:45:13 -08:00
Martin Konicek f69e33e6a8 [ReactNative] Text docs
Summary:
In preparation for open sourcing React Native for Android, document which Text props are platform-specific.
2015-07-27 06:38:27 -08:00
Nick Lockwood aca76c75dd Fix gzip on iOS 9 2015-07-27 01:18:40 -08:00
Spencer Ahrens f1bd1cbc94 [ReactNative] cleanup native components 2015-07-24 18:54:35 -08:00
James Ide 53222f0dda [Packager] Include Content-Type headers with bundle and source maps
Summary:
The packager did not send back the Content-Type headers. Adding these.

Closes https://github.com/facebook/react-native/pull/2029
Github Author: James Ide <ide@jameside.com>
2015-07-24 18:46:17 -08:00
Nick Lockwood 5f0317291b Switched to OSS <Text> implementation for internal apps 2015-07-24 17:30:43 -08:00
Hedger Wang ea5276ed24 [Navigator] Port navigation APIs from Navigator to NavigationContext 2015-07-24 17:10:41 -08:00
James Ide c8373d2ad6 [Chrome Debugger] Update ws dependency to 0.7.2
Summary:
ws 0.7.2 officially supports io.js

Closes https://github.com/facebook/react-native/pull/2013
Github Author: James Ide <ide@jameside.com>
2015-07-24 15:52:49 -08:00
James Ide bf7e2a85d0 [Navigator] Vertically hide disabled scenes and use pointerEvents="none"
Summary:
Hides disabled scenes using `top` instead of `left`, which fixes a bug with the native UITabBar. When the UITabBar's width is zeroed because the scene has `left: SCREEN_WIDTH, right: 0` applied, this triggers a bug with the kerning of the tab titles. Instead, zeroing the height by setting `top: SCREEN_HEIGHT` avoids the bug.

Also applies `pointerEvents="none"` to disabled scenes so that views in the off-screen scenes definitely don't receive touches, which was occurring before.

Fixes #1401, fixes #2011

Closes https://github.com/facebook/react-native/pull/2104
Github Author: James Ide <ide@jameside.com>
2015-07-24 14:45:19 -08:00
Martin Konicek d10e4dbf0f [ReactNative] Use ASCII double quotes
Summary:
We mix ASCII double quotes with left and right quotes: https://github.com/facebook/react-native/blob/master/Libraries/CustomComponents/ListView/ListView.js#L13

Let's be consistent.
2015-07-24 13:16:25 -08:00
Michael Mitchell a1612a7dd2 [ReactNative] Delete AnimationExperimental and AnimationUtils
Summary:
AnimationExperimental is deprecated and being removed in favor of the Animated library.
Refer to https://facebook.github.io/react-native/docs/animations.html for information on how to use Animated
and https://facebook.github.io/react-native/docs/animations.html#animationexperimental-deprecated for the reasoning behind this.
2015-07-24 10:29:44 -08:00
Matej Hamas 000ab1139f [ReactNative] Adding clear function to the react native TextInput component. 2015-07-24 09:46:01 -08:00
Nick Lockwood 81dd9c27ea Optimized property setting and conversion 2015-07-24 09:37:28 -08:00
Tadeu Zagallo 4499f28c1d [ReactNative] Remove wrong lock from RCTProfile
Summary:
Remove sad lock from RCTProfileForwardInvocation that was locking concurrent
calls and messing with the profiler.
2015-07-24 09:14:46 -08:00
Nick Lockwood ef5cec4f08 Text highlighting on iOS
Summary:
This diff implements highlighting of tapped text subranges for the iOS `<Text>` component, styled to match how iOS webkit views highlight links (translucent grey overlay with rounded corners).

Highlighting is enabled by default for any `<Text>` component which has an onPress handler. To disable the highlight, add `suppressHighlighting={true}` to the component props.
2015-07-24 08:41:58 -08:00
Martin Konicek 7c87952e43 [ReactNative] Image docs
Summary:
In preparation for open sourcing React Native for Android, document which Image props are platform-specific.
2015-07-24 06:21:49 -08:00
lh_wang 1b06e41c83 fix examaple TabBarIOSExample bug; show click num when user click second & third tabbar
Summary:
Closes https://github.com/facebook/react-native/pull/1522
Github Author: lh_wang <lh_wang@Ctrip.com>
2015-07-23 19:12:42 -08:00
Rui Chen accf6f12e4 Make the scrollResponderScrollNativeHandleToKeyboard works on Android 2015-07-23 18:14:43 -08:00
Ben Alpert e01f90784f [ReactNative] Update core RN modules to work with React 0.14-beta1 2015-07-23 18:07:59 -08:00
Ben Alpert 710d29efae [ReactNative] Update React to 0.14-beta1 2015-07-23 18:07:58 -08:00
Jared Forsyth 9e4af68d91 [react-native] enable react devtools from JavascriptCore 2015-07-23 17:14:09 -08:00
Mark Miyashita 10ffe170c2 [StatusBar] Add ability to toggle the network activity indicator in the status bar + example in UIExplorer
Summary:
Added the ability to turn on and off the network activity indicator using:

```
StatusBarIOS.setNetworkActivityIndicatorVisible(true)
```
and
```
StatusBarIOS.setNetworkActivityIndicatorVisible(false)
```

Also added an example to the UIExplorer example app.

Fix #986
Closes https://github.com/facebook/react-native/pull/2079
Github Author: Mark Miyashita <negativetwelve@gmail.com>
2015-07-23 16:22:56 -08:00
Christopher 3fa3963465 [MovieApp] Add key to image components inside of MovieCell.
Summary:
Closes https://github.com/facebook/react-native/pull/2065
Github Author: Christopher <hello@blick-labs.com>
2015-07-23 15:09:42 -08:00
Andrei Coman aefb3d3628 [ReactNative] Use new animation library for 2048 game demo 2015-07-23 12:36:31 -08:00
Alexander Kotliarskyi a803e3217e Merge pull request #2105 from frantic/updates-23-jul
Updates 23 jul
2015-07-23 13:21:22 -07:00
Alex Kotliarskyi 03dccfbf71 Updates from Thu, July 23 2015-07-23 13:09:48 -07:00
Daniel Brockman 064dafa618 #!/bin/bash => #!/usr/bin/env bash
Summary:
This change makes `npm start` work correctly on e.g. NixOS.
Closes https://github.com/facebook/react-native/pull/2006
Github Author: Daniel Brockman <daniel@brockman.se>
2015-07-23 11:17:22 -08:00
Andrei Coman 9c8ba9502c [react_native] Refactor UIExplorerList to fix UIExplorerApp 2015-07-23 06:58:18 -08:00
Martin Konicek 19a8eff668 [ReactNative] ScrollView docs
Summary:
In preparation for open sourcing React Native for Android, document which ScrollView props are platform-specific.
2015-07-23 06:56:46 -08:00
Nick Lockwood 9d19829742 Refactored networking logic out into RCTDownloadTask 2015-07-23 04:00:31 -08:00
Christopher Chedeau 6fea7c2846 [ReactNative] Remove all the flow errors 2015-07-22 18:11:09 -08:00
Christopher Chedeau fea2db42fd [Animated] Send a final update with toValue for spring
Summary:
Animated.spring is not guarantee to stabilize at exactly toValue (determined by restDisplacementThreshold). It is a bit annoying that the last value is not toValue, it makes the logs harder to read and also prevents you from writing code like value === toValue. Instead you need to track it down somewhere else.
2015-07-22 17:33:00 -08:00
Christopher Chedeau b34892eb80 [ReactNative][BREAKING_CHANGE] Remove cloneElement from TouchableBounce 2015-07-22 17:22:35 -08:00
Jared Forsyth e06af51cf9 [react-native] inspector + devtools, naming things 2015-07-22 16:50:32 -08:00
Spencer Ahrens a671c58189 Merge pull request #2094 from sahrens/Updates_from_thurs_July_23rd
Updates from Thursday July 23rd
2015-07-23 01:39:57 +02:00
Rui Chen 93bbc6482d Unbreak the dismissing keyboard behavior on Android 2015-07-22 15:24:42 -08:00
Spencer Ahrens bb7aa500d7 Updates from Thurs July 23rd 2015-07-23 01:16:05 +02:00
Spencer Ahrens cec5360f1b [RN] Introduce initialValue prop to fix TextInputExamples
Summary:
Some of the examples relied on the fact that TextInput wasn't a controlled
component before.  This introduces a new `initialValue` prop which behaves the
way the `value` prop used to - that is, you could type without updating it and
it wouldn't get reset, thus acting as just an initial value - and switches the
examples to use it where appropriate.
2015-07-22 14:21:16 -08:00
Tadeu Zagallo 49b55804b1 [ReactNative] Fix crash when reload during profile (attempt #2)
Summary:
Fixes #1642

When reloading during profiling, the profile wouldn't unhook from the instance
being deallocated.
2015-07-22 11:02:32 -08:00
Hedger Wang 8dd1256c25 [Navigation] Implements NavigationContextFuture 2015-07-22 10:50:51 -08:00
Hedger Wang 280347d66a [Navigator]: Add method indexOf and slice to NavigationRouteStack 2015-07-22 10:46:57 -08:00
Felix Oghina 214c47ed76 [reactnative] move .android.js files to oss 2015-07-22 08:44:07 -08:00
Brent Vatne 75b220d6ce Merge pull request #2081 from MattFoley/patch-1
Enum Constants Explanation
2015-07-21 20:57:14 -07:00
Rui Chen 4e33b801ca Allow Animated.parallel to accept empty element in the array 2015-07-21 15:32:08 -08:00
Tj 1e5f22dc9c Updating for Code Review
Using UIStatusBarAnimation for real world example
2015-07-21 18:11:58 -04:00
Eric Vicenti 35aa9f3b97 [ReactNative] Remove idStack from Navigator
Summary:
We want to transition to NavigationRouteStack, so we need to simplify and remove all uses of idStack
2015-07-21 13:25:42 -08:00
Tj 4d3c3e625e Enum Constants Explanation
Explains the use of `RCT_ENUM_CONVERTER` for using `NS_ENUM` arguments in exported functions
2015-07-21 16:46:40 -04:00
Spencer Ahrens 961c1eb429 [ReactNative] TextInput bug fixes and features
Summary:
This introduces event counts to make sure JS doesn't set out of date values on
native text inputs, which can cause dropped characters and can mess with
autocomplete, and obviates the need for the input buffering which added lag and
complexity to the component.  Made sure to test simulated super-slow JS text
event processing to make sure characters aren't dropped, as well as typing
obviously correctable words and making sure autocomplete works as expected.

TextInput is now a controlled input by default without causing any issues for
most cases, so I removed the `controlled` prop.

Fixes selection state jumping by restoring it after setting new text values, so
highlighting the middle of some text in the new ReWrite example and hitting
space will replace that selection with an underscore and keep the cursor at a
sensible position as expected, instead of jumping to the end.

Ads `maxLength` prop to support the most commonly needed syncronous behavior:
preventing the user from typing too many characters.  It can also be used to
prevent users from continuing to type after entering special characters by
changing it to the current length after a regex match.  Made sure to verify it
works well with pasted input (including in the middle of existing text),
truncating it and collapsing the selection the same way it does on the web.

Fixes bug in TextEventsExample where it wouldn't show the submit and end events,
even though there were firing correctly.
2015-07-21 12:45:07 -08:00
Eric Vicenti 4f904b5d68 [ReactNative] Remove Navigator onItemRef
Summary:
Re-landing D2229686 after fixing bugs mentioned in D2250586

onItemRef is old and no longer needed now that the parent renders the scenes. This removes it from Navigator and all of our clients.

This is a breaking change to users of Navigator, but it is easy to transition to a ref in renderScene instead
2015-07-21 09:28:29 -08:00
Alex Akers 98ab7581a5 Remove images from offscreen image views 2015-07-21 09:02:28 -08:00
Nick Lockwood 85cb35c514 Fixed rotation and scaling issues when loading ALAssets using RCTImageLoader 2015-07-21 05:32:49 -08:00
Adam Roth 9c73e2ff7a [Image] Improved loading of Assets Library and Photos Framework images.
Summary:
Update to https://github.com/facebook/react-native/pull/1969

--
Recent improvements allow RCTImageLoader to select a more appropriate sized image based on the layout dimensions. Sizes:

	- asset.thumbnail
	- asset.aspectRatioThumbnail
	- asset.defaultRepresentation.fullScreenImage
	- asset.defaultRepresentation.fullResolutionImage

Prior, only the fullResolutionImage was used. This was memory intensive and resulted in crashes when loading several large images at once. The updated implementation works well, but can be made more efficient:

Consider loading 10 8MP (3264x2448) images in 150x150 pixel containers. The target size (150x150) is larger than asset.thumbnail (approx 100x100), therefore the fullScreenImage representation is used instead (approx 1334x1000).

This commit will scale the asset to the minimum size required while taking into account original aspect ratio and device scale. Memory usage is considerably lower and many more images can be loaded in
sequence without having to worry
Closes https://github.com/facebook/react-native/pull/2008
Github Author: Adam Roth <adamjroth@gmail.com>
2015-07-21 05:32:48 -08:00
Philipp von Weitershausen 9c5fe3612d [React Native][iOS] XHR upload progress events 2015-07-20 22:48:55 -08:00
Philipp von Weitershausen 151ddd9e42 [React Native] open source ImageStoreManager native module and plug into RCTImageLoader 2015-07-20 22:48:54 -08:00
Hedger Wang 6e2f07fb81 [Navigator] Add a callback that is called after emitting an event.
Summary:
While adeveloper requests the emitter to emit an event, the emitter
may not emit the event immediately instead of putting the request
into a queue and process it later.

This diff allows the developer to provide a callback which will be called
when the event has been emitted.

For instance:

```
class NavigationContext {
  push(nextRoute) {
    var nextStack = this._stack.push(nextRoute);
    this.emit(
      'change',
      {
        reason: 'push',
        nextStack: nextStack,
        nextRoute: nextRoute,
      },
      this._onPush
    );
  }

  _onPush(event){
    if (event.defaultPrevented) {
      return;
    }
    this._stack = event.nextStack;
    this.emit('change');
  }
}
```
2015-07-20 21:49:58 -08:00
Alex Kotliarskyi 9105b22925 [RN] Remove 14 more unused node_modules 2015-07-20 20:00:27 -08:00
Alex Kotliarskyi e54e452026 [RN] Remove extra copy of stacktrace-parser 2015-07-20 20:00:19 -08:00
Alex Kotliarskyi bf7497a418 [RN] Move ws to react-native-github 2015-07-20 20:00:18 -08:00
Tadeu Zagallo 270e09d46e [ReactNative][Profiler] Fix NSProcessInfo instacrash on iOS7
Summary:
`NSProcessInfo operatingSystemVersion` was being used to check the system version
for the Legacy Profiler on `RCTContextExecutor` but it's only available on iOS8+

Change it to `[UIDevice systemVersion]`
2015-07-20 19:36:13 -08:00
Christopher Chedeau 725053acfe [Animated][BREAKING_CHANGE] Convert <TouchableOpacity> to Animated
Summary:
Because we don't want to integrate Animated inside of the core of React, we can only pass Animated.Value to styles of <Animated.View>. TouchableOpacity unfortunately used cloneElement. This means that we should have asked every single call site to replace their children to Animated.View. This isn't great.

The other solution is to stop using cloneElement and instead wrap the children inside of an <Animated.View>. This has many advantages:
- We no longer use cloneElement so we're no longer messing up with elements that are not our own.
- Refs are now working correctly for children elements
- No longer need to enforce that there's only one child and that this child is a native element

The downside is that we're introducing a <View> into the hierarchy. Sadly with CSS there is no way to have a View that doesn't affect layout. What we need to do is to remove the inner <View> and transfer all the styles to the TouchableOpacity. It is annoying but fortunately a pretty mechanical process.

I think that having a wrapper is the best solution. I will investigate to see if we can make wrappers on TouchableHighliht and TouchableWithoutFeedback as well.

**Upgrade Path:**

If the child is a View, move the style of the View to TouchableOpacity and remove the View itself.

```
<TouchableOpacity onPress={...}>
  <View style={...}>
    ...
  </View>
</TouchableOpacity>

-->

<TouchableOpacity onPress={...} style={...}>
  ...
</TouchableOpacity>
```

If the child is an Image or Text, on all the examples at Facebook it worked without any change. But it is a great idea to double check them anyway.
2015-07-20 16:44:36 -08:00
Matheus Santos 6213950334 Added transitions 'VerticalUpSwipeJump' and 'VerticalDownSwipeJump' in…
Summary:
… NavigatorSceneConfigs
Closes https://github.com/facebook/react-native/pull/1822
Github Author: Matheus Santos <matheus.santos@struct.com.br>
2015-07-20 12:53:54 -08:00
Martín Bigio 95dc38929c [rn] revert D2201593 2015-07-20 11:48:08 -08:00
Martín Bigio 0d91b93aba [LAUNCH-BLOCKER] Revert JS callsite of D2201593 2015-07-20 11:48:07 -08:00
Tadeu Zagallo 72f7a1be6f [ReactNative] Add JavaScriptCore legacy profiler 2015-07-20 09:58:45 -08:00
Nick Lockwood 5db42643cf Added JSONKit support
Summary:
React Native will now use JSONKit if it's already available in the project, otherwise it will fall back to using NSJSONSerialization as before. This provides a small performance boost to JSON parsing in some cases.
2015-07-20 09:52:31 -08:00
Spencer Ahrens e3afc4efd8 Merge pull request #2049 from negativetwelve/docs/animated-input-events
[Docs] Fix Animated example for onScroll and onPanResponderMove to match paragraph description
2015-07-20 19:25:23 +02:00
Tadeu Zagallo f2d65ea85b [ReactNative] Fix RCTJavaScriptContext deallocation (attempt #2)
Summary:
The context wasn't being explicitly released before, since it'd be immediately
released. Now that the executors are bridge modules, it was only being deallocated
when the modules were released, what caused the threads to not be released at all.
2015-07-20 02:40:05 -08:00
Mark Miyashita f3dd07531c [Docs] Animated example for onScroll and onPanResponderMove should match the description in the paragraph above 2015-07-19 17:05:25 -07:00
Elliot Lynde 4a262e0f2b [React Native][Pokes Dashboard] Fix crash 2015-07-17 17:00:47 -08:00
Eric Vicenti c28d33f3a2 [ReactNative] Remove dependencies on Navigator idStack
Summary:
idStack is going away soon. This removes all references to it. Looking at the internal state of navigator will make you have a bad time.

The biggest change is switching to the new component-freezing techinique in the navigation bars. This way we avoid dependence on the idStack to provide a scalar ID for each route.
2015-07-17 15:28:57 -08:00
Eric Vicenti c4389c006f [ReactNative] Max RedBox windowLevel to always appear on top 2015-07-17 13:24:52 -08:00
Bill Fisher b56717ede9 [Storyline] SliderIOS responds to UIControlEventTouchUpOutside 2015-07-17 13:01:08 -08:00
DengYun 3c78aa6d25 [Bridge] remove unused semaphore
Summary:
dispatch_semaphore_wait with DISPATCH_TIME_NOW don't wait for the semaphore. It just test whether there's a signal and return the result.

So the line "dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW);" does nothing here. It seems like a bug, but each executing in js thread will be queued, so it's safe to remove the unused semaphore instead of wait for it.
Closes https://github.com/facebook/react-native/pull/1915
Github Author: DengYun <tdzl2003@gmail.com>
2015-07-17 10:01:26 -08:00
Nick Lockwood 61c648d564 Merged RCTNetworkImageView functionality into RCTStaticImage
Summary:
RCTNetworkImageView and RCTStaticImage had significant overlap in functionality, but each had a different subset of features and bugs.

This diff merges most of the functionality of RCTNetworkImageView into RCTStaticImage, eliminating some bugs in the former, such as constant redrawing when properties were changed.

I've also removed the onLoadAbort event for now (as it wasn't implemented), and renamed the other events to match the web specs for `<img>` and XHMLHttpRequest. The API is essentially what Adobe proposed here: http://blogs.adobe.com/webplatform/2012/01/13/html5-image-progress-events/

The following features have not yet been ported from RCTNetworkImageView:

- Background color compositing. It's not clear that this adds much value and it increases memory consumption, etc.
- Image request cancelling when images are removed from view. Again, it's not clear if this is a huge benefit, but if it is it should be combined with other optimisations, such as unloading offscreen images.

(Note that this only affects the open source fork. For now, internal apps will still use FBNetworkImageView for remote images.)
2015-07-17 07:43:16 -08:00
Nick Lockwood 82a774e92b Added unit tests for gzip functionality 2015-07-17 04:55:27 -08:00
Spencer Ahrens fc23d0c40d Merge pull request #2030 from sahrens/Updates_From_Fri_July_17th
Updates from fri july 17th
2015-07-17 14:26:44 +02:00
Spencer Ahrens 4a5f12aa29 Updates from Fri July 17th 2015-07-17 14:14:30 +02:00
Spencer Ahrens c43e93d1b4 Reverted ca9d1b3bf5a6f46ec29babe8685634690ff9a2bc to unbreak groups 2015-07-17 04:03:01 -08:00
Christopher Chedeau 2771fc4c52 Add link for releases 2015-07-16 19:41:22 -07:00
Kevin Gozali 77a0cf27f2 [ReactNative] Revert onItemRef removal 2015-07-16 17:49:56 -08:00
Kevin Gozali 5ec60effea [ReactNative] revert 'unbreak navigation due to onItemRef removal' 2015-07-16 17:49:56 -08:00
Hedger Wang 326a66ba07 [ReactNative][Navigation]: Add method preventDefault() to NavigationEvent 2015-07-16 17:35:21 -08:00
Spencer Ahrens 4b82673484 revert [React Native] Fix scroll view sticky headers 2015-07-16 16:31:53 -08:00
Martín Bigio ab9a87c33a [cg] Perf logging 2015-07-16 14:24:49 -08:00
Hedger Wang fca16fbe40 [ReactNative] unbreak navigation due to onItemRef removal 2015-07-16 13:41:20 -08:00
Sean Powell fa4c570d33 Support debugger reconnection when the packager goes down.
Summary:
This should resolve the issue highlighted in #1709
Closes https://github.com/facebook/react-native/pull/1992
Github Author: Sean Powell <sean@longdivision.co.uk>
2015-07-16 13:32:01 -08:00
Nick Lockwood 81ad713f5f Added Gzip support
Summary:
Added Gzip function to RCTUtils. This uses dlopen to load the zlib library at runtime so there's no need to link it into your project.

The main reason for this feature is to support gzipping of HTTP request bodies. Now, if you add 'Content-Encoding:gzip' to your request headers when using XMLHttpRequest, your request body will be automatically gzipped on the native side before sending.

(Note: Gzip decoding of *response* bodies is handled automatically by iOS, and was already available).
2015-07-16 09:38:20 -08:00
Frédéric Sagnes 36f76e5893 Improve the performance of React Native tests 2015-07-16 08:41:06 -08:00
Adam Farhi f74efc13ed Add ListView Grid Layout Example to UIExplorer Examples
Summary:
On @brentvatne suggestion:
https://github.com/facebook/react-native/issues/1276#issuecomment-112161358

I imported my Grid Layout example (https://github.com/yelled3/react-native-grid-example) into UIExplorer.

![demo-grid](https://cloud.githubusercontent.com/assets/818124/8229685/c4325dd4-15c1-11e5-8817-cdf270ab1003.gif)
Closes https://github.com/facebook/react-native/pull/1668
Github Author: Adam Farhi <yelled3@gmail.com>
2015-07-16 06:02:15 -08:00
James Ide b362072c83 [Rendering] Set allowsEdgeAntialiasing for transformed views
Summary:
By default, the edges of rotated layers on iOS have jagged edges because they are not antialiased. Setting `allowsEdgeAntialiasing` makes them look a lot nicer by smoothing out the jaggies. This is particularly important for UIs like Tinder cards, for example.

Closes https://github.com/facebook/react-native/pull/1999
Github Author: James Ide <ide@jameside.com>
2015-07-16 04:33:03 -08:00
Mr Speaker 2cb634bb0b Nav ios hide hairline
Summary:
For the current project I am working on I needed to add a boolean option (`shadowHidden`) to remove the 1px hairline shadow from the NavigationIOS component:

`<NavigatorIOS shadowHidden={true} initialRoute={...} />`

By default, or with `shadowHidden={false}` it looks like this:

![withhairline](https://cloud.githubusercontent.com/assets/129330/8145401/d2704956-11d4-11e5-86e8-a75435b68480.png)
Setting the shadow hidden  with `shadowHidden={true}` looks like this:

![nohairline2](https://cloud.githubusercontent.com/assets/129330/8145405/148ed56e-11d5-11e5-85d6-f8cd3453d5ac.png)

The code it uses to do the actual hiding is... a bit of a hack (*I* think), but it's the only way currently to do it, and is the way they do it in the iPhone calendar app: iterating through the subviews and removing the shadow image.

This removes the shadow *and* keeps the translucent blurry effect with a ScrollView (see this [SO discussion](http://stackoverflow.com/questions/18160173/how-to-remove-uinavigationbar-inner
Closes https://github.com/facebook/react-native/pull/1615
Github Author: Mr Speaker <mrspeaker@gmail.com>
2015-07-16 04:31:17 -08:00
Mike Armstrong 9f94dd457a Camera node for scene hierarchy 2015-07-16 01:57:00 -08:00
John Ku 72694a722e Include jestSupport for npm package
Summary:
https://github.com/facebook/react-native/pull/1639 was closed for unknown reason. This will help unit test with Jest without manually copying them into node_modules/react-native.
Closes https://github.com/facebook/react-native/pull/1848
Github Author: John Ku <john.cmyk@gmail.com>
2015-07-15 19:00:15 -08:00
Mr Speaker 09236ccbe7 Allow horizontal ListView. Rename height -> size
Summary:
Infinite scrolling in horizontal ListViews. Rather than just using height and Y offset to determine when to load more rows, it checks `props.horizontal` and switches between width/height and offset X/Y accordingly.

This changed required some renaming. However, the only change external to `ListView.js` is exporting `contentSize` instead of `contentHeight` from the `getMetrics()` function. (This is not part of the API, but is used "for perf investigations or analytics" and isn't reference in the repo).

I believe this change works as expected (and the xcode tests pass) though it's possible that there may more complexity in this issue that I have overlooked.
Closes https://github.com/facebook/react-native/pull/1786
Github Author: Mr Speaker <mrspeaker@gmail.com>
2015-07-15 10:13:12 -08:00
Spencer Ahrens 28b9a6f69e Merge pull request #2007 from sahrens/Updates_from_Wed_July_15th
Updates from wed july 15th
2015-07-15 19:26:26 +02:00
Spencer Ahrens 902ffbbfb8 Updates from Wed July 15th 2015-07-15 19:05:08 +02:00
Christopher 5006eca4a8 [TextInput] Remove focus on TextInput if property editable is …
Summary:
Clicking on a TextField with editable set to false still would trigger a keyboard event.
In this case that the TextField was a multiline, it would scroll you down to the bottom.

Closes https://github.com/facebook/react-native/pull/1855
Github Author: Christopher <hello@blick-labs.com>
2015-07-15 08:37:22 -08:00
Dave Sibiski 70feab9d50 [Packager] Fix when loading a path that can't be handled
Summary:
[Packager] Adds `NotFoundError` when loading a path that can't be handled

Resolves https://github.com/facebook/react-native/issues/1944
Closes https://github.com/facebook/react-native/pull/1948
Github Author: Dave Sibiski <dsibiski@gmail.com>
2015-07-15 08:25:31 -08:00
chirag04 915540d237 [transform] add perspective property to transform
Summary:
![matrixflip](https://cloud.githubusercontent.com/assets/1509831/8701143/607b069c-2b10-11e5-9c54-8b9767e74e16.gif)

cc @sahrens @vjeux
Closes https://github.com/facebook/react-native/pull/1980
Github Author: chirag04 <jain_chirag04@yahoo.com>
2015-07-15 08:08:29 -08:00
Matt Revell 64c00dcd7a Issues/#1689 text input warning
Summary:
This should close issue 1689. Using Object.assign to pass Flow checks.
Closes https://github.com/facebook/react-native/pull/1956
Github Author: Matt Revell <mattrevell82@me.com>
2015-07-15 06:33:03 -08:00
Dorota Kapturkiewicz ba433be886 [ReactNative] Make ErrorCookie work. 2015-07-15 04:04:09 -08:00
Brent Vatne 94e2e51876 Merge pull request #1949 from sjmueller/master
Clarify docs to use animated over react-tween-state & rebound
2015-07-14 23:16:36 -07:00
chirag04 548549ea9f [style] expose rotate x, y, z transforms
Summary:
Added rotateX, rotateY, rotateZ transforms.

cc @sahrens
Closes https://github.com/facebook/react-native/pull/1976
Github Author: chirag04 <jain_chirag04@yahoo.com>
2015-07-14 19:58:26 -08:00
James Ide 19ddbac113 [Versions] Update versions in package.json and podspec to 0.7.1
Summary:
When developing against master I want to rely on the version numbers being reasonably accurate.
Closes https://github.com/facebook/react-native/pull/1804
Github Author: James Ide <ide@jameside.com>
2015-07-14 17:57:07 -08:00
chirag04 04fa09afef [Style] added backface-visibility. fixes #1973
Summary:
default behavior remains same(backface visible).

cc @sahrens
Closes https://github.com/facebook/react-native/pull/1977
Github Author: chirag04 <jain_chirag04@yahoo.com>
2015-07-14 17:38:05 -08:00
Spencer Ahrens 5d4140c513 [ReactNative] deepDiff by default 2015-07-14 17:32:25 -08:00
Pylipala 7a23651ee1 Fix the main.jsbundle url in comment
Summary:
Fix the url in comment
Closes https://github.com/facebook/react-native/pull/1959
Github Author: Pylipala <pylipala@gmail.com>
2015-07-14 16:44:35 -08:00
Tadeu Zagallo d30ada61f0 [ReactNative] Remove unused executor context id
Summary:
Remove `RCTGetExecutorID` and `RCTSetExecutorID`, it wasn't used anymore since
the bridge was refactored into `RCTBridge` and `RCTBatchedBridge`.
2015-07-14 16:40:21 -08:00
Tadeu Zagallo 9799c215cb [ReactNative] Add JS errors handling to iOS
Summary:
Every once in a while a guard is forgotten somewhere and the redbox is gone. I
want to remove the guards, but for that the stack traces have to be symbolicated
on the native side. So for now it just adds yet another check, in case a guard
is missing on JS.
2015-07-14 16:24:06 -08:00
Spencer Ahrens 3e8604d5d8 Merge pull request #1982 from IskenHuang/feature/bundle_cli
add cli bundle url params
2015-07-15 02:07:30 +02:00
Kevin Gozali 2e9d156fad [ReactNative] revert D2233419: 'Dynamic Text Sizes for Text component' 2015-07-14 15:55:06 -08:00
Eric Vicenti c3e75393ab [ReactNative] Remove Navigator onItemRef
Summary:
onItemRef is old and no longer needed now that the parent renders the scenes. This removes it from Navigator and all of our clients.

This is a breaking change to users of Navigator, but it is easy to transition to a ref in renderScene instead
2015-07-14 14:56:16 -08:00
Dmitriy Loktev 74f8055692 [Image] Add examples to UIExplorer, fix some bugs
Summary:
Add two simple examples.
![image](https://cloud.githubusercontent.com/assets/1004115/8674092/03052652-2a55-11e5-8531-8f01c7970af4.png)

Also:
- do not start the task at DownloadTaskWrapper (it starts from ImageDowloader if image isn't cached yet);
- fire `onLoadAbor`t event;
- send more readable `error.localizedDescription` with `onLoadError`;
- rename `onLoaded` to `onLoadEnd`
Closes https://github.com/facebook/react-native/pull/1987
Github Author: Dmitriy Loktev <unknownliveid@hotmail.com>
2015-07-14 14:33:02 -08:00
Nick Lockwood d1a82c4af1 Fixed image downloader bug
Summary:
RCTImageDownloader was ignoring server response codes. When receiving a response other than 200 it would treat this as success, meaning the image would never load, nor report failure.

This diff fixes that by treating responses with non-200 status as an error so that error handler is called.
2015-07-14 13:04:34 -08:00
Jared Forsyth a43987309d [react native] prepare the react native inspector for the new react devtools
Summary:
These are the changes needed for full interop with the (as yet unreleased) new
version of React Devtools.

- the on-device inspector is minimized when devtools is open
- devtools highlight -> device and device touch -> devtools select works
- editing react native styles :)
2015-07-14 12:35:43 -08:00
Spencer Ahrens 52f599a080 Merge pull request #1988 from sahrens/Updates_from_Tue_July_14th
Updates from tue july 14th
2015-07-14 21:04:23 +02:00
Spencer Ahrens 34c2157b66 Updates from Tue July 14th 2015-07-14 20:37:13 +02:00
Forbes Lindesay ebd046ae21 Remove bluebird 2015-07-14 10:25:16 -08:00
Jacob Rosenthal a8cb47e011 add local notification api schedule and present
Summary:
Add local notifications to the push library.
```
  var PushNotificationIOS = React.PushNotificationIOS;
  PushNotificationIOS.requestPermissions();

  var notification = {
    "fireDate": Date.now() + 10000,
    "alertBody":"Whats up pumpkin"
  };

  PushNotificationIOS.scheduleLocalNotification(notification);
 //lock screen or move away from app
```

Apple has another api for pushing immediately instead of scheduling, like when your background delegate has been called with some new data (bluetooth, location, etc)
```
  var PushNotificationIOS = React.PushNotificationIOS;
  PushNotificationIOS.requestPermissions();

  var notification = {
    "alertBody":"Whats up pumpkin"
  };

  PushNotificationIOS.presentLocalNotification(notification);
 //lock screen or move away from app
```

Closed https://github.com/facebook/react-native/pull/843 looks related:

See https://developer.apple.com/library/ios/documentation/iPhone/Reference/UILocalNotification_Class/ for much more available in
Closes https://github.com/facebook/react-native/pull/1616
Github Author: Jacob Rosenthal <jakerosenthal@gmail.com>
2015-07-14 09:08:30 -08:00
Jean Regisser 9936a2406d [TabBarIOS] Add translucent property to TabBarIOS
Summary:
To be on par with NavigatorIOS, I added the translucent property to TabBarIOS.

Usage:
```
<TabBarIOS
 translucent={false} // default is true
/>
```
Closes https://github.com/facebook/react-native/pull/1937
Github Author: Jean Regisser <jean.regisser@gmail.com>
2015-07-14 08:02:44 -08:00
Martín Bigio 691a1dafd1 s/RKScrollViewManager/RCTScrollViewManager 2015-07-14 07:52:30 -08:00
Nick Lockwood 0c61b49f0a Improved RCTCache performance + fixed border color crash
Summary:
RCTCache had really bad insertion performance when the cache was full due to having to LRU-sort the entries. This was making color
animations very slow.

I've fixed this in two ways:

1) by removing the sort and doing a linear search to remove old entries, which changes insertion perf to O(n) in the worst case instead of O(n log n) or even (n2).

2) by reducing the size of the color cache to 128 from 1024, which should be fine for normal use, without penalising animation performance.

Separately, border colors were not being retained, which caused crashes when the color cache was cleared. I've fixed that by retaining the border colors inside RCTView.
2015-07-14 04:56:25 -08:00
Nick Lockwood b34a85f4da Merged RCTStaticImage with FB internal version
Summary:
Merged RCTStaticImage with our internal RKStaticImage and ported over logic where assets are loaded at the optimal size and reloaded if the view size changes.
2015-07-14 04:06:18 -08:00
Alex Akers a65bbe14d3 [React Native] Update additional callsites with RCTResponseErrorBlock 2015-07-14 03:59:18 -08:00
Vladislav Alexeev be2cabc3f8 Dynamic Text Sizes for Text component
Summary:
Dynamic Text Sizes for Text component.
Text gains new prop - allowFontScaling (true by default).
There is also AccessibilityManager module that allows you to tune multipliers per each content size category, but predefined multipliers are there.
This could potentially break some apps so please test carefully.
2015-07-14 03:13:32 -08:00
Alex Akers eb06659711 [React Native] Update code comments about layout-only view 2015-07-14 02:52:45 -08:00
Isken Huang 6357931b61 add cli bundle url params 2015-07-14 10:40:39 +08:00
Nathan Spaun 875ab073ea [Treehouse] Sync from android permalink keyboard layout changes 2015-07-13 18:29:54 -08:00
Spencer Ahrens 0d153562be Merge pull request #1978 from sahrens/Updates_for_Mon_July_13th
Updates for mon july 13th
2015-07-14 02:18:18 +02:00
Spencer Ahrens 31b63ade13 Updates_for_Mon_July_13th 2015-07-14 00:27:24 +02:00
Spencer Ahrens 509e9c96e2 [ReactNative] Disable flaky Layout only node scenario tests 2015-07-13 14:20:10 -08:00
Param Aggarwal e1ce646275 Stray import statement - RCTTouchHandler
Summary:
Closes https://github.com/facebook/react-native/pull/1970
Github Author: Param Aggarwal <paramaggarwal@gmail.com>
2015-07-13 12:47:18 -08:00
Spencer Ahrens e5f7200213 [ReactNative] Fix crash in ListView 2015-07-13 12:36:56 -08:00
James Ide 9f07b9a2b6 [ListView] Operate on the true scroll responder instead of the scroll component
Summary:
When composing scroll views, `this.refs[SCROLLVIEW_REF]` may refer to another higher-order scroll component instead of a ScrollView. This can cause issues if you expect to need it to be a ScrollView backed by an RCTScrollView.

The solution is to call `getScrollResponder()` - as long as all higher-order scroll components implement this method, it will make its way down to the true ScrollView, which is what ListView wants here.

Closes https://github.com/facebook/react-native/pull/1927
Github Author: James Ide <ide@jameside.com>
2015-07-13 12:36:55 -08:00
James Ide d5943b0e47 [Image] Add support for tintColor to remote images
Summary:
Remote images now support the `tintColor` prop.

Also picked nicer demo colors for the UIExplorer example.

Fixes #1867

Closes https://github.com/facebook/react-native/pull/1932
Github Author: James Ide <ide@jameside.com>
2015-07-13 10:36:32 -08:00
Nick Lockwood 90dd7a13f0 Added support for URLs pointing to files inside application home 2015-07-13 10:34:48 -08:00
Alex Kotliarskyi d1b14ef062 [React Native] Log to ASL
Summary:
By default we were just writing all log messages to stderr. This also
adds support for [Apple System Log](https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/asl_log.3.html) that
can be viewed using standard tools.
2015-07-13 09:52:16 -08:00
Krzysztof Magiera 47315af069 [ReactNative] Fix SPY_MODE to show all JS->N communication. 2015-07-13 09:43:04 -08:00
Nick Lockwood 01151f8c7a Added LRU cache to fix out of memory issues with color caching 2015-07-13 08:50:00 -08:00
Alex Akers 4beef5bec3 [React Native] Re-enable testScenario{1,2}
Summary:
The tests are passing locally. Not sure why they weren't passing on FB CI.
2015-07-13 07:16:52 -08:00
Spencer Ahrens 9c4b9973f9 [ReactNative] add _flowconfig and _gitignore to SampleApp 2015-07-13 06:39:18 -08:00
Sam Mueller f732e46581 Clarify docs to use animated over react-tween-state & rebound 2015-07-10 14:04:45 -07:00
Hedger Wang 2cbcfcea88 [Android][JS]: supports prop "html" in WebView 2015-07-10 12:33:16 -08:00
Jared Forsyth 2b916f3cef Merge pull request #1947 from jaredly/Hotfix_Fri_10_July
Hotfix fri 10 july
2015-07-10 13:19:50 -07:00
Jared Forsyth 98a00f4840 Hotfix from Fri 10 July 2015-07-10 13:01:05 -07:00
Jared Forsyth b54594e42b [react native] fix inspector touch bug 2015-07-10 11:53:23 -08:00
Nick Lockwood f6d058dfea Merge pull request #1943 from nicklockwood/update_fri_10_jul
Updates for Friday 10th July
2015-07-10 18:07:28 +01:00
Nick Lockwood 7fa08e5c3f Updates for Fri 10 Jul 2015-07-10 17:48:12 +01:00
Nick Lockwood 9229eadff0 Fixed ART Text
Summary:
ART text was crashing due to a bug in the release logic.
2015-07-10 08:31:21 -08:00
Nick Lockwood 4f464962a0 Added missing semver dependency 2015-07-10 07:34:44 -08:00
Alexsander Akers ea959af850 [React Native] Fix test failures 2015-07-10 06:56:50 -08:00
Alexsander Akers 72b50dc32d [React Native] Update image downloader
Summary:
Change `RCTImageDownloader` so it stores the `RCTDownloadTaskWrapper` for reuse. Modify `RCTDownloadTaskWrapper` to use associated objects to store the completion/progress blocks.
2015-07-10 06:34:22 -08:00
Dmitriy Loktev 8e70c7f003 [Image] Add onLoadStart, onLoadProgress, onLoadError events to Image component
Summary:
This PR adds 4 native events to NetworkImage.

![demo](http://zippy.gfycat.com/MelodicLawfulCaecilian.gif)

Using these events I could wrap `Image` component into something like:
```javascript
class NetworkImage extends React.Component {
  getInitialState() {
    return {
      downloading: false,
      progress: 0
    }
  }

  render() {
    var loader = this.state.downloading ?
      <View style={this.props.loaderStyles}>
        <ActivityIndicatorIOS animating={true} size={'large'} />
        <Text style={{color: '#bbb'}}>{this.state.progress}%</Text>
      </View>
      :
      null;

    return <Image source={this.props.source}
      onLoadStart={() => this.setState({downloading: true}) }
      onLoaded={() => this.setState({downloading: false}) }
      onLoadProgress={(e)=> this.setState({progress: Math.round(100 * e.nativeEvent.written / e.nativeEvent.total)});
      onLoadError={(e)=> {
        alert('the image cannot be downloaded because: ', JSON.stringify(e));
        this.setState({downloading: false});
      }}>
      {loader}
    </Image>
  }
}
```
Useful on slow connections and server errors.

There are dozen lines of Objective C, which I don't have experience with. There are neither specific tests nor documentation yet. And I do realize that you're already working right now on better `<Image/>` (pipeline, new asset management, etc.). So this is basically a proof concept of events for images, and if this idea is not completely wrong I could improve it or help somehow.

Closes https://github.com/facebook/react-native/pull/1318
Github Author: Dmitriy Loktev <unknownliveid@hotmail.com>
2015-07-10 06:34:21 -08:00
Kostiantyn Koval 54c21ac651 add NSSet type to RCTConvert
Summary:
Add support for NSSet type
Closes https://github.com/facebook/react-native/pull/1938
Github Author: Kostiantyn Koval <konstantin.koval1@gmail.com>
2015-07-10 04:19:05 -08:00
Alex Akers ffaf16283f [React Native] Add new E2E tests 2015-07-10 04:12:28 -08:00
James Ide 40a043109d [io.js] Print a warning message if the user is not on io.js 2.x
Summary:
Detects if the user is on Node or io.js 1.x and prints a banner explaining how to upgrade. We probably should link to more detailed upgrade docs so this is just a start.

I also added a function to format banners that is kind of useful.

Addresses part of #1737

![packager-banner](https://cloud.githubusercontent.com/assets/379606/8447050/ad615402-1f67-11e5-8c02-ece5f7488135.png)

Closes https://github.com/facebook/react-native/pull/1824
Github Author: James Ide <ide@jameside.com>
2015-07-10 00:32:46 -08:00
Brent Vatne 86c815f1d4 Merge pull request #1930 from kphed/master
Minor grammatical fixes to EmbeddedApp.md
2015-07-09 20:42:35 -07:00
Khoa Phan 572157d14b Minor grammatical fixes:
1. 'Install' should be 'installed' (past tense)
2. Change 'checkout' to 'check out'
2015-07-09 19:48:25 -07:00
LYK fc059857e2 [Text] Get the system font instead of Helvetica programmatically and add a virtual fontName called "System"
Summary:
Get the system font instead of Helvetica programmatically and add a virtual fontName called "System" that defaults to whatever the current system font is.
#1611
Closes https://github.com/facebook/react-native/pull/1635
Github Author: LYK <dalinaum@gmail.com>
2015-07-09 15:48:49 -08:00
Peter Zich 10bb054b62 [react-native] Typo fix (s/monolithically/monotonically/) 2015-07-09 14:40:50 -08:00
Matthew Arbesfeld 23909cd6f6 [Image] Support loading images from application home directory.
Summary:
Image source uri's prefixed with ~ are expanded into a full path to
the app directory.

For example: `~/Documents/foo.png` is expanded into `Users/arbesfeld/Library/Developer/CoreSimulator/Devices/977988DF-A8BC-4CE5-A27A-75807A6DF085/data/Containers/Data/Application/CBEFC261-5900-4EF9-8646-603BC57B094A/Documents/foo.png`.

This lets us store and use images from the application home directory with the `Image` component:

```
<Image source={{uri: '~/Documents/foo.png', width: 300, height: 300}} />
```

Resolves #1178
Closes https://github.com/facebook/react-native/pull/1740
Github Author: Matthew Arbesfeld <arbesfeld@gmail.com>
2015-07-09 12:58:26 -08:00
Olivier Notteghem e1f53c043c Restore SPY mode to sniff traffic across bridge 2015-07-09 09:23:27 -08:00
Tadeu Zagallo 1419941f8e [ReactNative] Log with RCTPerformanceLogger only once per bridge instance
Summary:
Fixes #1809

Even if a bridge has more than one root view, it's not supported by the js side
right now, and it will keep warning that those timespans had already been
recorded.
2015-07-09 07:35:16 -08:00
Spencer Ahrens 8a5fa6cb3a Merge pull request #1899 from sahrens/AnimatedDocs
Add new Animated API to animation docs.
2015-07-09 14:48:28 +02:00
Spencer Ahrens bda7f7389a Add new Animated API to animation docs. 2015-07-09 14:47:47 +02:00
Spencer Ahrens a2578fed3c Merge pull request #1900 from sahrens/Update_Tue_Jul_7_Animated
Updates from Tue July 7 and Wed July 8th - includes new Animated API
2015-07-09 14:22:51 +02:00
Spencer Ahrens 233f80d6c2 Fix tests
e2e flowconfig needed update, plus tweaks
2015-07-09 14:12:56 +02:00
Spencer Ahrens 7ce8cd7222 Updates Tue July 7th and Wed July 8th including Animated 2015-07-09 12:59:47 +02:00
Spencer Ahrens fd2cb763df [ReactNative] add immutable dependency for NavigationRouteStack 2015-07-09 02:53:02 -08:00
Spencer Ahrens 04fe80b7a0 [ReactNative] Export Easing module so folks can use it 2015-07-09 02:44:13 -08:00
Spencer Ahrens 7d4b1877ae [RN] add Animated test for spring tracking 2015-07-09 01:59:49 -08:00
Krzysztof Magiera 9b162d7659 [ReactNative] Add support for onLayout View property. 2015-07-09 00:56:09 -08:00
Hedger Wang 21b98b23c9 [Navigator] Introducing NavigationRouteStack.
Summary:
Introducing the data structure NavigationRouteStack that focused on managing
navigation routes stack.

The goal is to make <Navigatior /> thinner by moving stack management logic into
its own class and make sure it's well-tested.

Teh next step will be cleaning up <Navigatior /> and add `NavigationRouteStack` to
`NavigationContext`.
2015-07-08 16:58:11 -08:00
Jarrod Mosen bb07817023 Update SegmentedControlIOSExample.js
Summary:
`event.nativeEvent` now uses `selectedSegmentIndex`, not `selectedIndex`.
Closes https://github.com/facebook/react-native/pull/1872
Github Author: Jarrod Mosen <jarrod.mosen@me.com>
2015-07-08 12:52:04 -08:00
Jani Evakallio b5c1cd7918 [Navigator] Guard navigator.state.routeStack from accidental mutation
Summary:
A minor improvement suggestion: `Navigator.getCurrentRoutes()` probably shouldn't return its `routeStack` backing array as-is, because the caller may mutate it, causing the internal state of the navigator to go out of sync. Instead a shallow copy of the routes should be returned.

I stumbled on this problem in my app by attempting to read the navigator state as follows:
```
let routes = Navigator.getCurrentRoutes();
let current = routes.pop();
let previous = routes.pop();
```

Which led to an exception at next navigation event.

CLA signed.

Closes https://github.com/facebook/react-native/pull/1888
Github Author: Jani Evakallio <jani.evakallio@gmail.com>
2015-07-08 12:49:52 -08:00
philipp.krone 4b5b952c32 Changing Error to Warning
Summary:
As discussed with @nicklockwood in the issue https://github.com/facebook/react-native/issues/1780, the error should be changed to a warning to not break fetch() to send a POST to a remote API without wanting to parse the reply. E.g. google sends back an empty 1x1px gif when POSTing something to google analytics.
Closes https://github.com/facebook/react-native/pull/1860
Github Author: "philipp.krone" <kronep@googlemail.com>
2015-07-08 09:36:13 -08:00
Alex Akers bfbc280fb4 [React Native] Fix scroll view sticky headers
Summary:
The `ScrollView` component tells the native side the subview indices of the views to make sticky. The problem is that, once layout-only views are collapsed, the indices are no longer reflective of the original views to make stick to the top.
2015-07-08 09:35:16 -08:00
Spencer Ahrens c66b1c64b5 [RN] quick fix to unblock OSS tests
Summary:
For some reason jest on github isn't checking invariants.
2015-07-08 07:46:41 -08:00
Nick Lockwood a886e4c66b Migrated RCTText into FBReactKit 2015-07-08 07:13:00 -08:00
Spencer Ahrens 57513fd24a make npm test command easier to find 2015-07-08 14:03:05 +02:00
Spencer Ahrens 2829be7de6 Note about setting up jest environment (io.js etc) 2015-07-08 14:01:28 +02:00
Spencer Ahrens 0d0b4c947b [RN: Animated] Fix delay anims
Summary:
They weren't calling onEnd because of duration: 0 optimiziation.
2015-07-08 03:18:13 -08:00
James Ide b3e0a702a7 [ListView] Allow different types of ScrollView to be composed
Summary:
This enables code like:
```js
<ListView renderScrollView={() => <CustomScrollView />} />
```

where CustomScrollView might be inverted or support pull-to-refresh, etc.
Closes https://github.com/facebook/react-native/pull/785
Github Author: James Ide <ide@jameside.com>
2015-07-08 02:35:29 -08:00
Natansh Verma 98521eb16e Revert "[ReactNative] Fix RCTJavaScriptContext deallocation" 2015-07-07 23:37:07 -08:00
Natansh Verma f21e79d5e1 Revert "[ReactNative] Fix crash when reload during profile" 2015-07-07 23:37:07 -08:00
Tadeu Zagallo 0ffb2d36eb [ReactNative] Fix crash when reload during profile
Summary:
Fixes #1642

When reloading during profiling, the profile wouldn't unhook from the instance
being deallocated.
2015-07-07 18:31:17 -08:00
Tadeu Zagallo a251316a5f [ReactNative] Fix RCTJavaScriptContext deallocation
Summary:
The context wasn't being explicitly released before, since it'd be immediately
released. Now that the executors are bridge modules, it was only being deallocated
when the modules were released, what caused the threads to not be released at all.
2015-07-07 18:31:17 -08:00
Hedger Wang bb141e3a3c Rename prop "injectedJavascriptIOS" to "injectedJavaScript
Summary:
Android WebView now supports the prop "injectedJavaScript", too.
It's time to rename "injectedJavascriptIOS" to "injectedJavaScript" for API
consistency between IOS and Android.
2015-07-07 17:17:22 -08:00
Nick Lockwood 1b7699f671 Migrate unit tests from FBReactKitModules to FBReactKit 2015-07-07 16:39:35 -08:00
Brent Vatne 90022023c9 Merge pull request #1802 from ide/iojs-docs
[Docs] Update installation docs to reference io.js instead of Node
2015-07-07 16:35:25 -07:00
Jean Regisser 5c01b1e1a0 Fix incorrect lowercase response headers set for XHR responses
Summary:
Trivial change to fix the lowercase response headers set for XHR responses.

What would happen is the first iterated header wouldn't be part of `_lowerCaseResponseHeaders`.
Also it would mutate the original `responseHeaders` object, mixing lowercase headers with the original values.
Closes https://github.com/facebook/react-native/pull/1876
Github Author: Jean Regisser <jean.regisser@gmail.com>
2015-07-07 15:05:45 -08:00
Spencer Ahrens 566ca9e58d [ReactNative] fix duplicate LayoutAnimation warning 2015-07-07 14:15:04 -08:00
Spencer Ahrens b770310555 [ReactNative] Move Animated to Open Source
Summary:
Moves the files over and Exports Animated from 'react-native'.
2015-07-07 13:44:09 -08:00
Spencer Ahrens d56ff42596 [ReactNative] Animated infra - ValueXY, addListener, fixes, etc
Summary:
This is most of the infra necessary for the gratuitous animation demo app.

I originally had things more split up, but it was just confusing because everything is so interlinked and dependent, so lower diffs would have code that wasn't even going to survive (and thus not useful to review), so I merged it all here.

- `Animated.event` now supports mapping to multiple arguments (needed for `onPanResponderMove` events which provide the `gestureState` as the second arg.
- Vectors: new `Animated.ValueXY` class which composes two `Animated.Value`s for convenience/brevity
- Listeners: values and events can be listened to in order to trigger state updates based on their values.  Intended to work as async updates from native that might lag behind truth.
- Offsets: a common pattern with pan and other gestures is to track where you left off.  This is easily encoded in the Value directly with `setOffset(offset)`, typically used on grant, and can be flattened back into the base value and reset with `flattenOffset()`, typically called on release.
- Tracking: supports `Animated.Value/ValueXY` for `toValue` with all animations, enabling linking multiple values together with some curve or physics.  `Animated.timing` can be used with `duration: 0` to rigidly link the values with no lag, or `Animated.spring` can be used to link them like chat heads.
- `Animated.Image` as a default export.
- Various cleanup, bug, flow and lint fixes.
2015-07-07 13:44:07 -08:00
Alex Akers c928d9495b [React Native] Fix whitespace 2015-07-07 12:12:01 -08:00
Brent Vatne c27defee7b Merge pull request #1894 from colinramsay/patch-1
Update NativeModule documentation to show correct event emitter usage
2015-07-07 10:11:40 -07:00
Alex Akers 3c541ca540 [React Native] Update native error callback handling
Summary:
This introduces a new `RCTResponseErrorBlock` block type that allows a bridge module writer to call it with an `NSError` instance rather than a dictionary.
2015-07-07 08:54:05 -08:00
Martín Bigio 66d3f3c616 [rn] Keep native ListView child frames in sync on JS wrapper
Summary: At the moment the `ListView.js` `_childFrames` variable is only updated on scroll. As a consequence, `onChangeVisibleRows` won't get triggered for the initial render, nor any future render not trigered by scroll events. To fix this we need to make sure native and JS have the child frames in sync.
2015-07-07 07:40:56 -08:00
KJlmfe b57a14d07c <Text> module add textDecoration style attributes
Summary:
This is simply a rebased and squashed version of @KJlmfe's PR over at https://github.com/facebook/react-native/pull/845

It was actually already squashed into one commit, but for some reason that was hard to see from the original PR.
Closes https://github.com/facebook/react-native/pull/1869
Github Author: KJlmfe <kjlmfe@gmail.com>
2015-07-07 06:15:20 -08:00
Colin Ramsay b13e2e8c2e Update NativeModule documentation to show correct event emitter usage
It looks like in the various changes to native module events, the documentation has become a little confused. As far as I can tell, if you use `sendAppEventWithName` then the `NativeAppEventEmitter` is used and if `sendDeviceEventWithName` then it should be `DeviceEventEmitter`.
2015-07-07 15:04:50 +01:00
Alexsander Akers 02db374e50 [React Native] Remove layout-only nodes (Take 2!)
Summary:
Remove layout-only views. Works by checking properties against a list of known properties that only affect layout. The `RCTShadowView` hierarchy still has a 1:1 correlation with the JS nodes.

This works by adjusting the tags and indices in `manageChildren`. For example, if JS told us to insert tag 1 at index 0 and tag 1 is layout-only with children whose tags are 2 and 3, we adjust it so we insert tags 2 and 3 at indices 0 and 1. This keeps changes out of `RCTView` and `RCTScrollView`. In order to simplify this logic, view moves are now processed as view removals followed by additions. A move from index 0 to 1 is recorded as a removal of view at indices 0 and 1 and an insertion of tags 1 and 2 at indices 0 and 1. Of course, the remaining indices have to be offset to take account for this.

The `collapsible` attribute is a bit of a hack to force `RCTScrollView` to always have one child. This was easier than rethinking out the logic there, but we could change this later.
2015-07-07 05:06:50 -08:00
Alexsander Akers fe2155e238 Merge pull request #1893 from a2/Update_Tue_7_Jul
Updates from Tuesday, 7 July
2015-07-07 14:05:39 +01:00
Alexsander Akers 3325e8f768 Updates from Tuesday, 7 July 2015-07-07 13:56:11 +01:00
Param Aggarwal 0f2d8e662e [ScrollView] Pick data from older event on coalescing.
Summary:
The `ScrollView` sends important `updatedChildFrames` data to the `ListView` to be able to implement `onChangeVisibleRows` method. Coalescing operates very strongly on older devices like the iPhone 4s where this data is then lost.

Fixes #1782.

`ListView` has a method called `onChangeVisibleRows` that is called whenever the rows visible on screen change. This method is critical to be able to implement deletion/creation of views and hence be conservative in memory usage. I have an infinite scrolling view which uses this method to only render the full rows for what is visible on screen and put placeholders for everything else.

In the `RCTEventDispatcher`, we [coalesce events](https://github.com/facebook/react-native/blob/522fd33d6f3c8fb339b0dde35b05df34c1233306/React/Base/RCTEventDispatcher.m#L135-L152) that are meant to be sent across the bridge. They are [dequeued](https://github.com/facebook/react-native/blob/522fd33d6f3c8fb339b0dde35b05df34c1233306/React/Base/RCTEventDispatcher.m#L180-L188) on each
Closes https://github.com/facebook/react-native/pull/1783
Github Author: Param Aggarwal <paramaggarwal@gmail.com>
2015-07-06 17:27:40 -08:00
Eric Vicenti 65027e8e29 [ReactNative] Fix timeout edge-case in POPAnimation hack 2015-07-06 15:15:56 -08:00
Pieter De Baets 3955236b0f Update StaticContainer from static_upstream 2015-07-06 15:06:59 -08:00
Nick Lockwood 652ffa28b2 Added regenerator to node_modules 2015-07-06 14:08:06 -08:00
Alex Akers c065d98112 [React Native] Change nil to Nil because it's more correct
Summary: #OCD
2015-07-06 11:15:45 -08:00
Brent Vatne c045c566e9 Remove unnecessary imports for RCTHTTPRequestHandler to fix Cocoapods build
Summary:
@tadeuzagallo - We discussed this ~a week ago when I was putting together the 0.7.0-rc release, only got around to creating the PR for it now so it's properly sync'd.
Closes https://github.com/facebook/react-native/pull/1865
Github Author: Brent Vatne <brentvatne@gmail.com>
2015-07-06 10:12:43 -08:00
Alex Akers ca791dfe6f [React Native] Update RCTAdSupport
Summary:
No longer check for the `ASIdentifierManager` class. Since we only target iOS 7.0 and up, this is unnecessary. Instead, we should check for whether the `advertisingIdentifier` is non-nil. If it is, we send it; otherwise we send an error.
2015-07-06 09:44:51 -08:00
Pieter De Baets 7e70ee2e03 Check for RCTSettingsManager in Settings.ios 2015-07-06 04:47:04 -08:00
Alex Akers b4cd019f39 [React Native] Remove animated GIFs from TicTacToe example 2015-07-06 04:11:03 -08:00
James Ide f5ad9c2103 [Crashfix] Replace dispatch_get_current_queue with DISPATCH_CURRENT_QUEUE_LABEL
Summary:
I encountered a crash when `RCTCurrentThreadName` called `dispatch_get_current_queue`. There are reports of it crashing e.g. https://github.com/CocoaLumberjack/CocoaLumberjack/issues/108 so better not to call it at all, plus it is deprecated.

Since we still want helpful debugging information, use `DISPATCH_CURRENT_QUEUE_LABEL` instead. It's kind of strange that this constant is defined to be NULL and the docs for `dispatch_get_queue_label` say not to pass in NULL, but in practice `DISPATCH_CURRENT_QUEUE_LABEL` is provided by the iOS SDK and works correctly.

Closes https://github.com/facebook/react-native/pull/1868
Github Author: James Ide <ide@jameside.com>
2015-07-06 03:17:03 -08:00
Alex Akers aba148061f [React Native] Re-alphabetize file names in Xcode projects
Summary:
Fixes my OCD problems.
2015-07-06 01:57:06 -08:00
Alexsander Akers fe9af98a28 Merge pull request #1694 from prathamesh-sonpatki/async-storage
[DOC] Removed unwanted "e.g" from documentation of multiSet
2015-07-05 11:37:41 +02:00
Alexsander Akers 60b56455c4 Merge pull request #1858 from a2/Update_Thu_3_Jul
Updates from Thursday, 3 July
2015-07-03 13:36:32 +01:00
Alexsander Akers e37e794ccf Merge new changes from fbobjc 2015-07-03 13:22:43 +01:00
Alex Akers 93d3cc135d [React Native] Fix failing UIExplorer integration tests 2015-07-03 04:15:54 -08:00
Alexsander Akers c1d7c0df47 Updates from Thu 3 Jul 2015-07-03 11:37:17 +01:00
Alex Akers 16cb41a24e [React Native] Fix padding in UIExplorer 2015-07-03 02:24:56 -08:00
Alex Akers 4fdeed0214 [React Native] Fix crash if current queue has no label
Summary:
If the current queue has no label, `dispatch_queue_get_label()` returns `NULL` and `@((char *)0)` will crash the app.

Closes facebook#1833
2015-07-03 02:24:30 -08:00
Alex Akers 88cfc1aaa6 [React Native] Fix navigation bar translucency 2015-07-03 02:12:28 -08:00
James Ide 3441847aa1 [Crashfix] Ensure that the image response is non-nil before caching it
Summary:
If you try to create a cached response from a nil response the app will crash. Looking at the code that uses NSURLSession and NSURLCache, this fix looks correct to me.

Fixes #1850

Closes https://github.com/facebook/react-native/pull/1852
Github Author: James Ide <ide@jameside.com>
2015-07-03 02:01:20 -08:00
Rui Chen 66e32dc406 [Treehouse RN] Sync for D2161376 2015-07-02 19:50:47 -08:00
Eric Vicenti 4e650f05d1 [ReactNative] setTimeout hack avoids POPAnimation race condition
Summary:
Having bugs in Groups because POPAnimation experiences a race condition. This hack avoids that for now while we transition away from POPAnimation altogether.
2015-07-02 10:51:48 -08:00
James Ide a97a866570 [Docs] Update installation docs to reference io.js instead of Node
It's pretty straightforward -- io.js is available through Homebrew so all you run is `brew install iojs` and then you can still run `node` from the command line. Also mentioned nvm since it's really good for switching between Node/io.js versions.
2015-07-02 11:42:25 -07:00
Alex Akers 00e85cbc85 [React Native] Persist open UIExplorer example between refreshes 2015-07-02 09:36:26 -08:00
Alexsander Akers 1d1386e735 Merge pull request #1839 from a2/Update_Wed_1_Jul
Updates from Wed 1 Jul
2015-07-02 12:15:35 +01:00
Alexsander Akers 13be9454cc Update with test fixes 2015-07-02 11:19:17 +01:00
Hedger Wang 54825b304a [WebView]: Kill shouldInjectAJAXHandler, and add injectedJavascriptIOS
Summary:
@public

The API and implementation of `shouldInjectAJAXHandler` is very opinionated, and it does not solve many of the use cases that we'd like to address.

Since  `shouldInjectAJAXHandler` is basically juts injecting JS to the web page, we should let developer inject whatever JS that address different issues that they want to fix.

Test Plan:
Test this snippet at <Playground />

```
<WebView
  url="http://www.facebook.com"
  injectedJavascriptIOS="document.body.style.border='solid 10px red'"
/>
```
2015-07-01 18:56:14 -08:00
Amjad Masad b45e2ed7ed [react-packager] fix test 2015-07-01 17:37:51 -08:00
Alexsander Akers d0cb80c072 Merge branch 'iojs-tests' of https://github.com/ide/react-native into Update_Wed_1_Jul
Conflicts:
	package.json
2015-07-01 22:07:41 +01:00
Alexsander Akers 4886b3dc57 Merge branch 'flow-13' of https://github.com/ide/react-native into Update_Wed_1_Jul 2015-07-01 22:06:24 +01:00
Alexsander Akers d161640f52 Update with required PRs 2015-07-01 22:05:10 +01:00
James Ide 5aa27586f0 [Tests] Update tests to run on io.js with the latest version of jest
Summary:
[This is a preview diff for getting RN's tests to pass with a future version of jest that supports io.js and other future versions of Node. This can be merged once the diff to update jest is merged upstream and published.]

Updates the tests in small ways so they run on io.js with two updates:

 - The Cache test which relies on Promises uses `runAllImmediates` for modern versions of Node because bluebird uses `setImmediate` instead of `process.nextTick` for Node >0.10.

Closes https://github.com/facebook/react-native/pull/1382
Github Author: James Ide <ide@jameside.com>

Test Plan:  Run `npm test` with the latest version of jest.
2015-07-01 13:02:29 -08:00
James Ide 7a8398b956 [Flow] Update flowconfig's version req to 0.13.1, fix Movies example typechecking
Summary:
This should fix tests.

Closes https://github.com/facebook/react-native/pull/1819
Github Author: James Ide <ide@jameside.com>

Test Plan:  Run Travis CI tests. Also run the movies app and verify that there are no invariant violations.
2015-07-01 13:01:52 -08:00
James Ide 212bd2250c [Tests] Update tests to run on io.js with the latest version of jest
Updates the tests in small ways so they run on io.js with some updates:

 - The Cache test which relies on Promises uses `runAllImmediates` for modern versions of Node because bluebird uses `setImmediate` instead of `process.nextTick` for Node >0.10.

Test Plan: Run `npm test` with the latest version of jest.
2015-07-01 11:38:17 -07:00
Alexsander Akers 44c587e828 Updates from Wed 1 Jul 2015-07-01 19:10:35 +01:00
Joe Savona 776dc97437 InteractionManager: remove dev timeout warnings 2015-07-01 04:51:28 -08:00
James Ide 5418cdf071 [CocoaPods] Run npm install --production when installing React.podspec
Summary:
This omits the devDependencies (e.g. test infra), which are intended only for people working on RN.

Part of #1737.
Closes https://github.com/facebook/react-native/pull/1803
Github Author: James Ide <ide@jameside.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-07-01 03:18:05 -08:00
Philipp von Weitershausen 14fef6474d [ReactNative] expose missing haste modules through 'react-native' node module 2015-06-30 18:57:26 -08:00
Alex Kotliarskyi d7ddff7554 [ReactNative] Fix dev menu customization when JS fails to load 2015-06-30 17:13:27 -08:00
James Ide 301c01260d [Flow] Update flowconfig's version req to 0.13.1, fix Movies example typechecking
This should fix tests.

Test Plan: Run Travis CI tests. Also run the movies app and verify that there are no invariant violations.
2015-06-30 16:52:55 -07:00
Brent Vatne 4e6f48c650 Merge pull request #1820 from rnplay/runnable-docs
Start adding links to runnable examples in the documentation
2015-06-30 14:51:07 -07:00
Joshua Sierles 5af8849aa4 [Docs] Add a 'run this example' link to AlertIOS docs, plus supporting code to add more links progressively 2015-06-30 23:39:49 +02:00
James Ide eee630827a Merge pull request #1818 from facebook/amasad-patch-1
Don't encourage the use of internal modules
2015-06-30 13:13:50 -07:00
James Ide 5a206d2fee Merge pull request #1817 from facebook/amasad-docs-patch
Don't encourage the use of internal modules
2015-06-30 13:13:13 -07:00
Amjad Masad 82ca3364c6 Don't encourage the use of internal modules 2015-06-30 13:12:47 -07:00
Amjad Masad e5ba0f388b Don't encourage the use of internal modules 2015-06-30 13:12:00 -07:00
Brent Vatne 97bf9a6b4d Merge pull request #1811 from dhrrgn/dhrrgn-timermixin-docs
[Docs] Update TimerMixin docs.
2015-06-30 10:41:50 -07:00
Dan Horrigan cae410bda0 [Docs] Update TimerMixin docs.
Adds in install instructions for `react-timer-mixin` to the `TimerMixin` docs.
2015-06-30 13:23:40 -04:00
James Ide e3225f3403 [Bridge] Support nullability annotations in bridged methods
Summary:
Fixes a crash due to the selector regex not knowing about the nullability annotations. Adds support for both the core annotations `__nullable` and `__nonnull` plus their shorthand counterparts `nullable` and `nonnull`.

Objective-C allows the shorthand versions only at the front of a parameter type declaration like `(nullable NSString *)` but the regex will pick up `(NSString * nullable)` too. This shouldn't cause any adverse effects and I left the code this way to keep the regex readable.

Fixes #1795

Closes https://github.com/facebook/react-native/pull/1796
Github Author: James Ide <ide@jameside.com>

Test Plan:
 Wrote a bridge method that uses a nullability annotation and verified that it didn't cause the app to crash:
```
RCT_EXPORT_METHOD(method:(nullable NSNumber *)reactTag)
{
}
```

Also added a nullable annotation to RCTTest.
2015-06-30 04:17:20 -08:00
Amjad Masad 7d184adf1a [react-packager] Use latest babel-core in place of babel (40% perf improvement) 2015-06-30 03:55:21 -08:00
Jeff Morrison 9f22f67599 [flow 0.13.1] Deploy to 2015-06-29 20:49:05 -08:00
Dmitry Soshnikov 555236865b [react-native][jest] Sync to 0.5.x and update to io.js 2015-06-29 20:36:34 -08:00
Matt Revell cf6ff3f815 #1562 Rename 'tick' to 'onTick' to pass iTunes Connect validation.
Summary:
Should close this issue and successfully pass iTunes Connect validation.
Closes https://github.com/facebook/react-native/pull/1722
Github Author: Matt Revell <mattrevell82@me.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-29 06:51:44 -08:00
Alex Akers 454b5f3c0b [React Native] Replace RCTCache with NSURLCache 2015-06-29 05:26:35 -08:00
James Ide c953aa7e0b [Executor] Make executor ID functions non-static to fix ASan
Summary:
When `RCTGetExecutorID` was a static function in the header file, it would return nil when the app was running with ASan enabled even though directly calling `objc_getAssociatedObject(executor, RCTJavaScriptExecutorID)` returned the correct ID as an NSNumber. Moving this function into the .m file fixes this issue.

Closes https://github.com/facebook/react-native/pull/1712
Github Author: James Ide <ide@jameside.com>

Test Plan:  Run the UIExplorer with ASan enabled in Xcode 7. Before this diff, the app would just hang since the executor was unable to read a valid ID and so it would bail out from running JS. With this diff the executor runs the JS and the UIExplorer works fine.
2015-06-29 04:30:29 -08:00
Andy Street 7196445cc6 [react_native] Update common UI examples 2015-06-29 04:20:04 -08:00
Nick Lockwood 8708c35702 Restructuring FBReactKit project: Part 2 2015-06-28 11:49:41 -08:00
Amjad Masad 73b032ab87 [react-packager] Update sane to get a new version of fb-watchman (perf) 2015-06-26 17:48:39 -08:00
Joe Wood 19e32399b0 [Packager] Windows support for Packager - Blacklist changes
Summary:
Another Pull Request implementing the changes in issue #468 - Enabled Packager to run on Windows
This change relates to the blacklist fixes. It includes the path conversion for blacklist and changes to the default watched directory.  It has no impact on Mac OSX.
Closes https://github.com/facebook/react-native/pull/893
Github Author: Joe Wood <joewood>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-26 16:27:12 -08:00
Amjad Masad de020b44c9 [react-packager] Enable watchman fs crawl
Summary:
@public
Now that watchman perf issue was fixed we can enable watchman-based fs crawling which is faster than node.
This showed an existing issue with some files missing from the blacklist which I addressed.

Test Plan:
./fbrnios.sh run
click around and scroll all the apps
2015-06-26 16:20:50 -08:00
Johannes Lumpe 1461e4a17e [Packager] Allow user to specify a custom transformer file
Summary:
This is an edited re-submission of #1458 because I'm stupid.
Closes https://github.com/facebook/react-native/pull/1497
Github Author: Johannes Lumpe <johannes@johanneslumpe.de>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-26 16:00:37 -08:00
Alexander Kotliarskyi 951b5f9517 Merge pull request #1761 from frantic/updates-26-jun
Updates from Fri, 26 Jun
2015-06-26 15:37:06 -07:00
Alex Kotliarskyi 843e181542 Updates from Fri 26, Jun 2015-06-26 15:16:59 -07:00
Spencer Ahrens 29e49bdb91 [ReactNative] LayoutAnimation brevity
Summary:
@public

Less verbose - now can just do `LayoutAnimation.easeInEaseOut()` instead of
`LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)`

Test Plan: D2171336, play with AdsManager pickers.
2015-06-26 10:48:36 -08:00
James Ide fe7edf0860 [ListView] Defer measurement one frame after componentDidMount to fix error
Summary:
When `UIManager.measure` is called from `componentDidMount` it causes the error "Attempted to measure layout but offset or dimensions were NaN". Deferring the layout by one frame solves this problem. Layout measurement is already asynchronous anyway, so I believe adding the `requestAnimationFrame` call doesn't affect the program's correctness.

Fixes #1749

Closes https://github.com/facebook/react-native/pull/1750
Github Author: James Ide <ide@jameside.com>

Test Plan:
 Load UIExplorer and no longer get a redbox that says "Attempted to measure layout but offset or dimensions were NaN".
2015-06-26 10:26:07 -08:00
Owen Kelly 1cca4fb769 [NavigatorIOS] Allow translucent on NavigatorIOS
Summary:
Hi,

I've updated the NavigatorIOS component to allow setting the translucent property.

usage is:
```
            <NavigatorIOS
                translucent={false}
            />
```

This is my first contrib to react-native, so apologies if I've missed something.

Cheers,
Owen
Closes https://github.com/facebook/react-native/pull/1273
Github Author: Owen Kelly <owen@novede.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-26 07:17:54 -08:00
Kevin Gozali 3ec3312c7c [madman]: Fix MapView crashing problem. 2015-06-25 21:21:08 -08:00
Eric Vicenti e3e60983e6 [ReactNative] Navigator improved willFocus logic
Summary:
This makes sure to call willFocus before new scenes get mounted. This fixes cases where the keyboard is dismissed on willfocus events which incorrectly happens *after* the autofocus in a new scene. The keyboard was opening and getting immediately closed

@public

Test Plan: Test keyboard autofocus in new nav scenes on iOS
2015-06-25 14:45:23 -08:00
chaceliang 7159a4e947 Revert "[React Native] Remove layout-only nodes" 2015-06-25 13:30:06 -08:00
Eric Vicenti 7963add0d5 [ReactNative] Revamp Navigator scene cache strategy
Summary:
Updating range is too complicated. We can keep cached versions of the previously rendered scenes in a map.

@public

Test Plan: Verify that the active scene is the only thing that get re-rendered, and that rendering doesn't happen during transitions or gestures. Test navigation thouroughly in AdsManager
2015-06-25 10:36:49 -08:00
Tadeu Zagallo 5e71d352a6 [ReactNative] Guard agains errors during reconciliation
Summary:
@public

After refactoring the MessageQueue a guard was missing on around `batchedUpdates`
call.

Test Plan: Introduce an error on `getInitialState` of `AdsManagerTabsModalView.ios.js`
2015-06-25 09:40:48 -08:00
Stanislav Vishnevskiy f383bf2b83 [LayoutAnimation] RCTAnimationTypeKeyboard
Summary:
This adds the Keyboard animation type for when you want to animate UI based on the keyboard appearing/disappearing.
Closes https://github.com/facebook/react-native/pull/1366
Github Author: Stanislav Vishnevskiy <vishnevskiy@gmail.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-25 09:17:01 -08:00
David Mohl 99bc08cf61 [MapView] Support for annotation callouts, annotation press, callout presses and pin animation
Summary:
Started from here - https://github.com/facebook/react-native/issues/1120. Most functionality for annotations were missing so I started implementing and somehow got caught up until the entire thing was done.

![screen shot 2015-05-12 at 10 07 43 pm](https://cloud.githubusercontent.com/assets/688326/7588677/8479a7a4-f8f9-11e4-99a4-1dc3c7691810.png)

2 new events:
- callout presses (left / right)
- annotation presses

6 new properties for annotations:
- hasLeftCallout
- hasRightCallout
- onLeftCalloutPress
- onRightCalloutPress
- animateDrop
- id

1 new property for MapView
- onAnnotationPress

---
Now the important thing is, that I implemented all of this the way "I would do it". I am not sure this is the 'reacty' way so please let me know my mistakes 😄

The problem is that there is no real way to identify annotations which makes it difficult to distinguish which one got clicked. The idea is to pass a `id` and whether it has callouts the entire way with the annotation. I had to
Closes https://github.com/facebook/react-native/pull/1247
Github Author: David Mohl <me@dave.cx>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-25 09:15:21 -08:00
Alex Akers 3c5b4b0a9f [React Native] Remove layout-only nodes
Summary:
Remove layout-only views. Works by checking properties against a list of known properties that only affect layout. The `RCTShadowView` hierarchy still has a 1:1 correlation with the JS nodes.

This works by adjusting the tags and indices in `manageChildren`. For example, if JS told us to insert tag 1 at index 0 and tag 1 is layout-only with children whose tags are 2 and 3, we adjust it so we insert tags 2 and 3 at indices 0 and 1. This keeps changes out of `RCTView` and `RCTScrollView`. In order to simplify this logic, view moves are now processed as view removals followed by additions. A move from index 0 to 1 is recorded as a removal of view at indices 0 and 1 and an insertion of tags 1 and 2 at indices 0 and 1. Of course, the remaining indices have to be offset to take account for this.

The `collapsible` attribute is a bit of a hack to force `RCTScrollView` to always have one child. This was easier than rethinking out the logic there, but we could change this later.

@public

Test Plan: There are tests in `RCTUIManagerTests.m` that test the tag- and index-manipulation logic works. There are various scenarios including add-only, remove-only, and move. In addition, two scenario tests verify that the optimization works by checking the number of views and shadow views after various situations happen.
2015-06-25 09:12:00 -08:00
Prathamesh Sonpatki ffe80fa10a [DOC] Removed unwanted "e.g" from documentation of multiSet 2015-06-20 10:31:48 +05:30
1114 changed files with 71424 additions and 11484 deletions
+9 -8
View File
@@ -9,11 +9,10 @@
# Ignore react-tools where there are overlaps, but don't ignore anything that
# react-native relies on
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
.*/node_modules/react-tools/src/browser/ui/React.js
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
.*/node_modules/react-tools/src/event/EventPropagators.js
.*/node_modules/react-tools/src/React.js
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
# Ignore commoner tests
.*/node_modules/commoner/test/.*
@@ -36,13 +35,15 @@ Examples/UIExplorer/ImageMocks.js
[options]
module.system=haste
munge_underscores=true
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-2]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-2]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version]
0.12.0
0.14.0
+7
View File
@@ -25,6 +25,13 @@ project.xcworkspace
# OS X
.DS_Store
# Android/IJ
.idea
.gradle
local.properties
*.iml
# Node
node_modules
*.log
.nvm
+7 -7
View File
@@ -10,19 +10,19 @@ cache:
before_install:
- brew update
install:
- brew reinstall flow xctool nvm
- brew reinstall xctool nvm
- rm -Rf `node -p "require('os').tmpDir()"`/jest_preprocess_cache
- npm install -g flow-bin@`node -p "require('fs').readFileSync('.flowconfig', 'utf8').split('[version]')[1].trim()"`
- mkdir -p .nvm
- cp $(brew --prefix nvm)/nvm-exec .nvm/
- export NVM_DIR=.nvm
- export NVM_DIR="$PWD/.nvm"
- source $(brew --prefix nvm)/nvm.sh
- nvm install v0.10
- nvm install iojs-v2
- nvm use iojs-v2
- npm config set spin=false
- npm install
script:
- |
nvm use v0.10
if [ "$TEST_TYPE" = objc ]
then
@@ -37,7 +37,7 @@ script:
then
cd website
npm install
$(which npm) install
./setup.sh
if [ "$TRAVIS_PULL_REQUEST" = false ] && [ "$TRAVIS_BRANCH" = master ]; then
# Automatically publish the website
+19 -25
View File
@@ -12,7 +12,7 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1461632C1AC3E22900C2F5AD /* libReact.a */; };
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */; };
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F82F1771B85784500FAE87E /* libRCTWebSocket.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
/* End PBXBuildFile section */
@@ -24,12 +24,12 @@
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = React;
};
58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */ = {
5F82F1761B85784500FAE87E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
containerPortal = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTAnimationExperimental;
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
remoteInfo = RCTWebSocket;
};
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -41,7 +41,6 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimationExperimental.xcodeproj; path = ../../Libraries/Animation/RCTAnimationExperimental.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = 2048/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = 2048/AppDelegate.m; sourceTree = "<group>"; };
@@ -50,6 +49,7 @@
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = 2048/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = 2048/main.m; sourceTree = "<group>"; };
146163271AC3E22900C2F5AD /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -58,8 +58,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */,
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */,
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */,
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -88,10 +88,10 @@
name = Products;
sourceTree = "<group>";
};
58C1E4071ACF54B4006D1A47 /* Products */ = {
5F82F1731B85784500FAE87E /* Products */ = {
isa = PBXGroup;
children = (
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */,
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */,
);
name = Products;
sourceTree = "<group>";
@@ -99,9 +99,9 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */,
146163271AC3E22900C2F5AD /* React.xcodeproj */,
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
@@ -174,14 +174,14 @@
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 58C1E4071ACF54B4006D1A47 /* Products */;
ProjectRef = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
},
{
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
},
{
ProductGroup = 5F82F1731B85784500FAE87E /* Products */;
ProjectRef = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
},
{
ProductGroup = 146163281AC3E22900C2F5AD /* Products */;
ProjectRef = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
@@ -202,11 +202,11 @@
remoteRef = 1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */ = {
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTAnimationExperimental.a;
remoteRef = 58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */;
path = libRCTWebSocket.a;
remoteRef = 5F82F1761B85784500FAE87E /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
@@ -266,10 +266,7 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = 2048;
@@ -287,10 +284,7 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = 2048;
+1
View File
@@ -52,6 +52,7 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"Game2048"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+39 -41
View File
@@ -24,7 +24,7 @@ var {
View,
} = React;
var AnimationExperimental = require('AnimationExperimental');
var Animated = require('Animated');
var GameBoard = require('GameBoard');
var TouchableBounce = require('TouchableBounce');
@@ -53,58 +53,58 @@ class Board extends React.Component {
}
class Tile extends React.Component {
static _getPosition(index): number {
return BOARD_PADDING + (index * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
}
constructor(props: {}) {
super(props);
var tile = this.props.tile;
this.state = {
opacity: new Animated.Value(0),
top: new Animated.Value(Tile._getPosition(tile.toRow())),
left: new Animated.Value(Tile._getPosition(tile.toColumn())),
};
}
calculateOffset(): {top: number; left: number; opacity: number} {
var tile = this.props.tile;
var pos = (i) => {
return BOARD_PADDING + (i * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
};
var animationPosition = (i) => {
return pos(i) + (CELL_SIZE / 2);
};
var offset = {
top: pos(tile.toRow()),
left: pos(tile.toColumn()),
opacity: 1,
top: this.state.top,
left: this.state.left,
opacity: this.state.opacity,
};
if (tile.isNew()) {
offset.opacity = 0;
} else {
var point = {
x: animationPosition(tile.toColumn()),
y: animationPosition(tile.toRow()),
};
AnimationExperimental.startAnimation({
node: this.refs['this'],
Animated.timing(this.state.opacity, {
duration: 100,
easing: 'easeInOutQuad',
property: 'position',
toValue: point,
});
toValue: 1,
}).start();
} else {
Animated.parallel([
Animated.timing(offset.top, {
duration: 100,
toValue: Tile._getPosition(tile.toRow()),
}),
Animated.timing(offset.left, {
duration: 100,
toValue: Tile._getPosition(tile.toColumn()),
}),
]).start();
}
return offset;
}
componentDidMount() {
AnimationExperimental.startAnimation({
node: this.refs['this'],
duration: 100,
easing: 'easeInOutQuad',
property: 'opacity',
toValue: 1,
});
}
render() {
var tile = this.props.tile;
var tileStyles = [
styles.tile,
styles['tile' + tile.value],
this.calculateOffset()
this.calculateOffset(),
];
var textStyles = [
@@ -115,9 +115,9 @@ class Tile extends React.Component {
];
return (
<View ref="this" style={tileStyles}>
<Animated.View style={tileStyles}>
<Text style={textStyles}>{tile.value}</Text>
</View>
</Animated.View>
);
}
}
@@ -136,10 +136,8 @@ class GameEndOverlay extends React.Component {
return (
<View style={styles.overlay}>
<Text style={styles.overlayMessage}>{message}</Text>
<TouchableBounce onPress={this.props.onRestart}>
<View style={styles.tryAgain}>
<Text style={styles.tryAgainText}>Try Again?</Text>
</View>
<TouchableBounce onPress={this.props.onRestart} style={styles.tryAgain}>
<Text style={styles.tryAgainText}>Try Again?</Text>
</TouchableBounce>
</View>
);
+3 -2
View File
@@ -37,14 +37,14 @@
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.includeRequire.runModule.bundle"];
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.ios.includeRequire.runModule.bundle"];
/**
* OPTION 2
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
* to your Xcode project folder in the terminal, and run
*
* $ curl 'http://localhost:8081/Examples/Movies/MoviesApp.includeRequire.runModule.bundle' -o main.jsbundle
* $ curl 'http://localhost:8081/Examples/Movies/MoviesApp.ios.includeRequire.runModule.bundle' -o main.jsbundle
*
* then add the `main.jsbundle` file to your project and uncomment this line:
*/
@@ -53,6 +53,7 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"MoviesApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+94
View File
@@ -0,0 +1,94 @@
/**
* 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 MoviesApp
* @flow
*/
'use strict';
var React = require('react-native');
var {
AppRegistry,
BackAndroid,
Navigator,
StyleSheet,
ToolbarAndroid,
View,
} = React;
var MovieScreen = require('./MovieScreen');
var SearchScreen = require('./SearchScreen');
var _navigator;
BackAndroid.addEventListener('hardwareBackPress', () => {
if (_navigator && _navigator.getCurrentRoutes().length > 1) {
_navigator.pop();
return true;
}
return false;
});
var RouteMapper = function(route, navigationOperations, onComponentRef) {
_navigator = navigationOperations;
if (route.name === 'search') {
return (
<SearchScreen navigator={navigationOperations} />
);
} else if (route.name === 'movie') {
return (
<View style={{flex: 1}}>
<ToolbarAndroid
actions={[]}
navIcon={require('image!android_back_white')}
onIconClicked={navigationOperations.pop}
style={styles.toolbar}
titleColor="white"
title={route.movie.title} />
<MovieScreen
style={{flex: 1}}
navigator={navigationOperations}
movie={route.movie}
/>
</View>
);
}
};
var MoviesApp = React.createClass({
render: function() {
var initialRoute = {name: 'search'};
return (
<Navigator
style={styles.container}
initialRoute={initialRoute}
configureScene={() => Navigator.SceneConfigs.FadeAndroid}
renderScene={RouteMapper}
/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
toolbar: {
backgroundColor: '#a9a9a9',
height: 56,
},
});
AppRegistry.registerComponent('MoviesApp', () => MoviesApp);
module.exports = MoviesApp;
+104
View File
@@ -0,0 +1,104 @@
/**
* 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 SearchBar
* @flow
*/
'use strict';
var React = require('react-native');
var {
Image,
Platform,
ProgressBarAndroid,
TextInput,
StyleSheet,
TouchableNativeFeedback,
View,
} = React;
var IS_RIPPLE_EFFECT_SUPPORTED = Platform.Version >= 21;
var SearchBar = React.createClass({
render: function() {
var loadingView;
if (this.props.isLoading) {
loadingView = (
<ProgressBarAndroid
styleAttr="Large"
style={styles.spinner}
/>
);
} else {
loadingView = <View style={styles.spinner} />;
}
var background = IS_RIPPLE_EFFECT_SUPPORTED ?
TouchableNativeFeedback.SelectableBackgroundBorderless() :
TouchableNativeFeedback.SelectableBackground();
return (
<View style={styles.searchBar}>
<TouchableNativeFeedback
background={background}
onPress={() => this.refs.input && this.refs.input.focus()}>
<View>
<Image
source={require('image!android_search_white')}
style={styles.icon}
/>
</View>
</TouchableNativeFeedback>
<TextInput
ref="input"
autoCapitalize="none"
autoCorrect={false}
autoFocus={true}
onChange={this.props.onSearchChange}
placeholder="Search a movie..."
placeholderTextColor="rgba(255, 255, 255, 0.5)"
onFocus={this.props.onFocus}
style={styles.searchBarInput}
/>
{loadingView}
</View>
);
}
});
var styles = StyleSheet.create({
searchBar: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#a9a9a9',
height: 56,
},
searchBarInput: {
flex: 1,
fontSize: 20,
fontWeight: 'bold',
color: 'white',
height: 50,
padding: 0,
backgroundColor: 'transparent'
},
spinner: {
width: 30,
height: 30,
},
icon: {
width: 24,
height: 24,
marginHorizontal: 8,
},
});
module.exports = SearchBar;
+6 -4
View File
@@ -26,6 +26,8 @@ var {
} = React;
var TimerMixin = require('react-timer-mixin');
var invariant = require('invariant');
var MovieCell = require('./MovieCell');
var MovieScreen = require('./MovieScreen');
@@ -73,18 +75,16 @@ var SearchScreen = React.createClass({
this.searchMovies('');
},
_urlForQueryAndPage: function(query: string, pageNumber: ?number): string {
_urlForQueryAndPage: function(query: string, pageNumber: number): string {
var apiKey = API_KEYS[this.state.queryNumber % API_KEYS.length];
if (query) {
return (
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
API_URL + 'movies.json?apikey=' + apiKey + '&q=' +
encodeURIComponent(query) + '&page_limit=20&page=' + pageNumber
);
} else {
// With no query, load latest movies
return (
// $FlowFixMe(>=0.13.0) - pageNumber may be null or undefined
API_URL + 'lists/movies/in_theaters.json?apikey=' + apiKey +
'&page_limit=20&page=' + pageNumber
);
@@ -176,6 +176,7 @@ var SearchScreen = React.createClass({
});
var page = resultsCache.nextPageNumberForQuery[query];
invariant(page != null, 'Next page number for "%s" is missing', query);
fetch(this._urlForQueryAndPage(query, page))
.then((response) => response.json())
.catch((error) => {
@@ -261,6 +262,7 @@ var SearchScreen = React.createClass({
) {
return (
<MovieCell
key={movie.id}
onSelect={() => this.selectMovie(movie)}
onHighlight={() => highlightRowFunc(sectionID, rowID)}
onUnhighlight={() => highlightRowFunc(null, null)}
@@ -306,7 +308,7 @@ var NoMovies = React.createClass({
render: function() {
var text = '';
if (this.props.filter) {
text = `No results for ${this.props.filter}`;
text = `No results for "${this.props.filter}"`;
} else if (!this.props.isLoading) {
// If we're looking at the latest movies, aren't currently loading, and
// still have no results, show a message
+35
View File
@@ -0,0 +1,35 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.facebook.react.movies"
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
// Depend on pre-built React Native
compile 'com.facebook.react:react-native:0.11.+'
// Depend on React Native source.
// This is useful for testing your changes when working on React Native.
// compile project(':ReactAndroid')
}
+17
View File
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
@@ -0,0 +1,21 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.react.movies">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@drawable/rotten_tomatoes_icon"
android:theme="@style/AppTheme">
<activity
android:name=".MoviesActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
@@ -0,0 +1,89 @@
/**
* 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.
*/
package com.facebook.react.movies;
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;
public class MoviesActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
@Override
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
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 void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onResume(this);
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

@@ -0,0 +1,12 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MoviesApp">
<com.facebook.react.ReactRootView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/react_root_view"/>
</RelativeLayout>
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">MoviesApp</string>
</resources>
@@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
+16 -6
View File
@@ -9,11 +9,11 @@
# Ignore react-tools where there are overlaps, but don't ignore anything that
# react-native relies on
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
.*/node_modules/react-tools/src/browser/ui/React.js
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
.*/node_modules/react-tools/src/event/EventPropagators.js
.*/node_modules/react-tools/src/React.js
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
# Ignore commoner tests
.*/node_modules/commoner/test/.*
@@ -32,5 +32,15 @@ node_modules/react-native/Libraries/react-native/react-native-interface.js
[options]
module.system=haste
munge_underscores=true
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-4]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version]
0.12.0
0.14.0
+1
View File
@@ -0,0 +1 @@
{}
@@ -0,0 +1,35 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.facebook.react.sample"
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.0'
// Depend on pre-built React Native
compile 'com.facebook.react:react-native:0.11.+'
// Depend on React Native source.
// This is useful for testing your changes when working on React Native.
// compile project(':ReactAndroid')
}
+17
View File
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
@@ -0,0 +1,21 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.react.sample">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
@@ -0,0 +1,88 @@
/**
* 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.
*/
package com.facebook.react.sample;
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 com.facebook.soloader.SoLoader;
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SoLoader.init(this, false);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("Examples/SampleApp/index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(
mReactInstanceManager,
"SampleApp",
null);
setContentView(mReactRootView);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onResume(this);
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">SampleApp</string>
</resources>
@@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
@@ -106,27 +106,27 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = iOS/main.jsbundle; sourceTree = "<group>"; };
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../../../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
00E356EE1AD99517003FC87E /* SampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* SampleAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAppTests.m; sourceTree = "<group>"; };
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = iOS/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = iOS/AppDelegate.m; sourceTree = "<group>"; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = iOS/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = iOS/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = iOS/main.m; sourceTree = "<group>"; };
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../../React/React.xcodeproj; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -233,15 +233,15 @@
13B07FAE1A68108700A75B9A /* SampleApp */ = {
isa = PBXGroup;
children = (
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FB71A68108700A75B9A /* main.m */,
);
name = SampleApp;
path = SampleApp;
sourceTree = "<group>";
};
146834001AC3E56700842450 /* Products */ = {
@@ -289,8 +289,8 @@
isa = PBXGroup;
children = (
13B07FAE1A68108700A75B9A /* SampleApp */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* SampleAppTests */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
83CBBA001A601CBA00E9B192 /* Products */,
);
indentWidth = 2;
@@ -548,7 +548,6 @@
13B07FB21A68108700A75B9A /* Base */,
);
name = LaunchScreen.xib;
path = iOS;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
@@ -566,6 +565,11 @@
"DEBUG=1",
"$(inherited)",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../../React/**",
);
INFOPLIST_FILE = SampleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -583,6 +587,11 @@
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../../React/**",
);
INFOPLIST_FILE = SampleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -598,9 +607,9 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
"$(SRCROOT)/../../../React/**",
);
INFOPLIST_FILE = "iOS/Info.plist";
INFOPLIST_FILE = "$(SRCROOT)/SampleApp/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = SampleApp;
@@ -614,9 +623,9 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
"$(SRCROOT)/../../../React/**",
);
INFOPLIST_FILE = "iOS/Info.plist";
INFOPLIST_FILE = "$(SRCROOT)/SampleApp/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = SampleApp;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0620"
LastUpgradeVersion = "0630"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -0,0 +1,61 @@
/**
* Copyright (c) 2015-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.
*/
#import "AppDelegate.h"
#import "RCTRootView.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
/**
* Loading JavaScript code - uncomment the one you want.
*
* OPTION 1
* Load from development server. Start the server from the repository root:
*
* $ npm start
*
* To run on device, change `localhost` to the IP address of your computer
* (you can get this by typing `ifconfig` into the terminal and selecting the
* `inet` value under `en0:`) and make sure your computer and iOS device are
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/SampleApp/index.ios.bundle"];
/**
* OPTION 2
* Load from pre-bundled file on disk. To re-generate the static bundle
* from the root of your project directory, run
*
* $ react-native bundle --minify
*
* see http://facebook.github.io/react-native/docs/runningondevice.html
*/
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"SampleApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1510" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
@@ -10,8 +10,7 @@
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "RCTAssert.h"
#import "RCTRedBox.h"
#import "RCTLog.h"
#import "RCTRootView.h"
#define TIMEOUT_SECONDS 240
@@ -23,7 +22,6 @@
@implementation SampleAppTests
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
{
if (test(view)) {
@@ -37,18 +35,23 @@
return NO;
}
- (void)testRendersWelcomeScreen {
- (void)testRendersWelcomeScreen
{
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
NSString *redboxError = nil;
__block NSString *redboxError = nil;
RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (level >= RCTLogLevelError) {
redboxError = message;
}
});
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
redboxError = [[RCTRedBox sharedInstance] currentErrorMessage];
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
return YES;
@@ -57,6 +60,8 @@
}];
}
RCTSetLogFunction(RCTDefaultLogFunction);
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
}
+52
View File
@@ -0,0 +1,52 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
} = React;
var SampleApp = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.android.js
</Text>
<Text style={styles.instructions}>
Shake or press menu button for dev menu
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);
@@ -14,6 +14,8 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 144C5F681AC3E5D800B004E7 /* libReact.a */; };
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5724D1AA6224400CDF9C8 /* libRCTText.a */; };
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */; };
832044981B492C2500E297FC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832044951B492C1E00E297FC /* libRCTSettings.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -38,6 +40,20 @@
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
remoteInfo = RCTText;
};
5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
remoteInfo = RCTWebSocket;
};
832044941B492C1E00E297FC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTSettings;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
@@ -51,6 +67,8 @@
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = TicTacToe/main.m; sourceTree = "<group>"; };
144C5F631AC3E5D800B004E7 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -58,9 +76,11 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */,
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */,
1341803E1AA91802003F314A /* libRCTImage.a in Frameworks */,
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */,
832044981B492C2500E297FC /* libRCTSettings.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -99,8 +119,10 @@
58C572071AA6126D00CDF9C8 /* Libraries */ = {
isa = PBXGroup;
children = (
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */,
144C5F631AC3E5D800B004E7 /* React.xcodeproj */,
134180381AA917ED003F314A /* RCTImage.xcodeproj */,
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */,
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */,
);
name = Libraries;
@@ -114,6 +136,22 @@
name = Products;
sourceTree = "<group>";
};
5FF894291B8556F8007731BE /* Products */ = {
isa = PBXGroup;
children = (
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */,
);
name = Products;
sourceTree = "<group>";
};
832044901B492C1E00E297FC /* Products */ = {
isa = PBXGroup;
children = (
832044951B492C1E00E297FC /* libRCTSettings.a */,
);
name = Products;
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
@@ -178,10 +216,18 @@
ProductGroup = 134180391AA917ED003F314A /* Products */;
ProjectRef = 134180381AA917ED003F314A /* RCTImage.xcodeproj */;
},
{
ProductGroup = 832044901B492C1E00E297FC /* Products */;
ProjectRef = 8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */;
},
{
ProductGroup = 58C572481AA6224300CDF9C8 /* Products */;
ProjectRef = 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */;
},
{
ProductGroup = 5FF894291B8556F8007731BE /* Products */;
ProjectRef = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
},
{
ProductGroup = 144C5F641AC3E5D800B004E7 /* Products */;
ProjectRef = 144C5F631AC3E5D800B004E7 /* React.xcodeproj */;
@@ -216,6 +262,20 @@
remoteRef = 58C5724C1AA6224400CDF9C8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTWebSocket.a;
remoteRef = 5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832044951B492C1E00E297FC /* libRCTSettings.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTSettings.a;
remoteRef = 832044941B492C1E00E297FC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
@@ -52,6 +52,7 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"TicTacToeApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+3 -35
View File
@@ -19,7 +19,6 @@
var React = require('react-native');
var {
AppRegistry,
Image,
StyleSheet,
Text,
TouchableHighlight,
@@ -118,17 +117,6 @@ var Cell = React.createClass({
}
},
imageStyle() {
switch (this.props.player) {
case 1:
return styles.imageX;
case 2:
return styles.imageO;
default:
return {};
}
},
textContents() {
switch (this.props.player) {
case 1:
@@ -140,17 +128,6 @@ var Cell = React.createClass({
}
},
imageContents() {
switch (this.props.player) {
case 1:
return 'http://www.picgifs.com/alphabets/alphabets/children-5/alphabets-children-5-277623.gif';
case 2:
return 'http://www.picgifs.com/alphabets/alphabets/children-5/alphabets-children-5-730492.gif';
default:
return '';
}
},
render() {
return (
<TouchableHighlight
@@ -158,7 +135,9 @@ var Cell = React.createClass({
underlayColor="transparent"
activeOpacity={0.5}>
<View style={[styles.cell, this.cellStyle()]}>
<Image source={{uri: this.imageContents()}} style={this.imageStyle()}/>
<Text style={[styles.cellText, this.textStyle()]}>
{this.textContents()}
</Text>
</View>
</TouchableHighlight>
);
@@ -304,17 +283,6 @@ var styles = StyleSheet.create({
color: '#b9dc2f',
},
// CELL IMAGE
imageX: {
width: 34,
height: 42,
},
imageO: {
width: 45,
height: 41,
},
// GAME OVER
overlay: {
@@ -0,0 +1,213 @@
/**
* 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 {
StyleSheet,
Text,
View,
ToastAndroid,
TouchableWithoutFeedback,
} = React;
var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');
var importantForAccessibilityValues = ['auto', 'yes', 'no', 'no-hide-descendants'];
var AccessibilityAndroidExample = React.createClass({
statics: {
title: 'Accessibility',
description: 'Examples of using Accessibility API.',
},
getInitialState: function() {
return {
count: 0,
backgroundImportantForAcc: 0,
forgroundImportantForAcc: 0,
};
},
_addOne: function() {
this.setState({
count: ++this.state.count,
});
},
_changeBackgroundImportantForAcc: function() {
this.setState({
backgroundImportantForAcc: (this.state.backgroundImportantForAcc + 1) % 4,
});
},
_changeForgroundImportantForAcc: function() {
this.setState({
forgroundImportantForAcc: (this.state.forgroundImportantForAcc + 1) % 4,
});
},
render: function() {
return (
<UIExplorerPage title={'Accessibility'}>
<UIExplorerBlock title="Nonaccessible view with TextViews">
<View>
<Text style={{color: 'green',}}>
This is
</Text>
<Text style={{color: 'blue'}}>
nontouchable normal view.
</Text>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Accessible view with TextViews wihout label">
<View accessible={true}>
<Text style={{color: 'green',}}>
This is
</Text>
<Text style={{color: 'blue'}}>
nontouchable accessible view without label.
</Text>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Accessible view with TextViews with label">
<View accessible={true}
accessibilityLabel="I have label, so I read it instead of embedded text.">
<Text style={{color: 'green',}}>
This is
</Text>
<Text style={{color: 'blue'}}>
nontouchable accessible view with label.
</Text>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Touchable with component type = button">
<TouchableWithoutFeedback
onPress={() => ToastAndroid.show('Toasts work by default', ToastAndroid.SHORT)}
accessibilityComponentType="button">
<View style={styles.embedded}>
<Text>Click me</Text>
<Text>Or not</Text>
</View>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="LiveRegion">
<TouchableWithoutFeedback onPress={this._addOne}>
<View style={styles.embedded}>
<Text>Click me</Text>
</View>
</TouchableWithoutFeedback>
<Text accessibilityLiveRegion="polite">
Clicked {this.state.count} times
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Overlapping views and importantForAccessibility property">
<View style={styles.container}>
<View
style={{
position: 'absolute',
left: 10,
top: 10,
right: 10,
height: 100,
backgroundColor: 'green'}}
accessible={true}
accessibilityLabel="First layout"
importantForAccessibility={
importantForAccessibilityValues[this.state.backgroundImportantForAcc]}>
<View accessible={true}>
<Text style={{fontSize: 25}}>
Hello
</Text>
</View>
</View>
<View
style={{
position: 'absolute',
left: 10,
top: 25,
right: 10,
height: 110,
backgroundColor: 'yellow', opacity: 0.5}}
accessible={true}
accessibilityLabel="Second layout"
importantForAccessibility={
importantForAccessibilityValues[this.state.forgroundImportantForAcc]}>
<View accessible={true}>
<Text style={{fontSize: 20}}>
world
</Text>
</View>
</View>
</View>
<TouchableWithoutFeedback onPress={this._changeBackgroundImportantForAcc}>
<View style={styles.embedded}>
<Text>
Change importantForAccessibility for background layout.
</Text>
</View>
</TouchableWithoutFeedback>
<View accessible={true}>
<Text>
Background layout importantForAccessibility
</Text>
<Text>
{importantForAccessibilityValues[this.state.backgroundImportantForAcc]}
</Text>
</View>
<TouchableWithoutFeedback onPress={this._changeForgroundImportantForAcc}>
<View style={styles.embedded}>
<Text>
Change importantForAccessibility for forground layout.
</Text>
</View>
</TouchableWithoutFeedback>
<View accessible={true}>
<Text>
Forground layout importantForAccessibility
</Text>
<Text>
{importantForAccessibilityValues[this.state.forgroundImportantForAcc]}
</Text>
</View>
</UIExplorerBlock>
</UIExplorerPage>
);
},
});
var styles = StyleSheet.create({
embedded: {
backgroundColor: 'yellow',
padding:10,
},
container: {
flex: 1,
backgroundColor: 'white',
padding: 10,
height:150,
},
});
module.exports = AccessibilityAndroidExample;
@@ -0,0 +1,256 @@
/**
* 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 {
StyleSheet,
Text,
View,
TouchableWithoutFeedback,
} = React;
var ToastAndroid = require('ToastAndroid');
var AccessibilityInfo = require('AccessibilityInfo');
var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');
var importantForAccessibilityValues = ['auto', 'yes', 'no', 'no-hide-descendants'];
var AccessibilityAndroidExample = React.createClass({
statics: {
title: 'Accessibility',
description: 'Examples of using Accessibility API.',
},
getInitialState: function() {
return {
count: 0,
talkbackEnabled: false,
backgroundImportantForAcc: 0,
forgroundImportantForAcc: 0,
};
},
componentDidMount: function() {
AccessibilityInfo.addEventListener(
'change',
this._handleTouchExplorationChange
);
AccessibilityInfo.fetch().done((enabled) => {
this.setState({
count: this.state.count,
talkbackEnabled: enabled}); }
);
},
componentWillUnmount: function() {
AccessibilityInfo.removeEventListener(
'change',
this._handleTouchExplorationChange
);
},
_handleTouchExplorationChange: function(isEnabled) {
this.setState({
count: this.state.count,
talkbackEnabled: isEnabled,
});
},
_showAccessibilityToast: function() {
var text = 'TouchExploration is ' + (this.state.talkbackEnabled ? 'enabled' : 'disabled');
ToastAndroid.show(text, ToastAndroid.SHORT);
},
_addOne: function() {
this.setState({
count: ++this.state.count,
talkbackEnabled: this.state.talkbackEnabled,
});
},
_changeBackgroundImportantForAcc: function() {
this.setState({
backgroundImportantForAcc: (this.state.backgroundImportantForAcc + 1) % 4,
});
},
_changeForgroundImportantForAcc: function() {
this.setState({
forgroundImportantForAcc: (this.state.forgroundImportantForAcc + 1) % 4,
});
},
render: function() {
return (
<UIExplorerPage title={'Accessibility'}>
<UIExplorerBlock title="Nonaccessible view with TextViews">
<View>
<Text style={{color: 'green',}}>
This is
</Text>
<Text style={{color: 'blue'}}>
nontouchable normal view.
</Text>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Accessible view with TextViews wihout label">
<View accessible={true}>
<Text style={{color: 'green',}}>
This is
</Text>
<Text style={{color: 'blue'}}>
nontouchable accessible view without label.
</Text>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Accessible view with TextViews with label">
<View accessible={true}
accessibilityLabel="I have label, so I read it instead of embedded text.">
<Text style={{color: 'green',}}>
This is
</Text>
<Text style={{color: 'blue'}}>
nontouchable accessible view with label.
</Text>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Touchable with component type = button">
<TouchableWithoutFeedback
onPress={() => ToastAndroid.show('Toasts work by default', ToastAndroid.SHORT)}>
<View style={styles.embedded} accessibilityComponentType="button">
<Text>Click me</Text>
<Text>Or not</Text>
</View>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="LiveRegion">
<TouchableWithoutFeedback onPress={this._addOne}>
<View style={styles.embedded} accessibilityComponentType="button">
<Text>Click me</Text>
</View>
</TouchableWithoutFeedback>
<Text accessibilityLiveRegion="polite">
Clicked {this.state.count} times
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Check if TouchExploration is enabled">
<TouchableWithoutFeedback onPress={this._showAccessibilityToast}>
<View style={styles.embedded}>
<Text>
Click to check TouchExploration
</Text>
</View>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Overlapping views and importantForAccessibility property">
<View style={styles.container}>
<View
style={{
position: 'absolute',
left: 10,
top: 10,
right: 10,
height: 100,
backgroundColor: 'green'}}
accessible={true}
accessibilityLabel="First layout"
importantForAccessibility={
importantForAccessibilityValues[this.state.backgroundImportantForAcc]}>
<View accessible={true}>
<Text style={{fontSize: 25}}>
Hello
</Text>
</View>
</View>
<View
style={{
position: 'absolute',
left: 10,
top: 25,
right: 10,
height: 110,
backgroundColor: 'yellow', opacity: 0.5}}
accessible={true}
accessibilityLabel="Second layout"
importantForAccessibility={
importantForAccessibilityValues[this.state.forgroundImportantForAcc]}>
<View accessible={true}>
<Text style={{fontSize: 20}}>
world
</Text>
</View>
</View>
</View>
<TouchableWithoutFeedback onPress={this._changeBackgroundImportantForAcc}>
<View style={styles.embedded}>
<Text>
Change importantForAccessibility for background layout.
</Text>
</View>
</TouchableWithoutFeedback>
<View accessible={true}>
<Text>
Background layout importantForAccessibility
</Text>
<Text>
{importantForAccessibilityValues[this.state.backgroundImportantForAcc]}
</Text>
</View>
<TouchableWithoutFeedback onPress={this._changeForgroundImportantForAcc}>
<View style={styles.embedded}>
<Text>
Change importantForAccessibility for forground layout.
</Text>
</View>
</TouchableWithoutFeedback>
<View accessible={true}>
<Text>
Forground layout importantForAccessibility
</Text>
<Text>
{importantForAccessibilityValues[this.state.forgroundImportantForAcc]}
</Text>
</View>
</UIExplorerBlock>
</UIExplorerPage>
);
},
});
var styles = StyleSheet.create({
embedded: {
backgroundColor: 'yellow',
padding:10,
},
container: {
flex: 1,
backgroundColor: 'white',
padding: 10,
height:150,
},
});
module.exports = AccessibilityAndroidExample;
+2 -1
View File
@@ -17,11 +17,12 @@
var React = require('react-native');
var {
ActionSheetIOS,
StyleSheet,
Text,
View,
} = React;
var ActionSheetIOS = require('ActionSheetIOS');
var BUTTONS = [
'Button Index: 0',
'Button Index: 1',
+1 -2
View File
@@ -15,10 +15,9 @@
*/
'use strict';
var AdSupportIOS = require('AdSupportIOS');
var React = require('react-native');
var {
AdSupportIOS,
StyleSheet,
Text,
View,
@@ -0,0 +1,321 @@
/**
* 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 AnExApp
* @flow
*/
'use strict';
var React = require('react-native');
var {
Animated,
LayoutAnimation,
PanResponder,
StyleSheet,
View,
} = React;
var AnExSet = require('AnExSet');
var CIRCLE_SIZE = 80;
var CIRCLE_MARGIN = 18;
var NUM_CIRCLES = 30;
class Circle extends React.Component {
_onLongPress: () => void;
_toggleIsActive: () => void;
constructor(props: Object): void {
super();
this._onLongPress = this._onLongPress.bind(this);
this._toggleIsActive = this._toggleIsActive.bind(this);
this.state = {
isActive: false,
pan: new Animated.ValueXY(), // Vectors reduce boilerplate. (step1: uncomment)
pop: new Animated.Value(0), // Initial value. (step2a: uncomment)
};
}
_onLongPress(): void {
var config = {tension: 40, friction: 3};
this.state.pan.addListener((value) => { // Async listener for state changes (step1: uncomment)
this.props.onMove && this.props.onMove(value);
});
Animated.spring(this.state.pop, {
toValue: 1, // Pop to larger size. (step2b: uncomment)
...config, // Reuse config for convenient consistency (step2b: uncomment)
}).start();
this.setState({panResponder: PanResponder.create({
onPanResponderMove: Animated.event([
null, // native event - ignore (step1: uncomment)
{dx: this.state.pan.x, dy: this.state.pan.y}, // links pan to gestureState (step1: uncomment)
]),
onPanResponderRelease: (e, gestureState) => {
LayoutAnimation.easeInEaseOut(); // @flowfixme animates layout update as one batch (step3: uncomment)
Animated.spring(this.state.pop, {
toValue: 0, // Pop back to 0 (step2c: uncomment)
...config,
}).start();
this.setState({panResponder: undefined});
this.props.onMove && this.props.onMove({
x: gestureState.dx + this.props.restLayout.x,
y: gestureState.dy + this.props.restLayout.y,
});
this.props.onDeactivate();
},
})}, () => {
this.props.onActivate();
});
}
render(): ReactElement {
if (this.state.panResponder) {
var handlers = this.state.panResponder.panHandlers;
var dragStyle = { // Used to position while dragging
position: 'absolute', // Hoist out of layout (step1: uncomment)
...this.state.pan.getLayout(), // Convenience converter (step1: uncomment)
};
} else {
handlers = {
onStartShouldSetResponder: () => !this.state.isActive,
onResponderGrant: () => {
this.state.pan.setValue({x: 0, y: 0}); // reset (step1: uncomment)
this.state.pan.setOffset(this.props.restLayout); // offset from onLayout (step1: uncomment)
this.longTimer = setTimeout(this._onLongPress, 300);
},
onResponderRelease: () => {
if (!this.state.panResponder) {
clearTimeout(this.longTimer);
this._toggleIsActive();
}
}
};
}
var animatedStyle: Object = {
shadowOpacity: this.state.pop, // no need for interpolation (step2d: uncomment)
transform: [
{scale: this.state.pop.interpolate({
inputRange: [0, 1],
outputRange: [1, 1.3] // scale up from 1 to 1.3 (step2d: uncomment)
})},
],
};
var openVal = this.props.openVal;
if (this.props.dummy) {
animatedStyle.opacity = 0;
} else if (this.state.isActive) {
var innerOpenStyle = [styles.open, { // (step4: uncomment)
left: openVal.interpolate({inputRange: [0, 1], outputRange: [this.props.restLayout.x, 0]}),
top: openVal.interpolate({inputRange: [0, 1], outputRange: [this.props.restLayout.y, 0]}),
width: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_SIZE, this.props.containerLayout.width]}),
height: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_SIZE, this.props.containerLayout.height]}),
margin: openVal.interpolate({inputRange: [0, 1], outputRange: [CIRCLE_MARGIN, 0]}),
borderRadius: openVal.interpolate({inputRange: [-0.15, 0, 0.5, 1], outputRange: [0, CIRCLE_SIZE / 2, CIRCLE_SIZE * 1.3, 0]}),
}];
}
return (
<Animated.View
onLayout={this.props.onLayout}
style={[styles.dragView, dragStyle, animatedStyle, this.state.isActive ? styles.open : null]}
{...handlers}>
<Animated.View style={[styles.circle, innerOpenStyle]}>
<AnExSet
containerLayout={this.props.containerLayout}
id={this.props.id}
isActive={this.state.isActive}
openVal={this.props.openVal}
onDismiss={this._toggleIsActive}
/>
</Animated.View>
</Animated.View>
);
}
_toggleIsActive(velocity) {
var config = {tension: 30, friction: 7};
if (this.state.isActive) {
Animated.spring(this.props.openVal, {toValue: 0, ...config}).start(() => { // (step4: uncomment)
this.setState({isActive: false}, this.props.onDeactivate);
}); // (step4: uncomment)
} else {
this.props.onActivate();
this.setState({isActive: true, panResponder: undefined}, () => {
// this.props.openVal.setValue(1); // (step4: comment)
Animated.spring(this.props.openVal, {toValue: 1, ...config}).start(); // (step4: uncomment)
});
}
}
}
class AnExApp extends React.Component {
_onMove: (position: Point) => void;
constructor(props: any): void {
super(props);
var keys = [];
for (var idx = 0; idx < NUM_CIRCLES; idx++) {
keys.push('E' + idx);
}
this.state = {
keys,
restLayouts: [],
openVal: new Animated.Value(0),
};
this._onMove = this._onMove.bind(this);
}
render(): ReactElement {
var circles = this.state.keys.map((key, idx) => {
if (key === this.state.activeKey) {
return <Circle key={key + 'd'} dummy={true} />;
} else {
if (!this.state.restLayouts[idx]) {
var onLayout = function(index, e) {
var layout = e.nativeEvent.layout;
this.setState((state) => {
state.restLayouts[index] = layout;
return state;
});
}.bind(this, idx);
}
return (
<Circle
key={key}
id={key}
openVal={this.state.openVal}
onLayout={onLayout}
restLayout={this.state.restLayouts[idx]}
onActivate={this.setState.bind(this, {
activeKey: key,
activeInitialLayout: this.state.restLayouts[idx],
})}
/>
);
}
});
if (this.state.activeKey) {
circles.push(
<Animated.View key="dark" style={[styles.darkening, {opacity: this.state.openVal}]} />
);
circles.push(
<Circle
openVal={this.state.openVal}
key={this.state.activeKey}
id={this.state.activeKey}
restLayout={this.state.activeInitialLayout}
containerLayout={this.state.layout}
onMove={this._onMove}
onDeactivate={() => { this.setState({activeKey: undefined}); }}
/>
);
}
return (
<View style={styles.container}>
<View style={styles.grid} onLayout={(e) => this.setState({layout: e.nativeEvent.layout})}>
{circles}
</View>
</View>
);
}
_onMove(position: Point): void {
var newKeys = moveToClosest(this.state, position);
if (newKeys !== this.state.keys) {
LayoutAnimation.easeInEaseOut(); // animates layout update as one batch (step3: uncomment)
this.setState({keys: newKeys});
}
}
}
type Point = {x: number, y: number};
function distance(p1: Point, p2: Point): number {
var dx = p1.x - p2.x;
var dy = p1.y - p2.y;
return dx * dx + dy * dy;
}
function moveToClosest({activeKey, keys, restLayouts}, position) {
var activeIdx = -1;
var closestIdx = activeIdx;
var minDist = Infinity;
var newKeys = [];
keys.forEach((key, idx) => {
var dist = distance(position, restLayouts[idx]);
if (key === activeKey) {
idx = activeIdx;
} else {
newKeys.push(key);
}
if (dist < minDist) {
minDist = dist;
closestIdx = idx;
}
});
if (closestIdx === activeIdx) {
return keys; // nothing changed
} else {
newKeys.splice(closestIdx, 0, activeKey);
return newKeys;
}
}
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,
paddingTop: 64, // push content below nav bar
},
grid: {
flex: 1,
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
backgroundColor: 'transparent',
},
circle: {
width: CIRCLE_SIZE,
height: CIRCLE_SIZE,
borderRadius: CIRCLE_SIZE / 2,
borderWidth: 1,
borderColor: 'black',
margin: CIRCLE_MARGIN,
overflow: 'hidden',
},
dragView: {
shadowRadius: 10,
shadowColor: 'rgba(0,0,0,0.7)',
shadowOffset: {height: 8},
alignSelf: 'flex-start',
backgroundColor: 'transparent',
},
open: {
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
width: undefined, // unset value from styles.circle
height: undefined, // unset value from styles.circle
borderRadius: 0, // unset value from styles.circle
},
darkening: {
backgroundColor: 'black',
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
},
});
module.exports = AnExApp;
@@ -0,0 +1,162 @@
/**
* 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 AnExBobble
* @flow
*/
'use strict';
var React = require('react-native');
var {
Animated,
Image,
PanResponder,
StyleSheet,
View,
} = React;
var NUM_BOBBLES = 5;
var RAD_EACH = Math.PI / 2 / (NUM_BOBBLES - 2);
var RADIUS = 160;
var BOBBLE_SPOTS = [...Array(NUM_BOBBLES)].map((_, i) => { // static positions
return i === 0 ? {x: 0, y: 0} : { // first bobble is the selector
x: -Math.cos(RAD_EACH * (i - 1)) * RADIUS,
y: -Math.sin(RAD_EACH * (i - 1)) * RADIUS,
};
});
class AnExBobble extends React.Component {
constructor(props: Object) {
super(props);
this.state = {};
this.state.bobbles = BOBBLE_SPOTS.map((_, i) => {
return new Animated.ValueXY();
});
this.state.selectedBobble = null;
var bobblePanListener = (e, gestureState) => { // async events => change selection
var newSelected = computeNewSelected(gestureState);
if (this.state.selectedBobble !== newSelected) {
if (this.state.selectedBobble !== null) {
var restSpot = BOBBLE_SPOTS[this.state.selectedBobble];
Animated.spring(this.state.bobbles[this.state.selectedBobble], {
toValue: restSpot, // return previously selected bobble to rest position
}).start();
}
if (newSelected !== null && newSelected !== 0) {
Animated.spring(this.state.bobbles[newSelected], {
toValue: this.state.bobbles[0], // newly selected should track the selector
}).start();
}
this.state.selectedBobble = newSelected;
}
};
var releaseBobble = () => {
this.state.bobbles.forEach((bobble, i) => {
Animated.spring(bobble, {
toValue: {x: 0, y: 0} // all bobbles return to zero
}).start();
});
};
this.state.bobbleResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
BOBBLE_SPOTS.forEach((spot, idx) => {
Animated.spring(this.state.bobbles[idx], {
toValue: spot, // spring each bobble to its spot
friction: 3, // less friction => bouncier
}).start();
});
},
onPanResponderMove: Animated.event(
[ null, {dx: this.state.bobbles[0].x, dy: this.state.bobbles[0].y} ],
{listener: bobblePanListener} // async state changes with arbitrary logic
),
onPanResponderRelease: releaseBobble,
onPanResponderTerminate: releaseBobble,
});
}
render(): ReactElement {
return (
<View style={styles.bobbleContainer}>
{this.state.bobbles.map((_, i) => {
var j = this.state.bobbles.length - i - 1; // reverse so lead on top
var handlers = j > 0 ? {} : this.state.bobbleResponder.panHandlers;
return (
<Animated.Image
{...handlers}
source={{uri: BOBBLE_IMGS[j]}}
style={[styles.circle, {
backgroundColor: randColor(), // re-renders are obvious
transform: this.state.bobbles[j].getTranslateTransform(), // simple conversion
}]}
/>
);
})}
</View>
);
}
}
var styles = StyleSheet.create({
circle: {
position: 'absolute',
height: 60,
width: 60,
borderRadius: 30,
borderWidth: 0.5,
},
bobbleContainer: {
top: -68,
paddingRight: 66,
flexDirection: 'row',
flex: 1,
justifyContent: 'flex-end',
backgroundColor: 'transparent',
},
});
function computeNewSelected(
gestureState: Object,
): ?number {
var {dx, dy} = gestureState;
var minDist = Infinity;
var newSelected = null;
var pointRadius = Math.sqrt(dx * dx + dy * dy);
if (Math.abs(RADIUS - pointRadius) < 80) {
BOBBLE_SPOTS.forEach((spot, idx) => {
var delta = {x: spot.x - dx, y: spot.y - dy};
var dist = delta.x * delta.x + delta.y * delta.y;
if (dist < minDist) {
minDist = dist;
newSelected = idx;
}
});
}
return newSelected;
}
function randColor(): string {
var colors = [0,1,2].map(() => Math.floor(Math.random() * 150 + 100));
return 'rgb(' + colors.join(',') + ')';
}
var BOBBLE_IMGS = [
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xpf1/t39.1997-6/10173489_272703316237267_1025826781_n.png',
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/l/t39.1997-6/p240x240/851578_631487400212668_2087073502_n.png',
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/p240x240/851583_654446917903722_178118452_n.png',
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/p240x240/851565_641023175913294_875343096_n.png',
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/851562_575284782557566_1188781517_n.png',
];
module.exports = AnExBobble;
@@ -0,0 +1,114 @@
/**
* 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 AnExChained
* @flow
*/
'use strict';
var React = require('react-native');
var {
Animated,
Image,
PanResponder,
StyleSheet,
View,
} = React;
class AnExChained extends React.Component {
constructor(props: Object) {
super(props);
this.state = {
stickers: [new Animated.ValueXY()], // 1 leader
};
var stickerConfig = {tension: 2, friction: 3}; // soft spring
for (var i = 0; i < 4; i++) { // 4 followers
var sticker = new Animated.ValueXY();
Animated.spring(sticker, {
...stickerConfig,
toValue: this.state.stickers[i], // Animated toValue's are tracked
}).start();
this.state.stickers.push(sticker); // push on the followers
}
var releaseChain = (e, gestureState) => {
this.state.stickers[0].flattenOffset(); // merges offset into value and resets
Animated.sequence([ // spring to start after decay finishes
Animated.decay(this.state.stickers[0], { // coast to a stop
velocity: {x: gestureState.vx, y: gestureState.vy},
deceleration: 0.997,
}),
Animated.spring(this.state.stickers[0], {
toValue: {x: 0, y: 0} // return to start
}),
]).start();
};
this.state.chainResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
this.state.stickers[0].stopAnimation((value) => {
this.state.stickers[0].setOffset(value); // start where sticker animated to
this.state.stickers[0].setValue({x: 0, y: 0}); // avoid flicker before next event
});
},
onPanResponderMove: Animated.event(
[null, {dx: this.state.stickers[0].x, dy: this.state.stickers[0].y}] // map gesture to leader
),
onPanResponderRelease: releaseChain,
onPanResponderTerminate: releaseChain,
});
}
render() {
return (
<View style={styles.chained}>
{this.state.stickers.map((_, i) => {
var j = this.state.stickers.length - i - 1; // reverse so leader is on top
var handlers = (j === 0) ? this.state.chainResponder.panHandlers : {};
return (
<Animated.Image
{...handlers}
source={{uri: CHAIN_IMGS[j]}}
style={[styles.sticker, {
transform: this.state.stickers[j].getTranslateTransform(), // simple conversion
}]}
/>
);
})}
</View>
);
}
}
var styles = StyleSheet.create({
chained: {
alignSelf: 'flex-end',
top: -160,
right: 126
},
sticker: {
position: 'absolute',
height: 120,
width: 120,
backgroundColor: 'transparent',
},
});
var CHAIN_IMGS = [
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xpf1/t39.1997-6/p160x160/10574705_1529175770666007_724328156_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xfa1/t39.1997-6/p160x160/851575_392309884199657_1917957497_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xfa1/t39.1997-6/p160x160/851567_555288911225630_1628791128_n.png',
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xfa1/t39.1997-6/p160x160/851583_531111513625557_903469595_n.png',
'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xpa1/t39.1997-6/p160x160/851577_510515972354399_2147096990_n.png',
];
module.exports = AnExChained;
@@ -0,0 +1,115 @@
/**
* 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 AnExScroll
*/
'use strict';
var React = require('react-native');
var {
Animated,
Image,
ScrollView,
StyleSheet,
Text,
View,
} = React;
class AnExScroll extends React.Component {
constructor(props) {
super(props);
this.state = {
scrollX: new Animated.Value(0),
};
}
render() {
var width = this.props.panelWidth;
return (
<View style={styles.container}>
<ScrollView
automaticallyAdjustContentInsets={false}
scrollEventThrottle={16 /* get all events */ }
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: this.state.scrollX}}}] // nested event mapping
)}
contentContainerStyle={{flex: 1, padding: 10}}
pagingEnabled={true}
horizontal={true}>
<View style={[styles.page, {width}]}>
<Image
style={{width: 180, height: 180}}
source={HAWK_PIC}
/>
<Text style={styles.text}>
{'I\'ll find something to put here.'}
</Text>
</View>
<View style={[styles.page, {width}]}>
<Text style={styles.text}>{'And here.'}</Text>
</View>
<View style={[styles.page, {width}]}>
<Text>{'But not here.'}</Text>
</View>
</ScrollView>
<Animated.Image
pointerEvents="none"
style={[styles.bunny, {transform: [
{translateX: this.state.scrollX.interpolate({
inputRange: [0, width, 2 * width],
outputRange: [0, 0, width / 3]}), // multi-part ranges
extrapolate: 'clamp'}, // default is 'extend'
{translateY: this.state.scrollX.interpolate({
inputRange: [0, width, 2 * width],
outputRange: [0, -200, -260]}),
extrapolate: 'clamp'},
{scale: this.state.scrollX.interpolate({
inputRange: [0, width, 2 * width],
outputRange: [0.5, 0.5, 2]}),
extrapolate: 'clamp'},
]}]}
source={BUNNY_PIC}
/>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
backgroundColor: 'transparent',
flex: 1,
},
text: {
padding: 4,
paddingBottom: 10,
fontWeight: 'bold',
fontSize: 18,
backgroundColor: 'transparent',
},
bunny: {
backgroundColor: 'transparent',
position: 'absolute',
height: 160,
width: 160,
},
page: {
alignItems: 'center',
justifyContent: 'flex-end',
},
});
var HAWK_PIC = {uri: 'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xfa1/t39.1997-6/10734304_1562225620659674_837511701_n.png'};
var BUNNY_PIC = {uri: 'https://scontent-sea1-1.xx.fbcdn.net/hphotos-xaf1/t39.1997-6/851564_531111380292237_1898871086_n.png'};
module.exports = AnExScroll;
@@ -0,0 +1,150 @@
/**
* 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 AnExSet
* @flow
*/
'use strict';
var React = require('react-native');
var {
Animated,
PanResponder,
StyleSheet,
Text,
View,
} = React;
var AnExBobble = require('./AnExBobble');
var AnExChained = require('./AnExChained');
var AnExScroll = require('./AnExScroll');
var AnExTilt = require('./AnExTilt');
class AnExSet extends React.Component {
constructor(props: Object) {
super(props);
function randColor() {
var colors = [0,1,2].map(() => Math.floor(Math.random() * 150 + 100));
return 'rgb(' + colors.join(',') + ')';
}
this.state = {
closeColor: randColor(),
openColor: randColor(),
};
}
render(): ReactElement {
var backgroundColor = this.props.openVal ?
this.props.openVal.interpolate({
inputRange: [0, 1],
outputRange: [
this.state.closeColor, // interpolates color strings
this.state.openColor
],
}) :
this.state.closeColor;
var panelWidth = this.props.containerLayout && this.props.containerLayout.width || 320;
return (
<View style={styles.container}>
<Animated.View
style={[styles.header, { backgroundColor }]}
{...this.state.dismissResponder.panHandlers}>
<Text style={[styles.text, styles.headerText]}>
{this.props.id}
</Text>
</Animated.View>
{this.props.isActive &&
<View style={styles.stream}>
<View style={styles.card}>
<Text style={styles.text}>
July 2nd
</Text>
<AnExTilt isActive={this.props.isActive} />
<AnExBobble />
</View>
<AnExScroll panelWidth={panelWidth}/>
<AnExChained />
</View>
}
</View>
);
}
componentWillMount() {
this.state.dismissY = new Animated.Value(0);
this.state.dismissResponder = PanResponder.create({
onStartShouldSetPanResponder: () => this.props.isActive,
onPanResponderGrant: () => {
Animated.spring(this.props.openVal, { // Animated value passed in.
toValue: this.state.dismissY.interpolate({ // Track dismiss gesture
inputRange: [0, 300], // and interpolate pixel distance
outputRange: [1, 0], // to a fraction.
})
}).start();
},
onPanResponderMove: Animated.event(
[null, {dy: this.state.dismissY}] // track pan gesture
),
onPanResponderRelease: (e, gestureState) => {
if (gestureState.dy > 100) {
this.props.onDismiss(gestureState.vy); // delegates dismiss action to parent
} else {
Animated.spring(this.props.openVal, {
toValue: 1, // animate back open if released early
}).start();
}
},
});
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
alignItems: 'center',
paddingTop: 18,
height: 90,
},
stream: {
flex: 1,
backgroundColor: 'rgb(230, 230, 230)',
},
card: {
margin: 8,
padding: 8,
borderRadius: 6,
backgroundColor: 'white',
shadowRadius: 2,
shadowColor: 'black',
shadowOpacity: 0.2,
shadowOffset: {height: 0.5},
},
text: {
padding: 4,
paddingBottom: 10,
fontWeight: 'bold',
fontSize: 18,
backgroundColor: 'transparent',
},
headerText: {
fontSize: 25,
color: 'white',
shadowRadius: 3,
shadowColor: 'black',
shadowOpacity: 1,
shadowOffset: {height: 1},
},
});
module.exports = AnExSet;
@@ -0,0 +1,107 @@
<br /><br />
# React Native: Animated
ReactEurope 2015, Paris - Spencer Ahrens - Facebook
<br /><br />
## Fluid Interactions
- People expect smooth, delightful experiences
- Complex interactions are hard
- Common patterns can be optimized
<br /><br />
## Declarative Interactions
- Wire up inputs (events) to outputs (props) + transforms (springs, easing, etc.)
- Arbitrary code can define/update this config
- Config can be serialized -> native/main thread
- No refs or lifecycle to worry about
<br /><br />
## var { Animated } = require('react-native');
- New library soon to be released for React Native
- 100% JS implementation -> X-Platform
- Per-platform native optimizations planned
- This talk -> usage examples, not implementation
<br /><br />
## Gratuitous Animation Demo App
- Layout uses `flexWrap: 'wrap'`
- longPress -> drag to reorder
- Tap to open example sets
<br /><br />
## Gratuitous Animation Codez
- Step 1: 2D tracking pan gesture
- Step 2: Simple pop-out spring on select
- Step 3: Animate grid reordering with `LayoutAnimation`
- Step 4: Opening animation
<br /><br />
## Animation Example Set
- `Animated.Value` `this.props.open` passed in from parent
- `interpolate` works with string "shapes," e.g. `'rgb(0, 0, 255)'`, `'45deg'`
- Examples easily composed as separate components
- Dismissing tracks interpolated gesture
- Custom release logic
<br /><br />
## Tilting Photo
- Pan -> translateX * 2, rotate, opacity (via tracking)
- Gesture release triggers separate animations
- `addListener` for async, arbitrary logic on animation progress
- `interpolate` easily creates parallax and other effects
<br /><br />
## Bobbles
- Static positions defined
- Listens to events to maybe change selection
- Springs previous selection back
- New selection tracks selector
- `getTranslateTransform` adds convenience
<br /><br />
## Chained
- Classic "Chat Heads" animation
- Each sticker tracks the one before it with a soft spring
- `decay` maintains gesture velocity, followed by `spring` to home
- `stopAnimation` provides the last value for `setOffset`
<br /><br />
## Scrolling
- `Animated.event` can track all sorts of stuff
- Multi-part ranges and extrapolation options
- Transforms decompose into ordered components
<br /><br />
# React Native: Animated
- Landing soon in master (days)
- GitHub: @vjeux, @sahrens
- Questions?
<br />
@@ -0,0 +1,139 @@
/**
* 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 AnExTilt
* @flow
*/
'use strict';
var React = require('react-native');
var {
Animated,
Image,
PanResponder,
StyleSheet,
View,
} = React;
class AnExTilt extends React.Component {
constructor(props: Object) {
super(props);
this.state = {
panX: new Animated.Value(0),
opacity: new Animated.Value(1),
burns: new Animated.Value(1.15),
};
this.state.tiltPanResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
Animated.timing(this.state.opacity, {
toValue: this.state.panX.interpolate({
inputRange: [-300, 0, 300], // pan is in pixels
outputRange: [0, 1, 0], // goes to zero at both edges
}),
duration: 0, // direct tracking
}).start();
},
onPanResponderMove: Animated.event(
[null, {dx: this.state.panX}] // panX is linked to the gesture
),
onPanResponderRelease: (e, gestureState) => {
var toValue = 0;
if (gestureState.dx > 100) {
toValue = 500;
} else if (gestureState.dx < -100) {
toValue = -500;
}
Animated.spring(this.state.panX, {
toValue, // animate back to center or off screen
velocity: gestureState.vx, // maintain gesture velocity
tension: 10,
friction: 3,
}).start();
this.state.panX.removeAllListeners();
var id = this.state.panX.addListener(({value}) => { // listen until offscreen
if (Math.abs(value) > 400) {
this.state.panX.removeListener(id); // offscreen, so stop listening
Animated.timing(this.state.opacity, {
toValue: 1, // Fade back in. This unlinks it from tracking this.state.panX
}).start();
this.state.panX.setValue(0); // Note: stops the spring animation
toValue !== 0 && this._startBurnsZoom();
}
});
},
});
}
_startBurnsZoom() {
this.state.burns.setValue(1); // reset to beginning
Animated.decay(this.state.burns, {
velocity: 1, // sublte zoom
deceleration: 0.9999, // slow decay
}).start();
}
componentWillMount() {
this._startBurnsZoom();
}
render(): ReactElement {
return (
<Animated.View
{...this.state.tiltPanResponder.panHandlers}
style={[styles.tilt, {
opacity: this.state.opacity,
transform: [
{rotate: this.state.panX.interpolate({
inputRange: [-320, 320],
outputRange: ['-15deg', '15deg']})}, // interpolate string "shapes"
{translateX: this.state.panX},
],
}]}>
<Animated.Image
pointerEvents="none"
style={{
flex: 1,
transform: [
{translateX: this.state.panX.interpolate({
inputRange: [-3, 3], // small range is extended by default
outputRange: [2, -2]}) // parallax
},
{scale: this.state.burns.interpolate({
inputRange: [1, 3000],
outputRange: [1, 1.25]}) // simple multiplier
},
],
}}
source={NATURE_IMAGE}
/>
</Animated.View>
);
}
}
var styles = StyleSheet.create({
tilt: {
overflow: 'hidden',
height: 200,
marginBottom: 4,
backgroundColor: 'rgb(130, 130, 255)',
borderColor: 'rgba(0, 0, 0, 0.2)',
borderWidth: 1,
borderRadius: 20,
},
});
var NATURE_IMAGE = {uri: 'http://www.deshow.net/d/file/travel/2009-04/scenic-beauty-of-nature-photography-2-504-4.jpg'};
module.exports = AnExTilt;
@@ -0,0 +1,98 @@
/**
* 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,
View,
ScrollView
} = React;
var AssetScaledImageExample = React.createClass({
getInitialState() {
return {
asset: this.props.asset
};
},
render() {
var image = this.state.asset.node.image;
return (
<ScrollView>
<View style={styles.row}>
<Image source={image} style={styles.imageWide}/>
</View>
<View style={styles.row}>
<Image source={image} style={styles.imageThumb}/>
<Image source={image} style={styles.imageThumb}/>
<Image source={image} style={styles.imageThumb}/>
</View>
<View style={styles.row}>
<Image source={image} style={styles.imageT1}/>
<Image source={image} style={styles.imageT2}/>
</View>
</ScrollView>
);
},
});
var styles = StyleSheet.create({
row: {
padding: 5,
flex: 1,
flexDirection: 'row',
alignSelf: 'center',
},
textColumn: {
flex: 1,
flexDirection: 'column',
},
imageWide: {
borderWidth: 1,
borderColor: 'black',
width: 320,
height: 240,
margin: 5,
},
imageThumb: {
borderWidth: 1,
borderColor: 'black',
width: 100,
height: 100,
margin: 5,
},
imageT1: {
borderWidth: 1,
borderColor: 'black',
width: 212,
height: 320,
margin: 5,
},
imageT2: {
borderWidth: 1,
borderColor: 'black',
width: 100,
height: 320,
margin: 5,
},
});
exports.title = '<AssetScaledImageExample>';
exports.description = 'Example component that displays the automatic scaling capabilities of the <Image /> tag';
module.exports = AssetScaledImageExample;
+30 -21
View File
@@ -29,18 +29,23 @@ var COLORS = ['red', 'orange', 'yellow', 'green', 'blue'];
var BasicStorageExample = React.createClass({
componentDidMount() {
AsyncStorage.getItem(STORAGE_KEY)
.then((value) => {
if (value !== null){
this.setState({selectedValue: value});
this._appendMessage('Recovered selection from disk: ' + value);
} else {
this._appendMessage('Initialized with no selection on disk.');
}
})
.catch((error) => this._appendMessage('AsyncStorage error: ' + error.message))
.done();
this._loadInitialState().done();
},
async _loadInitialState() {
try {
var value = await AsyncStorage.getItem(STORAGE_KEY);
if (value !== null){
this.setState({selectedValue: value});
this._appendMessage('Recovered selection from disk: ' + value);
} else {
this._appendMessage('Initialized with no selection on disk.');
}
} catch (error) {
this._appendMessage('AsyncStorage error: ' + error.message);
}
},
getInitialState() {
return {
selectedValue: COLORS[0],
@@ -80,19 +85,23 @@ var BasicStorageExample = React.createClass({
);
},
_onValueChange(selectedValue) {
async _onValueChange(selectedValue) {
this.setState({selectedValue});
AsyncStorage.setItem(STORAGE_KEY, selectedValue)
.then(() => this._appendMessage('Saved selection to disk: ' + selectedValue))
.catch((error) => this._appendMessage('AsyncStorage error: ' + error.message))
.done();
try {
await AsyncStorage.setItem(STORAGE_KEY, selectedValue);
this._appendMessage('Saved selection to disk: ' + selectedValue);
} catch (error) {
this._appendMessage('AsyncStorage error: ' + error.message);
}
},
_removeStorage() {
AsyncStorage.removeItem(STORAGE_KEY)
.then(() => this._appendMessage('Selection removed from disk.'))
.catch((error) => { this._appendMessage('AsyncStorage error: ' + error.message) })
.done();
async _removeStorage() {
try {
await AsyncStorage.removeItem(STORAGE_KEY);
this._appendMessage('Selection removed from disk.');
} catch (error) {
this._appendMessage('AsyncStorage error: ' + error.message);
}
},
_appendMessage(message) {
+26 -13
View File
@@ -24,9 +24,11 @@ var {
SwitchIOS,
Text,
View,
TouchableOpacity
} = React;
var CameraRollView = require('./CameraRollView.ios');
var AssetScaledImageExampleView = require('./AssetScaledImageExample');
var CAMERA_ROLL_VIEW = 'camera_roll_view';
@@ -54,7 +56,7 @@ var CameraRollExample = React.createClass({
<Text>{'Group Type: ' + this.state.groupTypes}</Text>
<CameraRollView
ref={CAMERA_ROLL_VIEW}
batchSize={5}
batchSize={20}
groupTypes={this.state.groupTypes}
renderImage={this._renderImage}
/>
@@ -62,24 +64,35 @@ var CameraRollExample = React.createClass({
);
},
loadAsset(asset){
this.props.navigator.push({
title: 'Camera Roll Image',
component: AssetScaledImageExampleView,
backButtonTitle: 'Back',
passProps: { asset: asset },
});
},
_renderImage(asset) {
var imageSize = this.state.bigImages ? 150 : 75;
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
var location = asset.node.location.longitude ?
JSON.stringify(asset.node.location) : 'Unknown location';
return (
<View key={asset} style={styles.row}>
<Image
source={asset.node.image}
style={imageStyle}
/>
<View style={styles.info}>
<Text style={styles.url}>{asset.node.image.uri}</Text>
<Text>{location}</Text>
<Text>{asset.node.group_name}</Text>
<Text>{new Date(asset.node.timestamp).toString()}</Text>
<TouchableOpacity onPress={ this.loadAsset.bind( this, asset ) }>
<View key={asset} style={styles.row}>
<Image
source={asset.node.image}
style={imageStyle}
/>
<View style={styles.info}>
<Text style={styles.url}>{asset.node.image.uri}</Text>
<Text>{location}</Text>
<Text>{asset.node.group_name}</Text>
<Text>{new Date(asset.node.timestamp).toString()}</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
},
@@ -115,7 +128,7 @@ var styles = StyleSheet.create({
},
});
exports.title = '<CameraRollView>';
exports.title = 'Camera Roll';
exports.description = 'Example component that uses CameraRoll to list user\'s photos';
exports.examples = [
{
+305
View File
@@ -0,0 +1,305 @@
/**
* 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 {
CameraRoll,
Image,
NativeModules,
ScrollView,
StyleSheet,
Text,
TouchableHighlight,
View,
} = React;
var ImageEditingManager = NativeModules.ImageEditingManager;
var RCTScrollViewConsts = NativeModules.UIManager.RCTScrollView.Constants;
var PAGE_SIZE = 20;
type ImageOffset = {
x: number;
y: number;
};
type ImageSize = {
width: number;
height: number;
};
type TransformData = {
offset: ImageOffset;
size: ImageSize;
}
class SquareImageCropper extends React.Component {
_isMounted: boolean;
_transformData: TransformData;
constructor(props) {
super(props);
this._isMounted = true;
this.state = {
randomPhoto: null,
measuredSize: null,
croppedImageURI: null,
cropError: null,
};
this._fetchRandomPhoto();
}
_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() {
this._isMounted = false;
}
render() {
if (!this.state.measuredSize) {
return (
<View
style={styles.container}
onLayout={(event) => {
var measuredWidth = event.nativeEvent.layout.width;
if (!measuredWidth) {
return;
}
this.setState({
measuredSize: {width: measuredWidth, height: measuredWidth},
});
}}
/>
);
}
if (!this.state.croppedImageURI) {
return this._renderImageCropper();
}
return this._renderCroppedImage();
}
_renderImageCropper() {
if (!this.state.randomPhoto) {
return (
<View style={styles.container} />
);
}
var error = null;
if (this.state.cropError) {
error = (
<Text>{this.state.cropError.message}</Text>
);
}
return (
<View style={styles.container}>
<Text>Drag the image within the square to crop:</Text>
<ImageCropper
image={this.state.randomPhoto}
size={this.state.measuredSize}
style={[styles.imageCropper, this.state.measuredSize]}
onTransformDataChange={(data) => this._transformData = data}
/>
<TouchableHighlight
style={styles.cropButtonTouchable}
onPress={this._crop.bind(this)}>
<View style={styles.cropButton}>
<Text style={styles.cropButtonLabel}>
Crop
</Text>
</View>
</TouchableHighlight>
{error}
</View>
);
}
_renderCroppedImage() {
return (
<View style={styles.container}>
<Text>Here is the cropped image:</Text>
<Image
source={{uri: this.state.croppedImageURI}}
style={[styles.imageCropper, this.state.measuredSize]}
/>
<TouchableHighlight
style={styles.cropButtonTouchable}
onPress={this._reset.bind(this)}>
<View style={styles.cropButton}>
<Text style={styles.cropButtonLabel}>
Try again
</Text>
</View>
</TouchableHighlight>
</View>
);
}
_crop() {
ImageEditingManager.cropImage(
this.state.randomPhoto.uri,
this._transformData,
(croppedImageURI) => this.setState({croppedImageURI}),
(cropError) => this.setState({cropError})
);
}
_reset() {
this.setState({
randomPhoto: null,
croppedImageURI: null,
cropError: null,
});
this._fetchRandomPhoto();
}
}
class ImageCropper extends React.Component {
_scaledImageSize: ImageSize;
_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;
if (widthRatio < heightRatio) {
this._scaledImageSize = {
width: this.props.size.width,
height: this.props.image.height / widthRatio,
};
} 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._updateTransformData(
this._contentOffset,
this._scaledImageSize,
this.props.size
);
}
_onScroll(event) {
this._updateTransformData(
event.nativeEvent.contentOffset,
event.nativeEvent.contentSize,
event.nativeEvent.layoutMeasurement
);
}
_updateTransformData(offset, scaledImageSize, croppedImageSize) {
var offsetRatioX = offset.x / scaledImageSize.width;
var offsetRatioY = offset.y / scaledImageSize.height;
var sizeRatioX = croppedImageSize.width / scaledImageSize.width;
var sizeRatioY = croppedImageSize.height / scaledImageSize.height;
this.props.onTransformDataChange && this.props.onTransformDataChange({
offset: {
x: this.props.image.width * offsetRatioX,
y: this.props.image.height * offsetRatioY,
},
size: {
width: this.props.image.width * sizeRatioX,
height: this.props.image.height * sizeRatioY,
},
});
}
render() {
var decelerationRate =
RCTScrollViewConsts && RCTScrollViewConsts.DecelerationRate ?
RCTScrollViewConsts.DecelerationRate.Fast :
0;
return (
<ScrollView
alwaysBounceVertical={true}
automaticallyAdjustContentInsets={false}
contentOffset={this._contentOffset}
decelerationRate={decelerationRate}
horizontal={true}
maximumZoomScale={3.0}
onMomentumScrollEnd={this._onScroll.bind(this)}
onScrollEndDrag={this._onScroll.bind(this)}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
style={this.props.style}
scrollEventThrottle={16}>
<Image source={this.props.image} style={this._scaledImageSize} />
</ScrollView>
);
}
}
exports.framework = 'React';
exports.title = 'ImageEditingManager';
exports.description = 'Cropping and scaling with ImageEditingManager';
exports.examples = [{
title: 'Image Cropping',
render() {
return <SquareImageCropper/>;
}
}];
var styles = StyleSheet.create({
container: {
flex: 1,
alignSelf: 'stretch',
},
imageCropper: {
alignSelf: 'center',
marginTop: 12,
},
cropButtonTouchable: {
alignSelf: 'center',
marginTop: 12,
},
cropButton: {
padding: 12,
backgroundColor: 'blue',
borderRadius: 4,
},
cropButtonLabel: {
color: 'white',
fontSize: 16,
fontWeight: '500',
},
});
+97 -18
View File
@@ -21,10 +21,41 @@ var {
StyleSheet,
Text,
View,
ActivityIndicatorIOS
} = React;
var ImageCapInsetsExample = require('./ImageCapInsetsExample');
var NetworkImageExample = React.createClass({
watchID: (null: ?number),
getInitialState: function() {
return {
error: false,
loading: false,
progress: 0
};
},
render: function() {
var loader = this.state.loading ?
<View style={styles.progress}>
<Text>{this.state.progress}%</Text>
<ActivityIndicatorIOS style={{marginLeft:5}}/>
</View> : null;
return this.state.error ?
<Text>{this.state.error}</Text> :
<Image
source={this.props.source}
style={[styles.base, {overflow: 'visible'}]}
onLoadStart={(e) => this.setState({loading: true})}
onError={(e) => this.setState({error: e.nativeEvent.error, loading: false})}
onProgress={(e) => this.setState({progress: Math.round(100 * e.nativeEvent.loaded / e.nativeEvent.total)})}
onLoad={() => this.setState({loading: false, error: false})}>
{loader}
</Image>;
}
});
exports.displayName = (undefined: ?string);
exports.framework = 'React';
exports.title = '<Image>';
@@ -59,6 +90,22 @@ exports.examples = [
);
},
},
{
title: 'Error Handler',
render: function() {
return (
<NetworkImageExample source={{uri: 'http://TYPO_ERROR_facebook.github.io/react/img/logo_og.png'}} />
);
},
},
{
title: 'Image Download Progress',
render: function() {
return (
<NetworkImageExample source={{uri: 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1'}}/>
);
},
},
{
title: 'Border Color',
render: function() {
@@ -194,23 +241,46 @@ exports.examples = [
'pixels to the tint color.',
render: function() {
return (
<View style={styles.horizontal}>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, {tintColor: 'blue' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: 'green' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: 'red' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: 'black' }]}
/>
<View>
<View style={styles.horizontal}>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, {tintColor: '#5ac8fa' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: '#4cd964' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: '#ff2d55' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: '#8e8e93' }]}
/>
</View>
<Text style={styles.sectionText}>
It also works with downloaded images:
</Text>
<View style={styles.horizontal}>
<Image
source={smallImage}
style={[styles.base, {tintColor: '#5ac8fa' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {tintColor: '#4cd964' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {tintColor: '#ff2d55' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {tintColor: '#8e8e93' }]}
/>
</View>
</View>
);
},
@@ -270,19 +340,28 @@ exports.examples = [
];
var fullImage = {uri: 'http://facebook.github.io/react/img/logo_og.png'};
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small.png'};
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small_2x.png'};
var styles = StyleSheet.create({
base: {
width: 38,
height: 38,
},
progress: {
flex: 1,
alignItems: 'center',
flexDirection: 'row',
width: 100
},
leftMargin: {
marginLeft: 10,
},
background: {
backgroundColor: '#222222'
},
sectionText: {
marginVertical: 6,
},
nestedText: {
marginLeft: 12,
marginTop: 20,
+10 -10
View File
@@ -15,37 +15,37 @@
*/
'use strict';
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare module 'image!story-background' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare module 'image!uie_comment_highlighted' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare module 'image!uie_comment_normal' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare module 'image!uie_thumb_normal' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare module 'image!uie_thumb_selected' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
+3 -4
View File
@@ -49,8 +49,7 @@ var LayoutEventExample = React.createClass({
() => {
console.log('layout animation done.');
this.addWrapText();
},
(error) => { throw new Error(JSON.stringify(error)); }
}
);
this.setState({
viewStyle: {
@@ -139,11 +138,11 @@ var styles = StyleSheet.create({
},
});
exports.title = 'onLayout';
exports.title = 'Layout Events';
exports.description = 'Layout events can be used to measure view size and position.';
exports.examples = [
{
title: 'onLayout',
title: 'LayoutEventExample',
render: function(): ReactElement {
return <LayoutEventExample />;
},
+4 -1
View File
@@ -62,8 +62,11 @@ var CircleBlock = React.createClass({
var LayoutExample = React.createClass({
statics: {
title: 'Layout - Flexbox',
description: 'Examples of using the flexbox API to layout views.'
description: 'Examples of using the flexbox API to layout views.',
},
displayName: 'LayoutExample',
render: function() {
return (
<UIExplorerPage title={this.props.navigator ? null : 'Layout'}>
@@ -0,0 +1,149 @@
/**
* 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,
ListView,
TouchableHighlight,
StyleSheet,
Text,
View,
} = React;
var THUMB_URLS = [
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851549_767334479959628_274486868_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851561_767334496626293_1958532586_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851579_767334503292959_179092627_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851589_767334513292958_1747022277_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851563_767334559959620_1193692107_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851593_767334566626286_1953955109_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851591_767334523292957_797560749_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851567_767334529959623_843148472_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851548_767334489959627_794462220_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851575_767334539959622_441598241_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851573_767334549959621_534583464_n.png',
'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851583_767334573292952_1519550680_n.png',
];
var ListViewGridLayoutExample = React.createClass({
statics: {
title: '<ListView> - Grid Layout',
description: 'Flexbox grid layout.'
},
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return {
dataSource: ds.cloneWithRows(this._genRows({})),
};
},
_pressData: ({}: {[key: number]: boolean}),
componentWillMount: function() {
this._pressData = {};
},
render: function() {
return (
// ListView wraps ScrollView and so takes on its properties.
// With that in mind you can use the ScrollView's contentContainerStyle prop to style the items.
<ListView
contentContainerStyle={styles.list}
dataSource={this.state.dataSource}
renderRow={this._renderRow}
/>
);
},
_renderRow: function(rowData: string, sectionID: number, rowID: number) {
var rowHash = Math.abs(hashCode(rowData));
var imgSource = {
uri: THUMB_URLS[rowHash % THUMB_URLS.length],
};
return (
<TouchableHighlight onPress={() => this._pressRow(rowID)} underlayColor="transparent">
<View>
<View style={styles.row}>
<Image style={styles.thumb} source={imgSource} />
<Text style={styles.text}>
{rowData}
</Text>
</View>
</View>
</TouchableHighlight>
);
},
_genRows: function(pressData: {[key: number]: boolean}): Array<string> {
var dataBlob = [];
for (var ii = 0; ii < 100; ii++) {
var pressedText = pressData[ii] ? ' (X)' : '';
dataBlob.push('Cell ' + ii + pressedText);
}
return dataBlob;
},
_pressRow: function(rowID: number) {
this._pressData[rowID] = !this._pressData[rowID];
this.setState({dataSource: this.state.dataSource.cloneWithRows(
this._genRows(this._pressData)
)});
},
});
/* eslint no-bitwise: 0 */
var hashCode = function(str) {
var hash = 15;
for (var ii = str.length - 1; ii >= 0; ii--) {
hash = ((hash << 5) - hash) + str.charCodeAt(ii);
}
return hash;
};
var styles = StyleSheet.create({
list: {
justifyContent: 'space-around',
flexDirection: 'row',
flexWrap: 'wrap'
},
row: {
justifyContent: 'center',
padding: 5,
margin: 3,
width: 100,
height: 100,
backgroundColor: '#F6F6F6',
alignItems: 'center',
borderWidth: 1,
borderRadius: 5,
borderColor: '#CCC'
},
thumb: {
width: 64,
height: 64
},
text: {
flex: 1,
marginTop: 5,
fontWeight: 'bold'
},
});
module.exports = ListViewGridLayoutExample;
+20 -21
View File
@@ -48,19 +48,19 @@ var Thumb = React.createClass({
},
render: function() {
return (
<TouchableOpacity onPress={this._onPressThumb}>
<View style={[styles.buttonContents, {flexDirection: this.state.dir}]}>
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
{this.state.dir === 'column' ?
<Text>
Oooo, look at this new text! So awesome it may just be crazy.
Let me keep typing here so it wraps at least one line.
</Text> :
<Text />
}
</View>
<TouchableOpacity
onPress={this._onPressThumb}
style={[styles.buttonContents, {flexDirection: this.state.dir}]}>
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
<Image style={styles.img} source={{uri: THUMB_URLS[this.state.thumbIndex]}} />
{this.state.dir === 'column' ?
<Text>
Oooo, look at this new text! So awesome it may just be crazy.
Let me keep typing here so it wraps at least one line.
</Text> :
<Text />
}
</TouchableOpacity>
);
}
@@ -127,14 +127,12 @@ var ListViewPagingExample = React.createClass({
<View><Text style={styles.text}>1 Like</Text></View> :
null;
return (
<TouchableOpacity onPress={this._onPressHeader}>
<View style={styles.header}>
{headerLikeText}
<View>
<Text style={styles.text}>
Table Header (click me)
</Text>
</View>
<TouchableOpacity onPress={this._onPressHeader} style={styles.header}>
{headerLikeText}
<View>
<Text style={styles.text}>
Table Header (click me)
</Text>
</View>
</TouchableOpacity>
);
@@ -212,6 +210,7 @@ var styles = StyleSheet.create({
width: 64,
height: 64,
marginHorizontal: 10,
backgroundColor: 'transparent',
},
section: {
flexDirection: 'column',
+1 -1
View File
@@ -16,9 +16,9 @@
'use strict';
var React = require('react-native');
var StyleSheet = require('StyleSheet');
var {
MapView,
StyleSheet,
Text,
TextInput,
View,
+172
View File
@@ -0,0 +1,172 @@
/**
* 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 {
Modal,
StyleSheet,
SwitchIOS,
Text,
TouchableHighlight,
View,
} = React;
exports.displayName = (undefined: ?string);
exports.framework = 'React';
exports.title = '<Modal>';
exports.description = 'Component for presenting modal views.';
var Button = React.createClass({
getInitialState() {
return {
active: false,
};
},
_onHighlight() {
this.setState({active: true});
},
_onUnhighlight() {
this.setState({active: false});
},
render() {
var colorStyle = {
color: this.state.active ? '#fff' : '#000',
};
return (
<TouchableHighlight
onHideUnderlay={this._onUnhighlight}
onPress={this.props.onPress}
onShowUnderlay={this._onHighlight}
style={[styles.button, this.props.style]}
underlayColor="#a9d9d4">
<Text style={[styles.buttonText, colorStyle]}>{this.props.children}</Text>
</TouchableHighlight>
);
}
});
var ModalExample = React.createClass({
getInitialState() {
return {
animated: true,
modalVisible: false,
transparent: false,
};
},
_setModalVisible(visible) {
this.setState({modalVisible: visible});
},
_toggleAnimated() {
this.setState({animated: !this.state.animated});
},
_toggleTransparent() {
this.setState({transparent: !this.state.transparent});
},
render() {
var modalBackgroundStyle = {
backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
};
var innerContainerTransparentStyle = this.state.transparent
? {backgroundColor: '#fff', padding: 20}
: null;
return (
<View>
<Modal
animated={this.state.animated}
transparent={this.state.transparent}
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>
<Button
onPress={this._setModalVisible.bind(this, false)}
style={styles.modalButton}>
Close
</Button>
</View>
</View>
</Modal>
<View style={styles.row}>
<Text style={styles.rowTitle}>Animated</Text>
<SwitchIOS value={this.state.animated} onValueChange={this._toggleAnimated} />
</View>
<View style={styles.row}>
<Text style={styles.rowTitle}>Transparent</Text>
<SwitchIOS value={this.state.transparent} onValueChange={this._toggleTransparent} />
</View>
<Button onPress={this._setModalVisible.bind(this, true)}>
Present
</Button>
</View>
);
},
});
exports.examples = [
{
title: 'Modal Presentation',
description: 'Modals can be presented with or without animation',
render: () => <ModalExample />,
},
];
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
innerContainer: {
borderRadius: 10,
},
row: {
alignItems: 'center',
flex: 1,
flexDirection: 'row',
marginBottom: 20,
},
rowTitle: {
flex: 1,
fontWeight: 'bold',
},
button: {
borderRadius: 5,
flex: 1,
height: 44,
justifyContent: 'center',
overflow: 'hidden',
},
buttonText: {
fontSize: 18,
margin: 5,
textAlign: 'center',
},
modalButton: {
marginTop: 10,
},
});
@@ -55,26 +55,24 @@ var BreadcrumbNavSample = React.createClass({
return (
<TouchableOpacity
onPress={() => navigator.push(_getRandomRoute())}>
<View>
<Text style={styles.titleText}>{route.title}</Text>
</View>
<Text style={styles.titleText}>{route.title}</Text>
</TouchableOpacity>
);
},
iconForRoute: function(route, navigator) {
return (
<TouchableOpacity onPress={() => {
navigator.popToRoute(route);
}}>
<View style={styles.crumbIconPlaceholder} />
</TouchableOpacity>
<TouchableOpacity
onPress={() => { navigator.popToRoute(route); }}
style={styles.crumbIconPlaceholder}
/>
);
},
separatorForRoute: function(route, navigator) {
return (
<TouchableOpacity onPress={navigator.pop}>
<View style={styles.crumbSeparatorPlaceholder} />
</TouchableOpacity>
<TouchableOpacity
onPress={navigator.pop}
style={styles.crumbSeparatorPlaceholder}
/>
);
}
};
@@ -51,12 +51,11 @@ var NavigationBarRouteMapper = {
var previousRoute = navState.routeStack[index - 1];
return (
<TouchableOpacity
onPress={() => navigator.pop()}>
<View style={styles.navBarLeftButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
{previousRoute.title}
</Text>
</View>
onPress={() => navigator.pop()}
style={styles.navBarLeftButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
{previousRoute.title}
</Text>
</TouchableOpacity>
);
},
@@ -64,12 +63,11 @@ var NavigationBarRouteMapper = {
RightButton: function(route, navigator, index, navState) {
return (
<TouchableOpacity
onPress={() => navigator.push(newRandomRoute())}>
<View style={styles.navBarRightButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
Next
</Text>
</View>
onPress={() => navigator.push(newRandomRoute())}
style={styles.navBarRightButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
Next
</Text>
</TouchableOpacity>
);
},
@@ -66,6 +66,7 @@ var NavigatorIOSColors = React.createClass({
tintColor="#FFFFFF"
barTintColor="#183E63"
titleTextColor="#FFFFFF"
translucent="true"
/>
);
},
@@ -0,0 +1,62 @@
/**
* 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 ProgressBar = require('ProgressBarAndroid');
var React = require('React');
var UIExplorerBlock = require('UIExplorerBlock');
var UIExplorerPage = require('UIExplorerPage');
var ProgressBarAndroidExample = React.createClass({
statics: {
title: '<ProgressBarAndroid>',
description: 'Visual indicator of progress of some operation. ' +
'Shows either a cyclic animation or a horizontal bar.',
},
render: function() {
return (
<UIExplorerPage title="ProgressBar Examples">
<UIExplorerBlock title="Default ProgressBar">
<ProgressBar />
</UIExplorerBlock>
<UIExplorerBlock title="Small ProgressBar">
<ProgressBar styleAttr="Small" />
</UIExplorerBlock>
<UIExplorerBlock title="Large ProgressBar">
<ProgressBar styleAttr="Large" />
</UIExplorerBlock>
<UIExplorerBlock title="Inverse ProgressBar">
<ProgressBar styleAttr="Inverse" />
</UIExplorerBlock>
<UIExplorerBlock title="Small Inverse ProgressBar">
<ProgressBar styleAttr="SmallInverse" />
</UIExplorerBlock>
<UIExplorerBlock title="Large Inverse ProgressBar">
<ProgressBar styleAttr="LargeInverse" />
</UIExplorerBlock>
</UIExplorerPage>
);
},
});
module.exports = ProgressBarAndroidExample;
@@ -0,0 +1,83 @@
/**
* 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 {
ScrollView,
StyleSheet,
Text,
TouchableOpacity
} = React;
var NUM_ITEMS = 20;
var ScrollViewSimpleExample = React.createClass({
statics: {
title: '<ScrollView>',
description: 'Component that enables scrolling through child components.'
},
makeItems: function(nItems: number, styles): Array<any> {
var items = [];
for (var i = 0; i < nItems; i++) {
items[i] = (
<TouchableOpacity key={i} style={styles}>
<Text>{'Item ' + i}</Text>
</TouchableOpacity>
);
}
return items;
},
render: function() {
// One of the items is a horizontal scroll view
var items = this.makeItems(NUM_ITEMS, styles.itemWrapper);
items[4] = (
<ScrollView key={'scrollView'} horizontal={true}>
{this.makeItems(NUM_ITEMS, [styles.itemWrapper, styles.horizontalItemWrapper])}
</ScrollView>
);
var verticalScrollView = (
<ScrollView style={styles.verticalScrollView}>
{items}
</ScrollView>
);
return verticalScrollView;
}
});
var styles = StyleSheet.create({
verticalScrollView: {
margin: 10,
},
itemWrapper: {
backgroundColor: '#dddddd',
alignItems: 'center',
borderRadius: 5,
borderWidth: 5,
borderColor: '#a52a2a',
padding: 30,
margin: 5,
},
horizontalItemWrapper: {
padding: 50
}
});
module.exports = ScrollViewSimpleExample;
@@ -118,7 +118,7 @@ var EventSegmentedControlExample = React.createClass({
_onChange(event) {
this.setState({
selectedIndex: event.nativeEvent.selectedIndex,
selectedIndex: event.nativeEvent.selectedSegmentIndex,
});
},
@@ -83,6 +83,26 @@ exports.examples = [{
</View>
);
},
}, {
title: 'Status Bar Network Activity Indicator',
render() {
return (
<View>
<TouchableHighlight style={styles.wrapper}
onPress={() => StatusBarIOS.setNetworkActivityIndicatorVisible(true)}>
<View style={styles.button}>
<Text>setNetworkActivityIndicatorVisible(true)</Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={styles.wrapper}
onPress={() => StatusBarIOS.setNetworkActivityIndicatorVisible(false)}>
<View style={styles.button}>
<Text>setNetworkActivityIndicatorVisible(false)</Text>
</View>
</TouchableHighlight>
</View>
);
},
}];
var styles = StyleSheet.create({
@@ -0,0 +1,80 @@
/**
* 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');
var SwitchAndroid = require('SwitchAndroid');
var Text = require('Text');
var UIExplorerBlock = require('UIExplorerBlock');
var UIExplorerPage = require('UIExplorerPage');
var SwitchAndroidExample = React.createClass({
statics: {
title: '<SwitchAndroid>',
description: 'Standard Android two-state toggle component'
},
getInitialState : function() {
return {
trueSwitchIsOn: true,
falseSwitchIsOn: false,
colorTrueSwitchIsOn: true,
colorFalseSwitchIsOn: false,
eventSwitchIsOn: false,
};
},
render: function() {
return (
<UIExplorerPage title="<SwitchAndroid>">
<UIExplorerBlock title="Switches can be set to true or false">
<SwitchAndroid
onValueChange={(value) => this.setState({falseSwitchIsOn: value})}
style={{marginBottom: 10}}
value={this.state.falseSwitchIsOn} />
<SwitchAndroid
onValueChange={(value) => this.setState({trueSwitchIsOn: value})}
value={this.state.trueSwitchIsOn} />
</UIExplorerBlock>
<UIExplorerBlock title="Switches can be disabled">
<SwitchAndroid
disabled={true}
style={{marginBottom: 10}}
value={true} />
<SwitchAndroid
disabled={true}
value={false} />
</UIExplorerBlock>
<UIExplorerBlock title="Change events can be detected">
<SwitchAndroid
onValueChange={(value) => this.setState({eventSwitchIsOn: value})}
style={{marginBottom: 10}}
value={this.state.eventSwitchIsOn} />
<SwitchAndroid
onValueChange={(value) => this.setState({eventSwitchIsOn: value})}
style={{marginBottom: 10}}
value={this.state.eventSwitchIsOn} />
<Text>{this.state.eventSwitchIsOn ? "On" : "Off"}</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Switches are controlled components">
<SwitchAndroid />
<SwitchAndroid value={true} />
</UIExplorerBlock>
</UIExplorerPage>
);
}
});
module.exports = SwitchAndroidExample;
+12 -7
View File
@@ -23,12 +23,16 @@ var {
View,
} = React;
var base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
var TabBarExample = React.createClass({
statics: {
title: '<TabBarIOS>',
description: 'Tab-based navigation.'
description: 'Tab-based navigation.',
},
displayName: 'TabBarExample',
getInitialState: function() {
return {
selectedTab: 'redTab',
@@ -37,11 +41,11 @@ var TabBarExample = React.createClass({
};
},
_renderContent: function(color: string, pageText: string) {
_renderContent: function(color: string, pageText: string, num?: number) {
return (
<View style={[styles.tabContent, {backgroundColor: color}]}>
<Text style={styles.tabText}>{pageText}</Text>
<Text style={styles.tabText}>{this.state.presses} re-renders of the More tab</Text>
<Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
</View>
);
},
@@ -49,10 +53,11 @@ var TabBarExample = React.createClass({
render: function() {
return (
<TabBarIOS
tintColor="black"
barTintColor="#3abeff">
tintColor="white"
barTintColor="darkslateblue">
<TabBarIOS.Item
title="Blue Tab"
icon={{uri: base64Icon, scale: 3}}
selected={this.state.selectedTab === 'blueTab'}
onPress={() => {
this.setState({
@@ -71,7 +76,7 @@ var TabBarExample = React.createClass({
notifCount: this.state.notifCount + 1,
});
}}>
{this._renderContent('#783E33', 'Red Tab')}
{this._renderContent('#783E33', 'Red Tab', this.state.notifCount)}
</TabBarIOS.Item>
<TabBarIOS.Item
systemIcon="more"
@@ -82,7 +87,7 @@ var TabBarExample = React.createClass({
presses: this.state.presses + 1
});
}}>
{this._renderContent('#21551C', 'Green Tab')}
{this._renderContent('#21551C', 'Green Tab', this.state.presses)}
</TabBarIOS.Item>
</TabBarIOS>
);
+349
View File
@@ -0,0 +1,349 @@
/**
* 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 {
StyleSheet,
Text,
View,
} = React;
var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');
var Entity = React.createClass({
render: function() {
return (
<Text style={{fontWeight: 'bold', color: '#527fe4'}}>
{this.props.children}
</Text>
);
}
});
var AttributeToggler = React.createClass({
getInitialState: function() {
return {fontWeight: 'bold', fontSize: 15};
},
toggleWeight: function() {
this.setState({
fontWeight: this.state.fontWeight === 'bold' ? 'normal' : 'bold'
});
},
increaseSize: function() {
this.setState({
fontSize: this.state.fontSize + 1
});
},
render: function() {
var curStyle = {fontWeight: this.state.fontWeight, fontSize: this.state.fontSize};
return (
<View>
<Text style={curStyle}>
Tap the controls below to change attributes.
</Text>
<Text>
<Text>See how it will even work on <Text style={curStyle}>this nested text</Text></Text>
</Text>
<Text>
<Text onPress={this.toggleWeight}>Toggle Weight</Text>
{' (with highlight onPress)'}
</Text>
<Text onPress={this.increaseSize} suppressHighlighting={true}>
Increase Size (suppressHighlighting true)
</Text>
</View>
);
}
});
var TextExample = React.createClass({
statics: {
title: '<Text>',
description: 'Base component for rendering styled text.',
},
render: function() {
return (
<UIExplorerPage title="<Text>">
<UIExplorerBlock title="Wrap">
<Text>
The text should wrap if it goes on multiple lines.
See, this is going to the next line.
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Padding">
<Text style={{padding: 10}}>
This text is indented by 10px padding on all sides.
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Font Family">
<Text style={{fontFamily: 'sans-serif'}}>
Sans-Serif
</Text>
<Text style={{fontFamily: 'sans-serif', fontWeight: 'bold'}}>
Sans-Serif Bold
</Text>
<Text style={{fontFamily: 'serif'}}>
Serif
</Text>
<Text style={{fontFamily: 'serif', fontWeight: 'bold'}}>
Serif Bold
</Text>
<Text style={{fontFamily: 'monospace'}}>
Monospace
</Text>
<Text style={{fontFamily: 'monospace', fontWeight: 'bold'}}>
Monospace Bold (After 5.0)
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Android Material Design fonts">
<View style={{flexDirection: 'row', alignItems: 'flex-start'}}>
<View style={{flex: 1}}>
<Text style={{fontFamily: 'sans-serif'}}>
Roboto Regular
</Text>
<Text style={{fontFamily: 'sans-serif', fontStyle: 'italic'}}>
Roboto Italic
</Text>
<Text style={{fontFamily: 'sans-serif', fontWeight: 'bold'}}>
Roboto Bold
</Text>
<Text style={{fontFamily: 'sans-serif', fontStyle: 'italic', fontWeight: 'bold'}}>
Roboto Bold Italic
</Text>
<Text style={{fontFamily: 'sans-serif-light'}}>
Roboto Light
</Text>
<Text style={{fontFamily: 'sans-serif-light', fontStyle: 'italic'}}>
Roboto Light Italic
</Text>
<Text style={{fontFamily: 'sans-serif-thin'}}>
Roboto Thin (After 4.2)
</Text>
<Text style={{fontFamily: 'sans-serif-thin', fontStyle: 'italic'}}>
Roboto Thin Italic (After 4.2)
</Text>
<Text style={{fontFamily: 'sans-serif-condensed'}}>
Roboto Condensed
</Text>
<Text style={{fontFamily: 'sans-serif-condensed', fontStyle: 'italic'}}>
Roboto Condensed Italic
</Text>
<Text style={{fontFamily: 'sans-serif-condensed', fontWeight: 'bold'}}>
Roboto Condensed Bold
</Text>
<Text style={{
fontFamily: 'sans-serif-condensed',
fontStyle: 'italic',
fontWeight: 'bold'}}>
Roboto Condensed Bold Italic
</Text>
<Text style={{fontFamily: 'sans-serif-medium'}}>
Roboto Medium (After 5.0)
</Text>
<Text style={{fontFamily: 'sans-serif-medium', fontStyle: 'italic'}}>
Roboto Medium Italic (After 5.0)
</Text>
</View>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Font Size">
<Text style={{fontSize: 23}}>
Size 23
</Text>
<Text style={{fontSize: 8}}>
Size 8
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Color">
<Text style={{color: 'red'}}>
Red color
</Text>
<Text style={{color: 'blue'}}>
Blue color
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Font Weight">
<Text style={{fontWeight: 'bold'}}>
Move fast and be bold
</Text>
<Text style={{fontWeight: 'normal'}}>
Move fast and be bold
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Font Style">
<Text style={{fontStyle: 'italic'}}>
Move fast and be bold
</Text>
<Text style={{fontStyle: 'normal'}}>
Move fast and be bold
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Font Style and Weight">
<Text style={{fontStyle: 'italic', fontWeight: 'bold'}}>
Move fast and be bold
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Nested">
<Text onPress={() => console.log('1st')}>
(Normal text,
<Text style={{fontWeight: 'bold'}} onPress={() => console.log('2nd')}>
(and bold
<Text style={{fontStyle: 'italic', fontSize: 11, color: '#527fe4'}} onPress={() => console.log('3rd')}>
(and tiny bold italic blue
<Text style={{fontWeight: 'normal', fontStyle: 'normal'}} onPress={() => console.log('4th')}>
(and tiny normal blue)
</Text>
)
</Text>
)
</Text>
)
</Text>
<Text style={{fontFamily: 'serif'}} onPress={() => console.log('1st')}>
(Serif
<Text style={{fontStyle: 'italic', fontWeight: 'bold'}} onPress={() => console.log('2nd')}>
(Serif Bold Italic
<Text
style={{fontFamily: 'monospace', fontStyle: 'normal', fontWeight: 'normal'}}
onPress={() => console.log('3rd')}>
(Monospace Normal
<Text
style={{fontFamily: 'sans-serif', fontWeight: 'bold'}}
onPress={() => console.log('4th')}>
(Sans-Serif Bold
<Text style={{fontWeight: 'normal'}} onPress={() => console.log('5th')}>
(and Sans-Serif Normal)
</Text>
)
</Text>
)
</Text>
)
</Text>
)
</Text>
<Text style={{fontSize: 12}}>
<Entity>Entity Name</Entity>
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Text Align">
<Text>
auto (default) - english LTR
</Text>
<Text>
أحب اللغة العربية auto (default) - arabic RTL
</Text>
<Text style={{textAlign: 'left'}}>
left left left left left left left left left left left left left left left
</Text>
<Text style={{textAlign: 'center'}}>
center center center center center center center center center center center
</Text>
<Text style={{textAlign: 'right'}}>
right right right right right right right right right right right right right
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Unicode">
<View style={{flex: 1}}>
<View style={{flexDirection: 'row'}}>
<Text style={{backgroundColor: 'red'}}>
星际争霸是世界上最好的游戏
</Text>
</View>
<View style={{flex: 1}}>
<Text style={{backgroundColor: 'red'}}>
星际争霸是世界上最好的游戏
</Text>
</View>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{backgroundColor: 'red'}}>
星际争霸是世界上最好的游戏
</Text>
</View>
<View style={{flex: 1}}>
<Text style={{backgroundColor: 'red'}}>
星际争霸是世界上最好的游戏星际争霸是世界上最好的游戏星际争霸是世界上最好的游戏星际争霸是世界上最好的游戏
</Text>
</View>
</View>
</UIExplorerBlock>
<UIExplorerBlock title="Spaces">
<Text>
A {'generated'} {' '} {'string'} and some &nbsp;&nbsp;&nbsp; spaces
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Line Height">
<Text style={{lineHeight: 35}}>
Holisticly formulate inexpensive ideas before best-of-breed benefits. <Text style={{fontSize: 20}}>Continually</Text> expedite magnetic potentialities rather than client-focused interfaces.
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Empty Text">
<Text />
</UIExplorerBlock>
<UIExplorerBlock title="Toggling Attributes">
<AttributeToggler />
</UIExplorerBlock>
<UIExplorerBlock title="backgroundColor attribute">
<Text style={{backgroundColor: '#ffaaaa'}}>
Red background,
<Text style={{backgroundColor: '#aaaaff'}}>
{' '}blue background,
<Text>
{' '}inherited blue background,
<Text style={{backgroundColor: '#aaffaa'}}>
{' '}nested green background.
</Text>
</Text>
</Text>
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="containerBackgroundColor attribute">
<View style={{flexDirection: 'row', height: 85}}>
<View style={{backgroundColor: '#ffaaaa', width: 150}} />
<View style={{backgroundColor: '#aaaaff', width: 150}} />
</View>
<Text style={[styles.backgroundColorText, {top: -80}]}>
Default containerBackgroundColor (inherited) + backgroundColor wash
</Text>
<Text style={[styles.backgroundColorText, {top: -70, backgroundColor: 'transparent'}]}>
{"containerBackgroundColor: 'transparent' + backgroundColor wash"}
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="numberOfLines attribute">
<Text numberOfLines={1}>
Maximum of one line no matter now much I write here. If I keep writing it{"'"}ll just truncate after one line
</Text>
<Text numberOfLines={2} style={{marginTop: 20}}>
Maximum of two lines no matter now much I write here. If I keep writing it{"'"}ll just truncate after two lines
</Text>
<Text style={{marginTop: 20}}>
No maximum lines specified no matter now much I write here. If I keep writing it{"'"}ll just keep going and going
</Text>
</UIExplorerBlock>
</UIExplorerPage>
);
}
});
var styles = StyleSheet.create({
backgroundColorText: {
left: 5,
backgroundColor: 'rgba(100, 100, 100, 0.3)'
},
});
module.exports = TextExample;
+67 -1
View File
@@ -185,6 +185,44 @@ exports.examples = [
</View>
);
},
}, {
title: 'Text Decoration',
render: function() {
return (
<View>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'solid'}}>
Solid underline
</Text>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'double', textDecorationColor: '#ff0000'}}>
Double underline with custom color
</Text>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'dashed', textDecorationColor: '#9CDC40'}}>
Dashed underline with custom color
</Text>
<Text style={{textDecorationLine: 'underline', textDecorationStyle: 'dotted', textDecorationColor: 'blue'}}>
Dotted underline with custom color
</Text>
<Text style={{textDecorationLine: 'none'}}>
None textDecoration
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'solid'}}>
Solid line-through
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'double', textDecorationColor: '#ff0000'}}>
Double line-through with custom color
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'dashed', textDecorationColor: '#9CDC40'}}>
Dashed line-through with custom color
</Text>
<Text style={{textDecorationLine: 'line-through', textDecorationStyle: 'dotted', textDecorationColor: 'blue'}}>
Dotted line-through with custom color
</Text>
<Text style={{textDecorationLine: 'underline line-through'}}>
Both underline and line-through
</Text>
</View>
);
},
}, {
title: 'Nested',
description: 'Nested text components will inherit the styles of their ' +
@@ -231,7 +269,7 @@ exports.examples = [
right right right right right right right right right right right right right
</Text>
<Text style={{textAlign: 'justify'}}>
justify: this text component's contents are laid out with "textAlign: justify"
justify: this text component{"'"}s contents are laid out with "textAlign: justify"
and as you can see all of the lines except the last one span the
available width of the parent container.
</Text>
@@ -331,6 +369,34 @@ exports.examples = [
</View>
);
},
}, {
title: 'Text highlighting (tap the link to see highlight)',
render: function() {
return (
<View>
<Text>Lorem ipsum dolor sit amet, <Text suppressHighlighting={false} style={{backgroundColor: 'white', textDecorationLine: 'underline', color: 'blue'}} onPress={() => null}>consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud</Text> exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</Text>
</View>
);
},
}, {
title: 'allowFontScaling attribute',
render: function() {
return (
<View>
<Text>
By default, text will respect Text Size accessibility setting on iOS.
It means that all font sizes will be increased or descreased depending on the value of Text Size setting in
{" "}<Text style={{fontWeight: 'bold'}}>Settings.app - Display & Brightness - Text Size</Text>
</Text>
<Text style={{marginTop: 10}}>
You can disable scaling for your Text component by passing {"\""}allowFontScaling={"{"}false{"}\""} prop.
</Text>
<Text allowFontScaling={false} style={{marginTop: 20}}>
This text will not scale.
</Text>
</View>
);
},
}];
var styles = StyleSheet.create({
@@ -0,0 +1,316 @@
/**
* 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 {
Text,
TextInput,
View,
StyleSheet,
} = React;
var TextEventsExample = React.createClass({
getInitialState: function() {
return {
curText: '<No Event>',
prevText: '<No Event>',
prev2Text: '<No Event>',
};
},
updateText: function(text) {
this.setState((state) => {
return {
curText: text,
prevText: state.curText,
prev2Text: state.prevText,
};
});
},
render: function() {
return (
<View>
<TextInput
autoCapitalize="none"
placeholder="Enter text to see events"
autoCorrect={false}
onFocus={() => this.updateText('onFocus')}
onBlur={() => this.updateText('onBlur')}
onChange={(event) => this.updateText(
'onChange text: ' + event.nativeEvent.text
)}
onEndEditing={(event) => this.updateText(
'onEndEditing text: ' + event.nativeEvent.text
)}
onSubmitEditing={(event) => this.updateText(
'onSubmitEditing text: ' + event.nativeEvent.text
)}
style={styles.singleLine}
/>
<Text style={styles.eventLabel}>
{this.state.curText}{'\n'}
(prev: {this.state.prevText}){'\n'}
(prev2: {this.state.prev2Text})
</Text>
</View>
);
}
});
class RewriteExample extends React.Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
return (
<TextInput
onChangeText={(text) => {
text = text.replace(/ /g, '_');
this.setState({text});
}}
style={styles.singleLine}
value={this.state.text}
/>
);
}
}
var styles = StyleSheet.create({
multiline: {
height: 60,
fontSize: 16,
padding: 4,
marginBottom: 10,
},
eventLabel: {
margin: 3,
fontSize: 12,
},
singleLine: {
fontSize: 16,
padding: 4,
},
singleLineWithHeightTextInput: {
height: 30,
},
});
exports.title = '<TextInput>';
exports.description = 'Single and multi-line text inputs.';
exports.examples = [
{
title: 'Auto-focus',
render: function() {
return <TextInput autoFocus={true} style={styles.singleLine} />;
}
},
{
title: "Live Re-Write (<sp> -> '_')",
render: function() {
return <RewriteExample />;
}
},
{
title: 'Auto-capitalize',
render: function() {
var autoCapitalizeTypes = [
'none',
'sentences',
'words',
'characters',
];
var examples = autoCapitalizeTypes.map((type) => {
return (
<TextInput
autoCapitalize={type}
placeholder={'autoCapitalize: ' + type}
style={styles.singleLine}
/>
);
});
return <View>{examples}</View>;
}
},
{
title: 'Auto-correct',
render: function() {
return (
<View>
<TextInput
autoCorrect={true}
placeholder="This has autoCorrect"
style={styles.singleLine}
/>
<TextInput
autoCorrect={false}
placeholder="This does not have autoCorrect"
style={styles.singleLine}
/>
</View>
);
}
},
{
title: 'Keyboard types',
render: function() {
var keyboardTypes = [
'default',
'email-address',
'numeric',
];
var examples = keyboardTypes.map((type) => {
return (
<TextInput
keyboardType={type}
placeholder={'keyboardType: ' + type}
style={styles.singleLine}
/>
);
});
return <View>{examples}</View>;
}
},
{
title: 'Event handling',
render: function(): ReactElement { return <TextEventsExample />; },
},
{
title: 'Colors and text inputs',
render: function() {
return (
<View>
<TextInput
style={[styles.singleLine]}
defaultValue="Default color text"
/>
<TextInput
style={[styles.singleLine, {color: 'green'}]}
defaultValue="Green Text"
/>
<TextInput
placeholder="Default placeholder text color"
style={styles.singleLine}
/>
<TextInput
placeholder="Red placeholder text color"
placeholderTextColor="red"
style={styles.singleLine}
/>
<TextInput
placeholder="Default underline color"
style={styles.singleLine}
/>
<TextInput
placeholder="Blue underline color"
style={styles.singleLine}
underlineColorAndroid="blue"
/>
</View>
);
}
},
{
title: 'Text input, themes and heights',
render: function() {
return (
<TextInput
placeholder="If you set height, beware of padding set from themes"
style={[styles.singleLineWithHeightTextInput]}
/>
);
}
},
{
title: 'Passwords',
render: function() {
return (
<TextInput
defaultValue="iloveturtles"
password={true}
style={styles.singleLine}
/>
);
}
},
{
title: 'Editable',
render: function() {
return (
<TextInput
defaultValue="Can't touch this! (>'-')> ^(' - ')^ <('-'<) (>'-')> ^(' - ')^"
editable={false}
style={styles.singleLine}
/>
);
}
},
{
title: 'Multiline',
render: function() {
return (
<View>
<TextInput
autoCorrect={true}
placeholder="multiline, aligned top-left"
placeholderTextColor="red"
multiline={true}
textAlign="start"
textAlignVertical="top"
style={styles.multiline}
/>
<TextInput
autoCorrect={true}
placeholder="multiline, aligned center"
placeholderTextColor="green"
multiline={true}
textAlign="center"
textAlignVertical="center"
style={[styles.multiline]}
/>
<TextInput
autoCorrect={true}
multiline={true}
textAlign="end"
textAlignVertical="bottom"
style={[styles.multiline, {color: 'blue'}]}>
<Text style={styles.multiline}>multiline with children, aligned bottom-right</Text>
</TextInput>
</View>
);
}
},
{
title: 'Fixed number of lines',
platform: 'android',
render: function() {
return (
<View>
<TextInput numberOfLines={2}
multiline={true}
placeholder="Two line input"
/>
<TextInput numberOfLines={5}
multiline={true}
placeholder="Five line input"
/>
</View>
);
}
},
];
@@ -33,7 +33,7 @@ var WithLabel = React.createClass({
{this.props.children}
</View>
);
}
},
});
var TextEventsExample = React.createClass({
@@ -41,13 +41,17 @@ var TextEventsExample = React.createClass({
return {
curText: '<No Event>',
prevText: '<No Event>',
prev2Text: '<No Event>',
};
},
updateText: function(text) {
this.setState({
curText: text,
prevText: this.state.curText,
this.setState((state) => {
return {
curText: text,
prevText: state.curText,
prev2Text: state.prevText,
};
});
},
@@ -73,13 +77,43 @@ var TextEventsExample = React.createClass({
/>
<Text style={styles.eventLabel}>
{this.state.curText}{'\n'}
(prev: {this.state.prevText})
(prev: {this.state.prevText}){'\n'}
(prev2: {this.state.prev2Text})
</Text>
</View>
);
}
});
class RewriteExample extends React.Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
var limit = 20;
var remainder = limit - this.state.text.length;
var remainderColor = remainder > 5 ? 'blue' : 'red';
return (
<View style={styles.rewriteContainer}>
<TextInput
multiline={false}
maxLength={limit}
onChangeText={(text) => {
text = text.replace(/ /g, '_');
this.setState({text});
}}
style={styles.default}
value={this.state.text}
/>
<Text style={[styles.remainder, {color: remainderColor}]}>
{remainder}
</Text>
</View>
);
}
}
var styles = StyleSheet.create({
page: {
paddingBottom: 300,
@@ -125,12 +159,19 @@ var styles = StyleSheet.create({
flex: 1,
},
label: {
width: 120,
justifyContent: 'flex-end',
flexDirection: 'row',
width: 115,
alignItems: 'flex-end',
marginRight: 10,
paddingTop: 2,
},
rewriteContainer: {
flexDirection: 'row',
alignItems: 'center',
},
remainder: {
textAlign: 'right',
width: 24,
},
});
exports.displayName = (undefined: ?string);
@@ -143,6 +184,12 @@ exports.examples = [
return <TextInput autoFocus={true} style={styles.default} />;
}
},
{
title: "Live Re-Write (<sp> -> '_') + maxLength",
render: function() {
return <RewriteExample />;
}
},
{
title: 'Auto-capitalize',
render: function() {
@@ -268,7 +315,7 @@ exports.examples = [
return (
<View>
<WithLabel label="true">
<TextInput password={true} style={styles.default} value="abc" />
<TextInput password={true} style={styles.default} defaultValue="abc" />
</WithLabel>
</View>
);
@@ -276,7 +323,7 @@ exports.examples = [
},
{
title: 'Event handling',
render: function(): ReactElement { return <TextEventsExample /> },
render: function(): ReactElement { return <TextEventsExample />; },
},
{
title: 'Colored input text',
@@ -285,11 +332,11 @@ exports.examples = [
<View>
<TextInput
style={[styles.default, {color: 'blue'}]}
value="Blue"
defaultValue="Blue"
/>
<TextInput
style={[styles.default, {color: 'green'}]}
value="Green"
defaultValue="Green"
/>
</View>
);
@@ -336,7 +383,7 @@ exports.examples = [
<WithLabel label="clearTextOnFocus">
<TextInput
placeholder="text is cleared on focus"
value="text is cleared on focus"
defaultValue="text is cleared on focus"
style={styles.default}
clearTextOnFocus={true}
/>
@@ -344,7 +391,7 @@ exports.examples = [
<WithLabel label="selectTextOnFocus">
<TextInput
placeholder="text is selected on focus"
value="text is selected on focus"
defaultValue="text is selected on focus"
style={styles.default}
selectTextOnFocus={true}
/>
@@ -364,7 +411,7 @@ exports.examples = [
style={styles.multiline}
/>
<TextInput
placeholder="mutliline text input with font styles and placeholder"
placeholder="multiline text input with font styles and placeholder"
multiline={true}
clearTextOnFocus={true}
autoCorrect={true}
@@ -374,7 +421,7 @@ exports.examples = [
style={[styles.multiline, styles.multilineWithFontStyles]}
/>
<TextInput
placeholder="uneditable mutliline text input"
placeholder="uneditable multiline text input"
editable={false}
multiline={true}
style={styles.multiline}
@@ -0,0 +1,68 @@
/**
* 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 {
StyleSheet,
Text,
ToastAndroid,
TouchableWithoutFeedback
} = React;
var UIExplorerBlock = require('UIExplorerBlock');
var UIExplorerPage = require('UIExplorerPage');
var ToastExample = React.createClass({
statics: {
title: 'Toast Example',
description: 'Toast Example',
},
getInitialState: function() {
return {};
},
render: function() {
return (
<UIExplorerPage title="ToastAndroid">
<UIExplorerBlock title="Simple toast">
<TouchableWithoutFeedback
onPress={() =>
ToastAndroid.show('This is a toast with short duration', ToastAndroid.SHORT)}>
<Text style={styles.text}>Click me.</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Toast with long duration">
<TouchableWithoutFeedback
onPress={() =>
ToastAndroid.show('This is a toast with long duration', ToastAndroid.LONG)}>
<Text style={styles.text}>Click me too.</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
</UIExplorerPage>
);
},
});
var styles = StyleSheet.create({
text: {
color: 'black',
},
});
module.exports = ToastExample;
@@ -0,0 +1,119 @@
/**
* 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 {
StyleSheet,
Text,
View,
} = React;
var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');
var SwitchAndroid = require('SwitchAndroid');
var ToolbarAndroid = require('ToolbarAndroid');
var ToolbarAndroidExample = React.createClass({
statics: {
title: '<ToolbarAndroid>',
description: 'Examples of using the Android toolbar.'
},
getInitialState: function() {
return {
actionText: 'Example app with toolbar component',
toolbarSwitch: false,
colorProps: {
titleColor: '#3b5998',
subtitleColor: '#6a7180',
},
};
},
render: function() {
return (
<UIExplorerPage title="<ToolbarAndroid>">
<UIExplorerBlock title="Toolbar with title/subtitle and actions">
<ToolbarAndroid
actions={toolbarActions}
navIcon={require('image!ic_menu_black_24dp')}
onActionSelected={this._onActionSelected}
onIconClicked={() => this.setState({actionText: 'Icon clicked'})}
style={styles.toolbar}
subtitle={this.state.actionText}
title="Toolbar" />
<Text>{this.state.actionText}</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Toolbar with logo & custom title view (a View with Switch+Text)">
<ToolbarAndroid
logo={require('image!launcher_icon')}
style={styles.toolbar}>
<View style={{height: 56, flexDirection: 'row', alignItems: 'center'}}>
<SwitchAndroid
value={this.state.toolbarSwitch}
onValueChange={(value) => this.setState({'toolbarSwitch': value})} />
<Text>{'\'Tis but a switch'}</Text>
</View>
</ToolbarAndroid>
</UIExplorerBlock>
<UIExplorerBlock title="Toolbar with no icon">
<ToolbarAndroid
actions={toolbarActions}
style={styles.toolbar}
subtitle="There be no icon here" />
</UIExplorerBlock>
<UIExplorerBlock title="Toolbar with navIcon & logo, no title">
<ToolbarAndroid
actions={toolbarActions}
logo={require('image!launcher_icon')}
navIcon={require('image!ic_menu_black_24dp')}
style={styles.toolbar} />
</UIExplorerBlock>
<UIExplorerBlock title="Toolbar with custom title colors">
<ToolbarAndroid
navIcon={require('image!ic_menu_black_24dp')}
onIconClicked={() => this.setState({colorProps: {}})}
title="Wow, such toolbar"
style={styles.toolbar}
subtitle="Much native"
{...this.state.colorProps} />
<Text>
Touch the icon to reset the custom colors to the default (theme-provided) ones.
</Text>
</UIExplorerBlock>
</UIExplorerPage>
);
},
_onActionSelected: function(position) {
this.setState({
actionText: 'Selected ' + toolbarActions[position].title,
});
},
});
var toolbarActions = [
{title: 'Create', icon: require('image!ic_create_black_48dp'), show: 'always'},
{title: 'Filter'},
{title: 'Settings', icon: require('image!ic_settings_black_48dp'), show: 'always'},
];
var styles = StyleSheet.create({
toolbar: {
backgroundColor: '#e9eaed',
height: 56,
},
});
module.exports = ToolbarAndroidExample;
+7 -4
View File
@@ -27,6 +27,7 @@ var {
} = React;
exports.displayName = (undefined: ?string);
exports.description = 'Touchable and onPress examples';
exports.title = '<Touchable*> and onPress';
exports.examples = [
{
@@ -130,10 +131,11 @@ var TouchableFeedbackEvents = React.createClass({
},
render: function() {
return (
<View>
<View testID="touchable_feedback_events">
<View style={[styles.row, {justifyContent: 'center'}]}>
<TouchableOpacity
style={styles.wrapper}
testID="touchable_feedback_events_button"
onPress={() => this._appendEvent('press')}
onPressIn={() => this._appendEvent('pressIn')}
onPressOut={() => this._appendEvent('pressOut')}
@@ -143,7 +145,7 @@ var TouchableFeedbackEvents = React.createClass({
</Text>
</TouchableOpacity>
</View>
<View style={styles.eventLogBox}>
<View testID="touchable_feedback_events_console" style={styles.eventLogBox}>
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
</View>
</View>
@@ -165,10 +167,11 @@ var TouchableDelayEvents = React.createClass({
},
render: function() {
return (
<View>
<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')}
@@ -181,7 +184,7 @@ var TouchableDelayEvents = React.createClass({
</Text>
</TouchableOpacity>
</View>
<View style={styles.eventLogBox}>
<View style={styles.eventLogBox} testID="touchable_delay_events_console">
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
</View>
</View>
+175 -46
View File
@@ -1,59 +1,85 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* @providesModule TransformExample
* 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');
var StyleSheet = require('StyleSheet');
var TimerMixin = require('react-timer-mixin');
var UIExplorerBlock = require('UIExplorerBlock');
var UIExplorerPage = require('UIExplorerPage');
var View = require('View');
var TransformExample = React.createClass({
mixins: [TimerMixin],
var React = require('react-native');
var {
Animated,
StyleSheet,
Text,
View,
} = React;
var Flip = React.createClass({
getInitialState() {
return {
interval: this.setInterval(this._update, 800),
pulse: false,
theta: new Animated.Value(45),
};
},
componentDidMount() {
this._animate();
},
_animate() {
this.state.theta.setValue(0);
Animated.timing(this.state.theta, {
toValue: 360,
duration: 5000,
}).start(this._animate);
},
render() {
return (
<UIExplorerPage title="Transforms">
<UIExplorerBlock title="foo bar">
<View style={{height: 500}}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box3step1} />
<View style={styles.box3step2} />
<View style={styles.box3step3} />
<View style={styles.box4} />
<View style={[
styles.box5,
this.state.pulse ? styles.box5Transform : null
]} />
</View>
</UIExplorerBlock>
</UIExplorerPage>
<View style={styles.flipCardContainer}>
<Animated.View style={[
styles.flipCard,
{transform: [
{perspective: 850},
{rotateX: this.state.theta.interpolate({
inputRange: [0, 180],
outputRange: ['0deg', '180deg']
})},
]}]}>
<Text style={styles.flipText}>
This text is flipping great.
</Text>
</Animated.View>
<Animated.View style={[styles.flipCard, {
position: 'absolute',
top: 0,
backgroundColor: 'red',
transform: [
{perspective: 850},
{rotateX: this.state.theta.interpolate({
inputRange: [0, 180],
outputRange: ['180deg', '360deg']
})},
]}]}>
<Text style={styles.flipText}>
On the flip side...
</Text>
</Animated.View>
</View>
);
},
_update() {
this.setState({
pulse: !this.state.pulse,
});
},
}
});
var styles = StyleSheet.create({
container: {
height: 500,
},
box1: {
left: 0,
backgroundColor: 'green',
@@ -86,7 +112,7 @@ var styles = StyleSheet.create({
},
box3step1: {
left: 0,
backgroundColor: '#ffb6c1', // lightpink
backgroundColor: 'lightpink',
height: 50,
position: 'absolute',
top: 0,
@@ -97,7 +123,7 @@ var styles = StyleSheet.create({
},
box3step2: {
left: 0,
backgroundColor: '#ff69b4', //hotpink
backgroundColor: 'hotpink',
height: 50,
opacity: 0.5,
position: 'absolute',
@@ -111,7 +137,7 @@ var styles = StyleSheet.create({
},
box3step3: {
left: 0,
backgroundColor: '#ff1493', // deeppink
backgroundColor: 'deeppink',
height: 50,
opacity: 0.5,
position: 'absolute',
@@ -127,7 +153,7 @@ var styles = StyleSheet.create({
},
box4: {
left: 0,
backgroundColor: '#ff8c00', // darkorange
backgroundColor: 'darkorange',
height: 50,
position: 'absolute',
top: 0,
@@ -139,7 +165,7 @@ var styles = StyleSheet.create({
width: 100,
},
box5: {
backgroundColor: '#800000', // maroon
backgroundColor: 'maroon',
height: 50,
position: 'absolute',
right: 0,
@@ -153,7 +179,110 @@ var styles = StyleSheet.create({
{scale: 2},
],
},
flipCardContainer: {
marginVertical: 40,
flex: 1,
alignSelf: 'center',
},
flipCard: {
width: 200,
height: 200,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'blue',
backfaceVisibility: 'hidden',
},
flipText: {
width: 90,
fontSize: 20,
color: 'white',
fontWeight: 'bold',
}
});
module.exports = TransformExample;
exports.title = 'Transforms';
exports.description = 'View transforms';
exports.examples = [
{
title: 'Perspective',
description: 'perspective: 850, rotateX: Animated.timing(0 -> 360)',
render(): ReactElement { return <Flip />; }
},
{
title: 'Translate, Rotate, Scale',
description: "translateX: 100, translateY: 50, rotate: '30deg', scaleX: 2, scaleY: 2",
render() {
return (
<View style={styles.container}>
<View style={styles.box1} />
</View>
);
}
},
{
title: 'Scale, Translate, Rotate, ',
description: "scaleX: 2, scaleY: 2, translateX: 100, translateY: 50, rotate: '30deg'",
render() {
return (
<View style={styles.container}>
<View style={styles.box2} />
</View>
);
}
},
{
title: 'Rotate',
description: "rotate: '30deg'",
render() {
return (
<View style={styles.container}>
<View style={styles.box3step1} />
</View>
);
}
},
{
title: 'Rotate, Scale',
description: "rotate: '30deg', scaleX: 2, scaleY: 2",
render() {
return (
<View style={styles.container}>
<View style={styles.box3step2} />
</View>
);
}
},
{
title: 'Rotate, Scale, Translate ',
description: "rotate: '30deg', scaleX: 2, scaleY: 2, translateX: 100, translateY: 50",
render() {
return (
<View style={styles.container}>
<View style={styles.box3step3} />
</View>
);
}
},
{
title: 'Translate, Scale, Rotate',
description: "translate: [200, 350], scale: 2.5, rotate: '-0.2rad'",
render() {
return (
<View style={styles.container}>
<View style={styles.box4} />
</View>
);
}
},
{
title: 'Translate, Rotate, Scale',
description: "translate: [-50, 35], rotate: '50deg', scale: 2",
render() {
return (
<View style={styles.container}>
<View style={[styles.box5, styles.box5Transform]} />
</View>
);
}
}
];
@@ -7,19 +7,25 @@
objects = {
/* Begin PBXBuildFile section */
1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1300627E1B59179B0043FE5A /* RCTGzipTests.m */; };
13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FE81AA91428003F314A /* libRCTImage.a */; };
134180011AA9153C003F314A /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; };
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 */; };
138D6A171B53CD440074A87E /* RCTCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A151B53CD440074A87E /* RCTCacheTests.m */; };
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A161B53CD440074A87E /* RCTShadowViewTests.m */; };
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */; };
139FDEDB1B0651FB00C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDED91B0651EA00C62182 /* libRCTWebSocket.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
141FC1211B222EBB004D5FFB /* IntegrationTestsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 141FC1201B222EBB004D5FFB /* IntegrationTestsTests.m */; };
143BC5A11B21E45C00462512 /* UIExplorerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* UIExplorerIntegrationTests.m */; };
144D21241B2204C5006DB32B /* RCTClippingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 144D21231B2204C5006DB32B /* RCTClippingTests.m */; };
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DB03471B5D2ED500C27245 /* RCTJSONTests.m */; };
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */; };
141FC1211B222EBB004D5FFB /* IntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 141FC1201B222EBB004D5FFB /* IntegrationTests.m */; };
143BC5A11B21E45C00462512 /* UIExplorerSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */; };
144D21241B2204C5006DB32B /* RCTImageUtilTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 144D21231B2204C5006DB32B /* RCTImageUtilTests.m */; };
147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; };
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */; };
1497CFAD1B21F5E400C1F8F2 /* RCTBridgeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */; };
@@ -47,6 +53,8 @@
14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DC67F11AB71876001358AB /* libRCTPushNotification.a */; };
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; };
834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; };
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */; };
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
/* End PBXBuildFile section */
@@ -153,11 +161,15 @@
/* 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>"; };
13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
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>"; };
138D6A151B53CD440074A87E /* RCTCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCacheTests.m; sourceTree = "<group>"; };
138D6A161B53CD440074A87E /* RCTShadowViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTShadowViewTests.m; sourceTree = "<group>"; };
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleMethodTests.m; sourceTree = "<group>"; };
139FDECA1B0651EA00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* UIExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = UIExplorer/AppDelegate.h; sourceTree = "<group>"; };
@@ -167,7 +179,9 @@
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>"; };
13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
141FC1201B222EBB004D5FFB /* IntegrationTestsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IntegrationTestsTests.m; 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>"; };
141FC1201B222EBB004D5FFB /* IntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IntegrationTests.m; sourceTree = "<group>"; };
143BC57E1B21E18100462512 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
143BC5811B21E18100462512 /* testLayoutExampleSnapshot_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testLayoutExampleSnapshot_1@2x.png"; sourceTree = "<group>"; };
143BC5821B21E18100462512 /* testSliderExampleSnapshot_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testSliderExampleSnapshot_1@2x.png"; sourceTree = "<group>"; };
@@ -177,8 +191,8 @@
143BC5861B21E18100462512 /* testViewExampleSnapshot_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testViewExampleSnapshot_1@2x.png"; sourceTree = "<group>"; };
143BC5951B21E3E100462512 /* UIExplorerIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIExplorerIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
143BC5981B21E3E100462512 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
143BC5A01B21E45C00462512 /* UIExplorerIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIExplorerIntegrationTests.m; sourceTree = "<group>"; };
144D21231B2204C5006DB32B /* RCTClippingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTClippingTests.m; sourceTree = "<group>"; };
143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIExplorerSnapshotTests.m; sourceTree = "<group>"; };
144D21231B2204C5006DB32B /* RCTImageUtilTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageUtilTests.m; sourceTree = "<group>"; };
1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAllocationTests.m; sourceTree = "<group>"; };
1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBridgeTests.m; sourceTree = "<group>"; };
1497CFA61B21F5E400C1F8F2 /* RCTContextExecutorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTContextExecutorTests.m; sourceTree = "<group>"; };
@@ -202,6 +216,8 @@
14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
357858F81B28D2C400341EDB /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
58005BE41ABA80530062E044 /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = ../../Libraries/RCTTest/RCTTest.xcodeproj; sourceTree = "<group>"; };
83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerScenarioTests.m; sourceTree = "<group>"; };
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = "<group>"; };
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -342,11 +358,18 @@
children = (
1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */,
1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */,
144D21231B2204C5006DB32B /* RCTClippingTests.m */,
138D6A151B53CD440074A87E /* RCTCacheTests.m */,
1497CFA61B21F5E400C1F8F2 /* RCTContextExecutorTests.m */,
1497CFA71B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m */,
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */,
1497CFA81B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m */,
1497CFA91B21F5E400C1F8F2 /* RCTEventDispatcherTests.m */,
1300627E1B59179B0043FE5A /* RCTGzipTests.m */,
144D21231B2204C5006DB32B /* RCTImageUtilTests.m */,
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */,
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */,
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */,
138D6A161B53CD440074A87E /* RCTShadowViewTests.m */,
1497CFAA1B21F5E400C1F8F2 /* RCTSparseArrayTests.m */,
1497CFAB1B21F5E400C1F8F2 /* RCTUIManagerTests.m */,
143BC57E1B21E18100462512 /* Info.plist */,
@@ -381,8 +404,9 @@
143BC5961B21E3E100462512 /* UIExplorerIntegrationTests */ = {
isa = PBXGroup;
children = (
141FC1201B222EBB004D5FFB /* IntegrationTestsTests.m */,
143BC5A01B21E45C00462512 /* UIExplorerIntegrationTests.m */,
141FC1201B222EBB004D5FFB /* IntegrationTests.m */,
143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */,
83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */,
143BC5971B21E3E100462512 /* Supporting Files */,
);
path = UIExplorerIntegrationTests;
@@ -772,14 +796,21 @@
buildActionMask = 2147483647;
files = (
1497CFB01B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m in Sources */,
144D21241B2204C5006DB32B /* RCTClippingTests.m in Sources */,
144D21241B2204C5006DB32B /* RCTImageUtilTests.m in Sources */,
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.m in Sources */,
1497CFB21B21F5E400C1F8F2 /* RCTSparseArrayTests.m in Sources */,
1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */,
1497CFAF1B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m in Sources */,
1497CFAE1B21F5E400C1F8F2 /* RCTContextExecutorTests.m in Sources */,
1497CFAD1B21F5E400C1F8F2 /* RCTBridgeTests.m in Sources */,
1497CFB11B21F5E400C1F8F2 /* RCTEventDispatcherTests.m in Sources */,
1497CFB31B21F5E400C1F8F2 /* RCTUIManagerTests.m in Sources */,
138D6A171B53CD440074A87E /* RCTCacheTests.m in Sources */,
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */,
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */,
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */,
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */,
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -796,8 +827,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
141FC1211B222EBB004D5FFB /* IntegrationTestsTests.m in Sources */,
143BC5A11B21E45C00462512 /* UIExplorerIntegrationTests.m in Sources */,
141FC1211B222EBB004D5FFB /* IntegrationTests.m in Sources */,
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */,
143BC5A11B21E45C00462512 /* UIExplorerSnapshotTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1014,9 +1046,11 @@
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
@@ -1028,6 +1062,7 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
"$(SRCROOT)/../../Libraries/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
@@ -1068,9 +1103,11 @@
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
@@ -1082,6 +1119,7 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
"$(SRCROOT)/../../Libraries/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
+58 -37
View File
@@ -14,56 +14,77 @@
#import "AppDelegate.h"
#import "RCTBridge.h"
#import "RCTJavaScriptLoader.h"
#import "RCTRootView.h"
@interface AppDelegate() <RCTBridgeDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self
launchOptions:launchOptions];
/**
* Loading JavaScript code - uncomment the one you want.
*
* OPTION 1
* Load from development server. Start the server from the repository root:
*
* $ npm start
*
* To run on device, change `localhost` to the IP address of your computer
* (you can get this by typing `ifconfig` into the terminal and selecting the
* `inet` value under `en0:`) and make sure your computer and iOS device are
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.includeRequire.runModule.bundle?dev=true"];
/**
* OPTION 2
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
* to your Xcode project folder and run
*
* $ curl 'http://localhost:8081/Examples/UIExplorer/UIExplorerApp.includeRequire.runModule.bundle' -o main.jsbundle
*
* then add the `main.jsbundle` file to your project and uncomment this line:
*/
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#if RUNNING_ON_CI
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"UIExplorerApp"
launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"UIExplorerApp"
initialProperties:nil];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [[UIViewController alloc] init];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge
{
NSURL *sourceURL;
/**
* Loading JavaScript code - uncomment the one you want.
*
* OPTION 1
* Load from development server. Start the server from the repository root:
*
* $ npm start
*
* To run on device, change `localhost` to the IP address of your computer
* (you can get this by typing `ifconfig` into the terminal and selecting the
* `inet` value under `en0:`) and make sure your computer and iOS device are
* on the same Wi-Fi network.
*/
sourceURL = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.includeRequire.runModule.bundle?dev=true"];
/**
* OPTION 2
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
* to your Xcode project folder and run
*
* $ curl 'http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.includeRequire.runModule.bundle' -o main.jsbundle
*
* then add the `main.jsbundle` file to your project and uncomment this line:
*/
// sourceURL = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#if RUNNING_ON_CI
sourceURL = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
return sourceURL;
}
- (void)loadSourceForBridge:(RCTBridge *)bridge
withBlock:(RCTSourceLoadBlock)loadCallback
{
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge]
onComplete:loadCallback];
}
@end
@@ -0,0 +1,13 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "uie_thumb_big.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

+31 -22
View File
@@ -17,33 +17,43 @@
'use strict';
var React = require('react-native');
var Dimensions = require('Dimensions');
var DrawerLayoutAndroid = require('DrawerLayoutAndroid');
var ToolbarAndroid = require('ToolbarAndroid');
var UIExplorerList = require('./UIExplorerList');
var {
AppRegistry,
BackAndroid,
Dimensions,
DrawerLayoutAndroid,
StyleSheet,
ToolbarAndroid,
View,
} = React;
var UIExplorerList = require('./UIExplorerList.android');
var DRAWER_WIDTH_LEFT = 56;
var UIExplorerApp = React.createClass({
getInitialState: function() {
return {
example: {
title: 'UIExplorer',
component: this._renderHome(),
},
example: this._getUIExplorerHome(),
};
},
_getUIExplorerHome: function() {
return {
title: 'UIExplorer',
component: this._renderHome(),
};
},
componentWillMount: function() {
BackAndroid.addEventListener('hardwareBackPress', this._handleBackButtonPress);
},
render: function() {
return (
<DrawerLayoutAndroid
drawerPosition={DrawerLayoutAndroid.positions.Left}
drawerWidth={Dimensions.get('window').width - DRAWER_WIDTH_LEFT}
keyboardDismissMode="on-drag"
ref={(drawer) => { this.drawer = drawer; }}
renderNavigationView={this._renderNavigationView}>
{this._renderNavigation()}
@@ -62,14 +72,11 @@ var UIExplorerApp = React.createClass({
onSelectExample: function(example) {
this.drawer.closeDrawer();
if (example.title === 'UIExplorer') {
example.component = this._renderHome();
if (example.title === this._getUIExplorerHome().title) {
example = this._getUIExplorerHome();
}
this.setState({
example: {
title: example.title,
component: example.component,
},
example: example,
});
},
@@ -103,16 +110,16 @@ var UIExplorerApp = React.createClass({
);
},
_handleBackButtonPress: function() {
if (this.state.example.title !== this._getUIExplorerHome().title) {
this.onSelectExample(this._getUIExplorerHome());
return true;
}
return false;
},
});
var styles = StyleSheet.create({
messageText: {
fontSize: 17,
fontWeight: '500',
padding: 15,
marginTop: 50,
marginLeft: 15,
},
container: {
flex: 1,
},
@@ -122,4 +129,6 @@ var styles = StyleSheet.create({
},
});
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
module.exports = UIExplorerApp;
+18 -17
View File
@@ -17,7 +17,7 @@
'use strict';
var React = require('react-native');
var UIExplorerList = require('./UIExplorerList');
var UIExplorerList = require('./UIExplorerList.ios');
var {
AppRegistry,
NavigatorIOS,
@@ -43,22 +43,23 @@ var UIExplorerApp = React.createClass({
/>
);
}
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
title: 'UIExplorer',
component: UIExplorerList,
passProps: {
onExternalExampleRequested: (example) => {
this.setState({ openExternalExample: example, });
},
}
}}
itemWrapperStyle={styles.itemWrapper}
tintColor="#008888"
/>
);
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
title: 'UIExplorer',
component: UIExplorerList,
passProps: {
onExternalExampleRequested: (example) => {
this.setState({ openExternalExample: example, });
},
}
}}
itemWrapperStyle={styles.itemWrapper}
tintColor="#008888"
/>
);
}
});
@@ -14,11 +14,11 @@
#import "RCTAssert.h"
@interface IntegrationTestsTests : XCTestCase
@interface IntegrationTests : XCTestCase
@end
@implementation IntegrationTestsTests
@implementation IntegrationTests
{
RCTTestRunner *_runner;
}
@@ -26,12 +26,12 @@
- (void)setUp
{
#if __LP64__
RCTAssert(false, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
RCTAssert(NO, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
#endif
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
RCTAssert(version.majorVersion == 8 || version.minorVersion == 3, @"Tests should be run on iOS 8.3, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp");
NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion;
RCTAssert(version.majorVersion == 8 || version.minorVersion >= 3, @"Tests should be run on iOS 8.3+, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp", nil);
}
#pragma mark Logic Tests

Some files were not shown because too many files have changed in this diff Show More