From 7ac931ee9b5e06ef1935d18e5b6a1e282db16c56 Mon Sep 17 00:00:00 2001 From: Joel Marcey Date: Wed, 29 Jun 2016 03:25:02 -0700 Subject: [PATCH] Publish DocDown Commits Into Next Release (0.29) (#8480) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Separate Out Core Components Into Individual Parts Summary: Will create new issue to add more information to the `Components` section of the Tutorial since that was gutted by this change. Fixes #8156 Closes https://github.com/facebook/react-native/pull/8256 Differential Revision: D3459601 Pulled By: JoelMarcey fbshipit-source-id: 4038afc463bffcf8efda36d29bc7c443bbc8f4bd * Cleanup troubleshooting and debugging docs. Summary: This is a followup to #8010. Troubleshooting has been updated to list only those issues that may affect a user that is setting up their environment. Any issues related to day to day use have been moved or merged into a more relevant doc. Closes https://github.com/facebook/react-native/pull/8254 Reviewed By: caabernathy Differential Revision: D3459018 Pulled By: JoelMarcey fbshipit-source-id: dd76097af34bd33dda376fab39fb0f71061ef3e4 * Remove survey link Summary: We have enough responses now and we are in the lockdown for improving the documentation. We can add another "did we improve?" survey after lockdown sometime. Closes https://github.com/facebook/react-native/pull/8260 Differential Revision: D3463284 Pulled By: JoelMarcey fbshipit-source-id: f2d585a8aa6308de0cce0bea3974b1e7f14d5a6f * Add docs to show how to select specific simulator. Summary: Add a message to let people know they can use the `--simulator` flag to run their apps on different simulators instead of the default "iPhone 6" Closes https://github.com/facebook/react-native/pull/8078 Differential Revision: D3464912 Pulled By: JoelMarcey fbshipit-source-id: b59d5061d2b3501618602932fcc285bac99b7573 * Add ScrollView to Basics docs Summary: Add basic information about the generic `ScrollView` -- talk a bit about how it renders elements and a quick compare against something like a `ListView`. Provide a simple example. Fixes #8261 Closes https://github.com/facebook/react-native/pull/8266 Differential Revision: D3465105 Pulled By: JoelMarcey fbshipit-source-id: 3a2e1eac6e877669763fc6b8bb0fc78ebe870ab1 * Improve autogen for reference docs including jsdoc support Summary: As part of improving the API and Component reference docs #8154 this pull request adds the following: - jsdoc support for API docs. See the AlertIOS changes as an example. - type definitions support and added to both API and Component docs. This is supported via react-docgen and jsdoc. - better formatting of method properties (now shown in a table). FYI, API and Component docs were previously generated in two different ways. Components were using react-docgen and that basically remains as-is. APIs were using custom parsing code and that's been switched to use a jsdoc parser + react-docgen as an option for typedefs (it could also use the jsdoc parser). Two docs have been updated to showcase how we'd like the new docs to look: - AlertIOS (API): showing method parameters, examples, typedefs, more details overall. - Statusbar (Component): showing method parameters, typedefs, more details overall. **Note**: To convert new API docs to use the new format, add `jsdoc` to the initial file comment. C Closes https://github.com/facebook/react-native/pull/8196 Differential Revision: D3465037 Pulled By: lacker fbshipit-source-id: 78415d44bc5be02db802f5b1f7a0b249689abdf7 * overhaul showcase Summary: The motivation is that the showcase is becoming far too large to be useful. I filtered the apps for, basically, "apps that have some sort of interesting news coverage or technical blog post about them". The UI is a bit updated to also mention something about the information link. I also added the FB app itself. Closes https://github.com/facebook/react-native/pull/8263 Differential Revision: D3463856 Pulled By: JoelMarcey fbshipit-source-id: cdd309ba85edca417868f14dee7c772f73af654b * New React Native Landing Page Summary: The motivation is that we haven't changed the copy on the initial React Native landing page since launching, and we have a much clearer view of the React Native value prop now. Themes: 1. React Native is like React but for mobile apps 2. A React Native app is a "real native app" 3. Development is fast 4. You can drop down to normal native development if you need Closes https://github.com/facebook/react-native/pull/8291 Differential Revision: D3466855 Pulled By: JoelMarcey fbshipit-source-id: d1a5035640bcd795704d5f830b79e7c3d2e3ab02 * Move Videos and Newsletter to Support Summary: Simplify the sidebar. We have Twitter feed in support. These have a community feel as well. Closes https://github.com/facebook/react-native/pull/8287 Differential Revision: D3467042 Pulled By: lacker fbshipit-source-id: 60749d0cb31f284dae7c5402bfcde7b4d01aa32f * Include info about console.log Summary: I spent so much time trying to optimize my JS without noticing this. Closes https://github.com/facebook/react-native/pull/8285 Differential Revision: D3468707 fbshipit-source-id: bd5ff38ca2501891318b4be3c75bdaa10a4c64da * Add a new Handling Touches guide Summary: The new Handling Touches guide provides an overall view of how touches can be handled. It is meant to be a higher level discussion of basic touch handling, e.g. "how do I implement a button?". The existing Gesture Responder System guide has been moved to the end of the docs and is still available for reference when building custom gesture handlers. Reference: #8160 ![handlingtouchesguide](https://cloud.githubusercontent.com/assets/165856/16256634/50a20c92-3808-11e6-8a5b-b49f2cda9fca.png) Closes https://github.com/facebook/react-native/pull/8299 Differential Revision: D3469681 Pulled By: JoelMarcey fbshipit-source-id: 3bc18e759b26c2d5c141b626acb433c5e973cef0 * Remove Polyfills section from sidebar Summary: Some of these will be in basics, guides and apis instead. One less layer of confusion. > Note: APIs are not totally alphabetical any longer -- but neither were Polyfills. We can fix that in `extractDocs.js` maybe. But not worth doing in this pull request, imho. Closes https://github.com/facebook/react-native/pull/8293 Differential Revision: D3469684 Pulled By: JoelMarcey fbshipit-source-id: 4f7830ca10b8e4406df9cec8bf13ff150e355250 * Docs: Basic Components Update Summary: This is an improvement to basic components docs. * I updated the basic components example code to better render components on iOS (added paddingTop). * I also modified the code to allow reader to easily copy, paste, and then run the code in their project if they followed the 'Getting Started' quick start guide. * I also added additional copy to clarify suggested usage/guidelines. Closes https://github.com/facebook/react-native/pull/8292 Differential Revision: D3469943 Pulled By: JoelMarcey fbshipit-source-id: 21ff6ee13b59741c43d80aab68a38aace0fbfca6 * Add react-native-web-player to core components docs Summary: This PR adds the interactive [React Native Web Player](http://dabbott.github.io/react-native-web-player/) to the docs. The web player is an embeddable iframe which runs React Native code using components from [react-native-web](https://github.com/necolas/react-native-web). For now, it's primarily for educational purposes, since only the basic components are implemented. Some details: - The iframe is loaded from MaxCDN using rawgit, locked down to a git tag. - Asset paths (i.e. images) are resolved relative to `//facebook.github.io/react-native/` - When viewed on mobile, it falls back to the syntax-highlighted code blocks. The WebPlayer can be inserted into markdown by using the fences: ``` ```ReactNativeWebPlayer import ... AppRegistry.registerComponent ... `` ` ``` ![screen shot 2016-06-22 at 12 46 50 pm](https://cloud.githubusercontent.com/assets/1198882/16281068/7056804e-3877-11e6-82f7-ece245690548.png) I didn't actually add the WebPlayer to any docs pages in this PR. That we c Closes https://github.com/facebook/react-native/pull/8328 Differential Revision: D3471527 Pulled By: lacker fbshipit-source-id: 704da41cd77e08c7e2bc820557a74d36e88e8eb7 * More Resources doc, updating Support doc and quickstart too Summary: TLDR even more docs changes So I created a More Resources doc that aggregates the high-quality-but-off-site stuff. Let's try to put more outlinks there. Also I removed the stuff on Support that was not support, and some misc changes to clean stuff up. Closes https://github.com/facebook/react-native/pull/8329 Differential Revision: D3471669 Pulled By: JoelMarcey fbshipit-source-id: 54edd543ced1b3a8f3d0baca5475ac96bae6e487 * Add React Native Web Player to most component basics Summary: > ListView is not supported by React Native Web as of yet, so it will not have it. Closes https://github.com/facebook/react-native/pull/8331 Differential Revision: D3472019 Pulled By: lacker fbshipit-source-id: e5fb430b6c8f4d437943c159beb00b9d9252c92d * Update Navigator component doc Summary: Related to #8203 to update the Navigator component reference doc. **Test plan (required)** Started up the website and checked: http://localhost:8079/react-native/docs/navigator.html ![component_navigator_2](https://cloud.githubusercontent.com/assets/691109/16280426/3f2cdc32-3874-11e6-810b-ca34d7bd4972.png) **Note** The code is not Flow-ified so depended on jsdoc formatting to get the method parameter types. There's a current issue with handling optional types via react-docgen which parses components. There's an open PR to look into this: https://github.com/reactjs/react-docgen/pull/89. When that's resolved the `replaceAtIndex` method parameter type that's documented for `cb` needs to be updated to make it optional. Closes https://github.com/facebook/react-native/pull/8318 Differential Revision: D3471185 Pulled By: JoelMarcey fbshipit-source-id: 99f85ee2ab00dc200cf2812cce5b3ccec743d6a0 * fix Firefox bug Summary: The motivation is that the getting started page was not working in some cases in Firefox. This line of code appears to be at best a no-op, at worst fails in Firefox, since "event" is undefined. Closes https://github.com/facebook/react-native/pull/8335 Differential Revision: D3473333 Pulled By: JoelMarcey fbshipit-source-id: 40581e83126675aa072c6ee25609cfb787015ce7 * Fix guides docs to es2015 classes and remove flowtype from Animation example Summary: 1. Animation guide page is the only place where Flowtype is used, it would be better to remove it to prevent some confusion. 2. ES2015 classes in guidelines docs pages and fixed some typos **Test plan (required)** Should i write any tests for this? Closes https://github.com/facebook/react-native/pull/8339 Differential Revision: D3474192 Pulled By: bestander fbshipit-source-id: 5531d1e399eaed0952732ac2e0bd1effc72d00a8 * Update Views API documentation Summary: Ensure all `props` have documentation. Add more details to current `props`. Provide more information to the API in general. > Would like to try to integrate the React Native Web Player for the initial > example, but not right now. Closes https://github.com/facebook/react-native/pull/8341 Differential Revision: D3475105 Pulled By: caabernathy fbshipit-source-id: 00ad30b2359831740715517278bec1d0231e089d * Fixes #8252: Document how to connect to a non-default packager port o… Summary: Added some documentation to the `RunningOnDeviceAndroid.md` with screenshots to set custom port Closes https://github.com/facebook/react-native/pull/8355 Differential Revision: D3475846 Pulled By: mkonicek fbshipit-source-id: 73675b19e2bb93c859bda239f228da0883f0e305 * Add docs pages for basics: Dimensions and Layout Summary: These pages should sufficiently give a beginner enough information to make most layouts in React Native. They should go after the basics-style page, whenever that is ready. Having a single page for Layout was too much, so I split it into two: Dimensions and Layout. ![dimensions react native a framework for building native apps using react](https://cloud.githubusercontent.com/assets/1198882/16311045/c6918b64-3923-11e6-8cc9-daeda9eb40e6.png) ![layout react native a framework for building native apps using react](https://cloud.githubusercontent.com/assets/1198882/16310233/9a66405a-3920-11e6-9ef6-1594f7228e83.png) lacker Closes https://github.com/facebook/react-native/pull/8364 Differential Revision: D3477147 Pulled By: lacker fbshipit-source-id: 1ef31ac0a64e43166a7581b38fa8263282672eeb * ES6-ify ListView Basics Summary: Fixes #8184 Closes https://github.com/facebook/react-native/pull/8370 Differential Revision: D3477196 Pulled By: caabernathy fbshipit-source-id: 929f84b3f8edaf03f918bb04fb9dbb48b4884b18 * Fix nits in update View API documentation Summary: Ref comments in #8341 Ref #8203 Closes https://github.com/facebook/react-native/pull/8361 Differential Revision: D3477174 Pulled By: caabernathy fbshipit-source-id: 495011c2d370d06d355e966d6ba2c52880146183 * ES6-ify ScrollView basics Summary: Closes https://github.com/facebook/react-native/pull/8368 Differential Revision: D3477381 Pulled By: caabernathy fbshipit-source-id: 0c43a9b8309db8f268a2776ebff2b4e52df559df * ES6-ify View Basics Summary: Closes https://github.com/facebook/react-native/pull/8366 Differential Revision: D3477409 Pulled By: caabernathy fbshipit-source-id: 5906e8dffc7884a6ed527fada5f907702a72c08f * ES6-ify Image Basics Summary: Closes https://github.com/facebook/react-native/pull/8365 Differential Revision: D3477411 Pulled By: caabernathy fbshipit-source-id: 26214fcf13c9e1352e198f34fcd6f5e88f1fe2da * ES6-ify TextInput Basics Summary: Closes https://github.com/facebook/react-native/pull/8367 Differential Revision: D3477404 Pulled By: caabernathy fbshipit-source-id: 16c279853b5c7a2d24033ef0d987da52dd148b24 * ES6-ify Text Basics Summary: Closes https://github.com/facebook/react-native/pull/8363 Differential Revision: D3477431 Pulled By: caabernathy fbshipit-source-id: 86ee5efb84e50609fbfae82102b1dc61fea69f05 * Update NavigatorIOS component doc Summary: Reference: #8203 Changes made: - Added more to the intro section and updated the intro examples to ES6 - Added more details to prop explanations - Added parameter descriptions for methods **Test plan (required)** Ran the website locally and checked: http://localhost:8079/react-native/docs/navigatorios.html ![component_navigatorios_2](https://cloud.githubusercontent.com/assets/691109/16315939/1501ba2a-3939-11e6-8ec0-54b43e03b323.png) Closes https://github.com/facebook/react-native/pull/8334 Differential Revision: D3476066 Pulled By: JoelMarcey fbshipit-source-id: 9fcefe3f9d59008d8c72683c57cb004d1f185f62 * Update webview doc Summary: Reference: #8203 Changes made: Added a webview example to the intro section Added more details to prop explanations Test plan (required) Ran the website locally and checked: http://localhost:8079/react-native/docs/webview.html ![component_webview_2](https://cloud.githubusercontent.com/assets/691109/16316552/f6847c56-393b-11e6-8fdd-a0b61e7f787b.png) Closes https://github.com/facebook/react-native/pull/8372 Differential Revision: D3477685 Pulled By: JoelMarcey fbshipit-source-id: a624f5c6c12a8367aea2a6e7c2e520da7a074bbd * Move everything out of Known Issues and into more appropriate locations. Summary: Two of the known issues have been moved to the issue tracker: * #8315 * #8316 Others have been moved into more appropriate locations, such as the `TextInput` issue to the API doc itself, and the React debugging issue to the Debugging doc. The Android-specific compatibility concerns have been dropped entirely as it does not seem like people would find these in the docs. Closes https://github.com/facebook/react-native/pull/8321 Differential Revision: D3477999 Pulled By: JoelMarcey fbshipit-source-id: dfffc9910ebf5514eb14c6aa8a9a3e70761db874 * Make a new "Style" doc that's in The Basics and uses the RNWP Summary: The example uses StyleSheet.create and also arrays-of-styles. I think this covers everything the old one did, but in simple-enough-for-the-basics form, so I removed the old one. I also reordered so that "Style -> Dimensions -> Layout" is the flow for learning "Styley" things. Closes https://github.com/facebook/react-native/pull/8379 Differential Revision: D3478384 Pulled By: caabernathy fbshipit-source-id: 158f0f0367c8eb8b2b24feda0d8d7a533fd7af4d * Add `extends Component` to Dimensions and Layout Basics Examples Summary: It works without out the `extends`, but I do not really understand why, unless there is some magic implicit `extends` if you don't put it and you call `registerComponent`. But, I figure we should be explicit unless there is a good reason not to be. Closes https://github.com/facebook/react-native/pull/8377 Differential Revision: D3478950 Pulled By: JoelMarcey fbshipit-source-id: 05ea4367c3c8c34aea6c092639ee51d8761bca3f * Bring out prop descriptions, for Flexbox Summary: For Flexbox API docs would like to tease out the prop descriptions. This PR makes that feasible by exposing the description for style. **Test plan (required)** 1. Temporarily modified the flexbox source doc: Libraries/StyleSheet/LayoutPropTypes.js to add a description. 2. Checked it out on local webpage: http://localhost:8079/react-native/docs/flexbox.html ![style_prop_descriptions](https://cloud.githubusercontent.com/assets/691109/16321579/866b186e-3952-11e6-823a-2d38132bd553.png) Closes https://github.com/facebook/react-native/pull/8382 Differential Revision: D3478796 Pulled By: lacker fbshipit-source-id: 49f3b7876ff1ccec9ee837921a78ee0dfb915453 * Update web player in docs for custom registerComponent names Summary: In the web player in the docs, allows `AppRegistry.registerComponent('name', App)` to use *anything* for `'name'`. It is ignored by the web player - last registration wins. Closes https://github.com/facebook/react-native/pull/8383 Differential Revision: D3478922 Pulled By: JoelMarcey fbshipit-source-id: 3d1d96e0ad41216d29134ba384896e86d0cd2b32 * Networking Guide Summary: Simplified Networking Guide, based on the old Network polyfill doc. This guide strongly recommends using fetch, while still informing the user about React Native's support for other libraries. In order to provide an actual working networking example, a `movies.json` file is added at the root of the site, allowing the user to fetch a small blob of JSON: ``` fetch('http://facebook.github.io/react-native/movies.json') ``` ![networking](https://cloud.githubusercontent.com/assets/165856/16321804/d2bd7c6a-3953-11e6-9fc5-30baaa38d7a4.png) Closes https://github.com/facebook/react-native/pull/8381 Differential Revision: D3479018 Pulled By: lacker fbshipit-source-id: 1f2078bf2414a13f7f77d5af55b08948909093a3 * Move Component Embedded Simulator next to its example Summary: Right now the embedded simulator is always at the top right corner. This can be confusing as to what code is associated with the simulation. So, move the simulator next to its actual code. This has the added benefit of allowing us to use the React Native Web Player for the simpler examples in the components. Closes https://github.com/facebook/react-native/pull/8384 Differential Revision: D3479056 Pulled By: bestander fbshipit-source-id: f400d8387ec771b94d5e798c1e955b25f9a0f1bf * fix bugs on landing page code, make the url an easter egg Summary: This is just improving a bit of lameness on the homepage - Devin pointed out the <>'s don't work within a Text tag, so I removed them, and someone else pointed out that nonexistent fake urls are suboptimal, so I improved that too. Closes https://github.com/facebook/react-native/pull/8387 Differential Revision: D3479087 Pulled By: JoelMarcey fbshipit-source-id: 45a2d21a9073b58b869e8b344550c28f849e0185 * Api documentation update for modal.js Summary: Related to #8203 to update the Modal API reference doc. **Test plan (required)** Started up the website and checked: http://localhost:8079/react-native/docs/modal.html ![modal update](https://cloud.githubusercontent.com/assets/23874/16316792/ecde19cc-393c-11e6-8136-16243a199d9b.png) **Note, copied from a previous PR** The code is not Flow-ified so depended on jsdoc formatting to get the method parameter types. There's a current issue with handling optional types via react-docgen which parses components. There's an open PR to look into this: https://github.com/reactjs/react-docgen/pull/89. When that's resolved the `replaceAtIndex` method parameter type that's documented for `cb` needs to be updated to make it optional. Closes https://github.com/facebook/react-native/pull/8375 Differential Revision: D3479536 Pulled By: caabernathy fbshipit-source-id: de2db3aa221e4adce0c0c5f3d94a1fad528a60da * Update MapView doc Summary: Reference: #8203 Changes made: - Added a MapView example to the intro section - Added more details to prop explanations - Added more info to an exported type, even if it's not used anywhere I can see - Removed mention of ios platform in props. Left an android one in there as I didn't want to touch code. **Test plan (required)** Ran the website locally and checked: http://localhost:8079/react-native/docs/mapview.html ![component_mapview_2](https://cloud.githubusercontent.com/assets/691109/16329753/43419508-3999-11e6-9310-11c53ca8c04b.png) Closes https://github.com/facebook/react-native/pull/8389 Differential Revision: D3481609 Pulled By: JoelMarcey fbshipit-source-id: 71e35ce49193dc09d40546ff16bc48559135d63f * Accessing console logs Summary: Instructions for accessing the output of a `console.log`. ![debugging](https://cloud.githubusercontent.com/assets/165856/16318119/7aff884e-3942-11e6-9a78-853aaba68308.png) Closes https://github.com/facebook/react-native/pull/8323 Differential Revision: D3480718 Pulled By: JoelMarcey fbshipit-source-id: 4185d2e730277b8ad986d3c8904420e7ae1ceb21 * Add Navigation Overview Summary: Initial stab at writing a high level guide on navigation. Its main focus is on Navigator due to it being cross-platform and fairly simple to use. This guide should be expanded to cover tabbed applications in a future pull request. The Navigation (Experimental) section will be similarly expanded upon as the API stabilizes. ![navigation](https://cloud.githubusercontent.com/assets/165856/16324560/52b508dc-396a-11e6-94b7-b2d1175f69e0.png) Closes https://github.com/facebook/react-native/pull/8390 Differential Revision: D3480304 Pulled By: caabernathy fbshipit-source-id: 280da9185fca295bc107a2df20106c783b461be7 * Update AsyncStorage doc Summary: Relates to #8203 for AsyncStorage API update. - Added a small example to the intro section. - Added jsdoc format tags to show up class description, parameter descriptions. - Word-smithed many of the method descriptions. I also made a bug fix to the autogen. It wasn't handling the scenario where a method may have no parameters. **Test plan (required)** Wrote a small sample app to test the snippet added to the intro section. Ran website locally: http://localhost:8079/react-native/docs/asyncstorage.html ![api_asyncstorage](https://cloud.githubusercontent.com/assets/691109/16329457/84f9d69c-3997-11e6-9e68-3a475df90377.png) Ran changed files through the linter. Closes https://github.com/facebook/react-native/pull/8396 Differential Revision: D3481783 Pulled By: JoelMarcey fbshipit-source-id: ebc4b9695482ada8a3455e621534d2a7fb11edf4 * Fix errors related to typehint when generating docs Summary: After pulling in AsyncStorage doc changes, getting typehint errors when running docs. This fixes that issue. **Test plan (required)** Opened http://localhost:8079/react-native/index.html Clicked around. No errors. Also successfully ran: ``` node server/generate.js ``` Closes https://github.com/facebook/react-native/pull/8412 Differential Revision: D3482007 Pulled By: JoelMarcey fbshipit-source-id: 7b0da2b2b38fd1f1bdec1b7c810ee70c536dd2bb * Update Image API Summary: - Provide runnable examples - Add more details to properties and jsdoc-ify the methods Ref #8203 Closes https://github.com/facebook/react-native/pull/8413 Differential Revision: D3482168 Pulled By: caabernathy fbshipit-source-id: 04fce5133317af282cced5850a53858e3f5b72f2 * Replace NavigatorComparison with the new Navigation guide. Summary: Several external sites link back to docs/navigator-comparison.html when talking about React Native's navigation. The Navigation guide added in #8390 is meant to replace this content, but it was added at docs/navigation.html. This pull request removes the comparison guide and replaces it with the Navigation guide's content. There is no content update in this PR. For review purposes, note that the next link from the previous document (JS Environment) has been updated to point to navigator-comparison, and the content of the Navigation guide remain unchanged from #8390. Closes https://github.com/facebook/react-native/pull/8417 Differential Revision: D3482273 Pulled By: caabernathy fbshipit-source-id: 9e04e11a5829d48541f8612fb65c01fe319e768b * Overhaul the Flexbox documentation Summary: Closes https://github.com/facebook/react-native/pull/8395 Differential Revision: D3482652 Pulled By: lacker fbshipit-source-id: 0bf8955341221b74f69ba24dcf5ab332c910a52c * Update TextInput API Summary: - Make the examples runnable (both copy/paste and with the web player) - Add a bit more information in props where needed. Closes https://github.com/facebook/react-native/pull/8392 Differential Revision: D3482747 Pulled By: caabernathy fbshipit-source-id: 8f2d812efc1efb3f14db45b5c054ce0d5c14f5f5 * Make "The Basics" flow like a linear tutorial Summary: Closes https://github.com/facebook/react-native/pull/8429 Differential Revision: D3487369 Pulled By: lacker fbshipit-source-id: 59b32f2a2a67370192c91dc43da3d4b76a43b810 * map -> object Summary: Closes https://github.com/facebook/react-native/pull/8450 Differential Revision: D3488018 fbshipit-source-id: a30269c89e87b546f77da7a32b1c4c65d978459d * Make the method signatures stand out more Summary: And more delineated from other parts of the method information. Hopefully this makes it easier to parse through. Closes https://github.com/facebook/react-native/pull/8421 Differential Revision: D3488251 Pulled By: JoelMarcey fbshipit-source-id: 44f2ed00b16849396cac94fd46567eaab48c50f3 * Use npmcdn in docs instead of rawgit for web player Summary: Switch web player cdn to npmcdn per discussion with lacker. This will make the url agnostic to who owns the git repo. Closes https://github.com/facebook/react-native/pull/8426 Differential Revision: D3488755 Pulled By: lacker fbshipit-source-id: b54dd4428a48c8a5a15b0b38ee0564d119916f9b * Update instructions for pointing Gradle to Android SDK Summary: Closes #8439 Closes https://github.com/facebook/react-native/pull/8446 Differential Revision: D3489034 fbshipit-source-id: 7cb50a43e64e216512294eaec06690dc9f3d6895 * Update RunningOnDeviceAndroid.md Summary: Add note associating error message to "adb reverse" command. When I first ran a React Native app on my Android phone, I received a cryptic "bridge configuration isn't available" error. After some research, I discovered that the "adb reverse" command mentioned further down on the page resolved the problem. Closes https://github.com/facebook/react-native/pull/7725 Differential Revision: D3491577 Pulled By: JoelMarcey fbshipit-source-id: 34c580acd6bf3e7788b674bd0b41bc5a1023b010 * improve text input docs Summary: Not a big deal, I was just going through the tutorial trying to figure out which doc was the most boring, and improve it a bit. IMO now the example is slightly funnier, and it mentions onSubmitEditing which in practice is probably a more useful callback. Closes https://github.com/facebook/react-native/pull/8447 Differential Revision: D3491938 Pulled By: JoelMarcey fbshipit-source-id: 3bd0f5762dc4db4a85c9d5badb6c005f4b8c52f4 * Update Text Component Summary: This updates the documentation for the `Text` component itself and the embedded `Text.md` that goes with it. - React Native Web Player - Document all props - NOTE: I actually added a new prop to `Text` called `accessible` since it was set by default and thus shown in the Props list in the original documentation (but with an empty description). - Stylistic fixes Closes https://github.com/facebook/react-native/pull/8445 Differential Revision: D3493112 Pulled By: JoelMarcey fbshipit-source-id: b428d4eb09065db5c6cb1ae5524ad22084fd2a82 * Fix TextInput API update nits Summary: Ref: https://github.com/facebook/react-native/pull/8392/files/7e7c2b5d57afe451dc5b6ede6b419819e3ac7fbd#r68444537 Ref: https://github.com/facebook/react-native/pull/8392/files/7e7c2b5d57afe451dc5b6ede6b419819e3ac7fbd#r68444442 Closes https://github.com/facebook/react-native/pull/8476 Differential Revision: D3494641 Pulled By: JoelMarcey fbshipit-source-id: 9a75ff66ccb895deb2f5027bdffe5d5bfe898e41 --- Libraries/Components/MapView/MapView.js | 89 +- .../Components/Navigation/NavigatorIOS.ios.js | 310 +++-- Libraries/Components/StatusBar/StatusBar.js | 46 + Libraries/Components/TextInput/TextInput.js | 220 ++- Libraries/Components/View/View.js | 271 +++- Libraries/Components/WebView/WebView.ios.js | 113 +- .../CustomComponents/Navigator/Navigator.js | 242 +++- Libraries/Image/Image.ios.js | 140 +- Libraries/Modal/Modal.js | 90 +- Libraries/Storage/AsyncStorage.js | 191 ++- Libraries/StyleSheet/LayoutPropTypes.js | 273 +++- Libraries/Text/Text.js | 103 +- Libraries/Utilities/AlertIOS.js | 146 +- docs/Accessibility.md | 2 +- docs/AndroidBuildingFromSource.md | 18 +- docs/Animations.md | 8 +- docs/Colors.md | 3 +- docs/Debugging.md | 80 +- docs/DirectManipulation.md | 40 +- docs/GestureResponderSystem.md | 2 +- ...rt-GettingStarted.md => GettingStarted.md} | 136 +- docs/HandlingTextInput.md | 49 + docs/HandlingTouches.md | 66 + docs/HeightAndWidth.md | 65 + docs/Images.md | 2 +- ...Apps.md => IntegrationWithExistingApps.md} | 8 +- docs/KnownIssues.md | 90 -- docs/LayoutWithFlexbox.md | 106 ++ docs/MoreResources.md | 48 + docs/NativeComponentsAndroid.md | 3 +- docs/NativeModulesIOS.md | 2 +- docs/NavigatorComparison.md | 186 ++- docs/Network.md | 155 --- docs/Networking.md | 129 ++ docs/Newsletter.md | 8 - docs/Performance.md | 4 + docs/PlatformSpecificInformation.md | 13 +- docs/Props.md | 72 + docs/RunningOnDeviceAndroid.md | 18 +- docs/RunningOnDeviceIOS.md | 47 +- docs/RunningOnSimulatorIOS.md | 18 + docs/SampleApplication-F8App.md | 8 - docs/SampleApplication-Movies.md | 504 ------- docs/State.md | 59 + docs/Style.md | 114 +- docs/Text.md | 50 +- docs/Timers.md | 4 +- docs/Troubleshooting.md | 93 +- docs/Tutorial-CoreComponents.md | 142 -- docs/Tutorial.md | 53 + docs/UsingAListView.md | 51 + docs/UsingAScrollView.md | 64 + docs/Videos.md | 67 - website/core/Marked.js | 12 +- website/core/WebPlayer.js | 68 + website/jsdocs/jsdoc-conf.json | 15 + website/jsdocs/jsdoc-plugin-values.js | 11 + website/layout/AutodocsLayout.js | 355 ++++- website/layout/DocsLayout.js | 9 - website/package.json | 12 +- website/server/docgenHelpers.js | 141 +- website/server/extractDocs.js | 271 +++- website/src/react-native/css/react-native.css | 176 ++- .../img/AndroidDevServerDialog.png | Bin 0 -> 142925 bytes .../react-native/img/AndroidDevSettings.png | Bin 0 -> 197019 bytes .../react-native/img/AndroidDeveloperMenu.png | Bin 0 -> 82306 bytes .../src/react-native/img/DeveloperMenu.png | Bin 0 -> 49640 bytes website/src/react-native/img/survey.png | Bin 20708 -> 0 bytes website/src/react-native/index.js | 396 +----- website/src/react-native/js/scripts.js | 21 +- website/src/react-native/movies.json | 11 + website/src/react-native/showcase.js | 1187 ++--------------- website/src/react-native/support.js | 32 +- 73 files changed, 4104 insertions(+), 3434 deletions(-) rename docs/{QuickStart-GettingStarted.md => GettingStarted.md} (65%) create mode 100644 docs/HandlingTextInput.md create mode 100644 docs/HandlingTouches.md create mode 100644 docs/HeightAndWidth.md rename docs/{Tutorial-IntegrationWithExistingApps.md => IntegrationWithExistingApps.md} (99%) delete mode 100644 docs/KnownIssues.md create mode 100644 docs/LayoutWithFlexbox.md create mode 100644 docs/MoreResources.md delete mode 100644 docs/Network.md create mode 100644 docs/Networking.md delete mode 100644 docs/Newsletter.md create mode 100644 docs/Props.md create mode 100644 docs/RunningOnSimulatorIOS.md delete mode 100644 docs/SampleApplication-F8App.md delete mode 100644 docs/SampleApplication-Movies.md create mode 100644 docs/State.md delete mode 100644 docs/Tutorial-CoreComponents.md create mode 100644 docs/Tutorial.md create mode 100644 docs/UsingAListView.md create mode 100644 docs/UsingAScrollView.md delete mode 100644 docs/Videos.md create mode 100644 website/core/WebPlayer.js create mode 100644 website/jsdocs/jsdoc-conf.json create mode 100644 website/jsdocs/jsdoc-plugin-values.js create mode 100644 website/src/react-native/img/AndroidDevServerDialog.png create mode 100644 website/src/react-native/img/AndroidDevSettings.png create mode 100644 website/src/react-native/img/AndroidDeveloperMenu.png create mode 100644 website/src/react-native/img/DeveloperMenu.png delete mode 100644 website/src/react-native/img/survey.png create mode 100644 website/src/react-native/movies.json diff --git a/Libraries/Components/MapView/MapView.js b/Libraries/Components/MapView/MapView.js index b554585c6e0dce..d6eb93f7e85932 100644 --- a/Libraries/Components/MapView/MapView.js +++ b/Libraries/Components/MapView/MapView.js @@ -27,21 +27,58 @@ const requireNativeComponent = require('requireNativeComponent'); type Event = Object; +/** + * State an annotation on the map. + */ export type AnnotationDragState = $Enum<{ + /** + * Annotation is not being touched. + */ idle: string; + /** + * Annotation dragging has began. + */ starting: string; + /** + * Annotation is being dragged. + */ dragging: string; + /** + * Annotation dragging is being canceled. + */ canceling: string; + /** + * Annotation dragging has ended. + */ ending: string; }>; /** - * A component for displaying embeddable maps and annotations using the native - * iOS MKMapView class. The Android version is not currently available in the - * open source React Native project, but you can use Leland Richardson's - * cross-platform and more feature-complete + * **This component is only supported on iOS.** + * + * `MapView` is used to display embeddable maps and annotations using + * `MKMapView`. + * + * For a cross-platform solution, check out * [react-native-maps](https://github.com/lelandrichardson/react-native-maps) - * instead. + * by Leland Richardson. + * + * ``` + * import React, { Component } from 'react'; + * import { MapView } from 'react-native'; + * + * class MapMyRide extends Component { + * render() { + * return ( + * + * ); + * } + * } + * ``` + * */ const MapView = React.createClass({ @@ -51,8 +88,7 @@ const MapView = React.createClass({ propTypes: { ...View.propTypes, /** - * Used to style and layout the `MapView`. See `StyleSheet.js` and - * `ViewStylePropTypes.js` for more info. + * Used to style and layout the `MapView`. */ style: View.propTypes.style, @@ -60,7 +96,7 @@ const MapView = React.createClass({ * If `true` the app will ask for the user's location and display it on * the map. Default value is `false`. * - * **NOTE**: on iOS, you need to add the `NSLocationWhenInUseUsageDescription` + * **NOTE**: You'll need to add the `NSLocationWhenInUseUsageDescription` * key in Info.plist to enable geolocation, otherwise it will fail silently. */ showsUserLocation: React.PropTypes.bool, @@ -69,21 +105,18 @@ const MapView = React.createClass({ * If `true` the map will follow the user's location whenever it changes. * Note that this has no effect unless `showsUserLocation` is enabled. * Default value is `true`. - * @platform ios */ followUserLocation: React.PropTypes.bool, /** * If `false` points of interest won't be displayed on the map. * Default value is `true`. - * @platform ios */ showsPointsOfInterest: React.PropTypes.bool, /** - * If `false` compass won't be displayed on the map. + * If `false`, compass won't be displayed on the map. * Default value is `true`. - * @platform ios */ showsCompass: React.PropTypes.bool, @@ -96,7 +129,9 @@ const MapView = React.createClass({ /** * When this property is set to `true` and a valid camera is associated with * the map, the camera’s heading angle is used to rotate the plane of the - * map around its center point. When this property is set to `false`, the + * map around its center point. + * + * When this property is set to `false`, the * camera’s heading angle is ignored and the map is always oriented so * that true north is situated at the top of the map view */ @@ -105,7 +140,9 @@ const MapView = React.createClass({ /** * When this property is set to `true` and a valid camera is associated * with the map, the camera’s pitch angle is used to tilt the plane - * of the map. When this property is set to `false`, the camera’s pitch + * of the map. + * + * When this property is set to `false`, the camera’s pitch * angle is ignored and the map is always displayed as if the user * is looking straight down onto it. */ @@ -120,11 +157,9 @@ const MapView = React.createClass({ /** * The map type to be displayed. * - * - standard: standard road map (default) - * - satellite: satellite view - * - hybrid: satellite view with roads and points of interest overlaid - * - * @platform ios + * - `standard`: Standard road map (default). + * - `satellite`: Satellite view. + * - `hybrid`: Satellite view with roads and points of interest overlaid. */ mapType: React.PropTypes.oneOf([ 'standard', @@ -154,8 +189,7 @@ const MapView = React.createClass({ }), /** - * Map annotations with title/subtitle. - * @platform ios + * Map annotations with title and subtitle. */ annotations: React.PropTypes.arrayOf(React.PropTypes.shape({ /** @@ -192,7 +226,7 @@ const MapView = React.createClass({ onBlur: React.PropTypes.func, /** - * Annotation title/subtile. + * Annotation title and subtile. */ title: React.PropTypes.string, subtitle: React.PropTypes.string, @@ -253,7 +287,6 @@ const MapView = React.createClass({ /** * Map overlays - * @platform ios */ overlays: React.PropTypes.arrayOf(React.PropTypes.shape({ /** @@ -278,21 +311,17 @@ const MapView = React.createClass({ })), /** - * Maximum size of area that can be displayed. - * @platform ios + * Maximum size of the area that can be displayed. */ maxDelta: React.PropTypes.number, /** - * Minimum size of area that can be displayed. - * @platform ios + * Minimum size of the area that can be displayed. */ minDelta: React.PropTypes.number, /** * Insets for the map's legal label, originally at bottom left of the map. - * See `EdgeInsetsPropType.js` for more information. - * @platform ios */ legalLabelInsets: EdgeInsetsPropType, @@ -307,7 +336,7 @@ const MapView = React.createClass({ onRegionChangeComplete: React.PropTypes.func, /** - * Deprecated. Use annotation onFocus and onBlur instead. + * Deprecated. Use annotation `onFocus` and `onBlur` instead. */ onAnnotationPress: React.PropTypes.func, diff --git a/Libraries/Components/Navigation/NavigatorIOS.ios.js b/Libraries/Components/Navigation/NavigatorIOS.ios.js index ad6530008335ea..9fe0af55c43375 100644 --- a/Libraries/Components/Navigation/NavigatorIOS.ios.js +++ b/Libraries/Components/Navigation/NavigatorIOS.ios.js @@ -93,86 +93,176 @@ type Event = Object; */ /** - * NavigatorIOS wraps UIKit navigation and allows you to add back-swipe - * functionality across your app. + * `NavigatorIOS` is a wrapper around UIKit navigation, enabling you to + * implement back-swipe functionality in your iOS app. Take a look at + * [`Navigator`](/docs/navigator.html) for a similar solution for your + * cross-platform needs. * - * > **NOTE**: This Component is not maintained by Facebook - * > - * > This component is under community responsibility. - * > If a pure JavaScript solution fits your needs you may try the `Navigator` - * > component instead. + * To set up the navigator, provide the `initialRoute` prop with a route + * object. A route object is used to describe each scene that your app + * navigates to. `initialRoute` represents the first route in your navigator. * - * #### Routes - * A route is an object used to describe each page in the navigator. The first - * route is provided to NavigatorIOS as `initialRoute`: + * ``` + * import React, { Component } from 'react'; + * import { NavigatorIOS, Text } from 'react-native'; + * + * class NavvyIOS extends Component { + * render() { + * return ( + * + * ); + * } + * } * + * class MyView extends Component { + * render() { + * return( + * + * See you on the other nav! + * + * ); + * } + * } * ``` - * render: function() { - * return ( - * - * ); - * }, + * + * In this code, the navigator sets its title and renders `MyView`. The + * component specified in `initialRoute` will receive a `route` prop and a + * `navigator` prop representing the navigator. + * + * You can optionally pass in a `passProps` property to your `initialRoute`. + * `NavigatorIOS` passes this in as props to the rendered component: + * + * ``` + * initialRoute={{ + * component: MyView, + * title: 'Foo This', + * passProps: { myProp: 'foo' } + * }} * ``` * - * Now MyView will be rendered by the navigator. It will receive the route - * object in the `route` prop, a navigator, and all of the props specified in - * `passProps`. + * You can then access the props passed in: * - * See the initialRoute propType for a complete definition of a route. + * ``` + * + * See you on the other nav {this.props.myProp}! + * + * ``` * - * #### Navigator + * #### Handling Navigation * - * A `navigator` is an object of navigation functions that a view can call. It - * is passed as a prop to any component rendered by NavigatorIOS. + * To trigger navigation functionality such as pushing or popping a view, you + * have access to a `navigator` object. The object is passed in as a prop to any + * component that is rendered by `NavigatorIOS`. You can then call the + * relevant methods to perform the navigation action you need: * * ``` - * var MyView = React.createClass({ - * _handleBackButtonPress: function() { + * class MyView extends Component { + * _handleBackPress() { * this.props.navigator.pop(); - * }, - * _handleNextButtonPress: function() { + * } + * + * _handleNextPress(nextRoute) { * this.props.navigator.push(nextRoute); - * }, - * ... - * }); + * } + * + * render() { + * const nextRoute = { + * component: MyView, + * title: 'Bar That', + * passProps: { myProp: 'bar' } + * }; + * return( + * this._handleNextPress(nextRoute)}> + * + * See you on the other nav {this.props.myProp}! + * + * + * ); + * } + * } * ``` * - * Navigator functions are also available on the NavigatorIOS component: + * You can also trigger navigator functionality from the `NavigatorIOS` + * component: * * ``` - * var MyView = React.createClass({ - * _handleNavigationRequest: function() { - * this.refs.nav.push(otherRoute); - * }, - * render: () => ( - * - * ), - * }); + * class NavvyIOS extends Component { + * _handleNavigationRequest() { + * this.refs.nav.push({ + * component: MyView, + * title: 'Genius', + * passProps: { myProp: 'genius' }, + * }); + * } + * + * render() { + * return ( + * this._handleNavigationRequest(), + * }} + * style={{flex: 1}} + * /> + * ); + * } + * } * ``` * - * Props passed to the NavigatorIOS component will set the default configuration + * The code above adds a `_handleNavigationRequest` private method that is + * invoked from the `NavigatorIOS` component when the right navigation bar item + * is pressed. To get access to the navigator functionality, a reference to it + * is saved in the `ref` prop and later referenced to push a new scene into the + * navigation stack. + * + * #### Navigation Bar Configuration + * + * Props passed to `NavigatorIOS` will set the default configuration * for the navigation bar. Props passed as properties to a route object will set * the configuration for that route's navigation bar, overriding any props - * passed to the NavigatorIOS component. + * passed to the `NavigatorIOS` component. * + * ``` + * _handleNavigationRequest() { + * this.refs.nav.push({ + * //... + * passProps: { myProp: 'genius' }, + * barTintColor: '#996699', + * }); + * } + * + * render() { + * return ( + * + * ); + * } + * ``` + * + * In the example above the navigation bar color is changed when the new route + * is pushed. */ var NavigatorIOS = React.createClass({ propTypes: { /** - * NavigatorIOS uses "route" objects to identify child views, their props, - * and navigation bar configuration. "push" and all the other navigation - * operations expect routes to be like this: + * NavigatorIOS uses `route` objects to identify child views, their props, + * and navigation bar configuration. Navigation operations such as push + * operations expect routes to look like this the `initialRoute`. */ initialRoute: PropTypes.shape({ /** @@ -181,139 +271,159 @@ var NavigatorIOS = React.createClass({ component: PropTypes.func.isRequired, /** - * The title displayed in the nav bar and back button for this route + * The title displayed in the navigation bar and the back button for this + * route. */ title: PropTypes.string.isRequired, /** - * Specify additional props passed to the component. NavigatorIOS will - * automatically provide "route" and "navigator" components + * If set, a title image will appear instead of the text title. + */ + titleImage: Image.propTypes.source, + + /** + * Use this to specify additional props to pass to the rendered + * component. `NavigatorIOS` will automatically pass in `route` and + * `navigator` props to the comoponent. */ passProps: PropTypes.object, /** - * If set, the left header button image will appear with this source. Note - * that this doesn't apply for the header of the current view, but the - * ones of the views that are pushed afterward. + * If set, the left navigation button image will be displayed using this + * source. Note that this doesn't apply to the header of the current + * view, but to those views that are subsequently pushed. */ backButtonIcon: Image.propTypes.source, /** - * If set, the left header button will appear with this name. Note that - * this doesn't apply for the header of the current view, but the ones - * of the views that are pushed afterward. + * If set, the left navigation button text will be set to this. Note that + * this doesn't apply to the left button of the current view, but to + * those views that are subsequently pushed */ backButtonTitle: PropTypes.string, /** - * If set, the left header button image will appear with this source + * If set, the left navigation button image will be displayed using + * this source. */ leftButtonIcon: Image.propTypes.source, /** - * If set, the left header button will appear with this name + * If set, the left navigation button will display this text. */ leftButtonTitle: PropTypes.string, /** - * Called when the left header button is pressed + * This function will be invoked when the left navigation bar item is + * pressed. */ onLeftButtonPress: PropTypes.func, /** - * If set, the right header button image will appear with this source + * If set, the right navigation button image will be displayed using + * this source. */ rightButtonIcon: Image.propTypes.source, /** - * If set, the right header button will appear with this name + * If set, the right navigation button will display this text. */ rightButtonTitle: PropTypes.string, /** - * Called when the right header button is pressed + * This function will be invoked when the right navigation bar item is + * pressed. */ onRightButtonPress: PropTypes.func, /** - * Styles for the navigation item containing the component + * Styles for the navigation item containing the component. */ wrapperStyle: View.propTypes.style, /** - * A Boolean value that indicates whether the navigation bar is hidden + * Boolean value that indicates whether the navigation bar is hidden. */ navigationBarHidden: PropTypes.bool, /** - * A Boolean value that indicates whether to hide the 1px hairline shadow + * Boolean value that indicates whether to hide the 1px hairline + * shadow. */ shadowHidden: PropTypes.bool, /** - * The color used for buttons in the navigation bar + * The color used for the buttons in the navigation bar. */ tintColor: PropTypes.string, /** - * The background color of the navigation bar + * The background color of the navigation bar. */ barTintColor: PropTypes.string, /** - * The text color of the navigation bar title + * The text color of the navigation bar title. */ titleTextColor: PropTypes.string, /** - * A Boolean value that indicates whether the navigation bar is translucent + * Bboolean value that indicates whether the navigation bar is + * translucent. */ translucent: PropTypes.bool, }).isRequired, /** - * A Boolean value that indicates whether the navigation bar is hidden by default + * Boolean value that indicates whether the navigation bar is hidden + * by default. */ navigationBarHidden: PropTypes.bool, /** - * A Boolean value that indicates whether to hide the 1px hairline shadow by default + * Boolean value that indicates whether to hide the 1px hairline shadow + * by default. */ shadowHidden: PropTypes.bool, /** * The default wrapper style for components in the navigator. - * A common use case is to set the backgroundColor for every page + * A common use case is to set the `backgroundColor` for every scene. */ itemWrapperStyle: View.propTypes.style, /** - * The default color used for buttons in the navigation bar + * The default color used for the buttons in the navigation bar. */ tintColor: PropTypes.string, /** - * The default background color of the navigation bar + * The default background color of the navigation bar. */ barTintColor: PropTypes.string, /** - * The default text color of the navigation bar title + * The default text color of the navigation bar title. */ titleTextColor: PropTypes.string, /** - * A Boolean value that indicates whether the navigation bar is translucent by default + * Boolean value that indicates whether the navigation bar is + * translucent by default */ translucent: PropTypes.bool, /** - * A Boolean value that indicates whether the interactive pop gesture is enabled. Useful - * for enabling/disabling the back swipe navigation gesture. If this prop is not provided, - * the default behavior is for the back swipe gesture to be enabled when the navigation bar - * is shown and disabled when the navigation bar is hidden. Once you've provided - * the interactivePopGestureEnabled prop, you can never restore the default behavior. + * Boolean value that indicates whether the interactive pop gesture is + * enabled. This is useful for enabling/disabling the back swipe navigation + * gesture. + * + * If this prop is not provided, the default behavior is for the back swipe + * gesture to be enabled when the navigation bar is shown and disabled when + * the navigation bar is hidden. Once you've provided the + * `interactivePopGestureEnabled` prop, you can never restore the default + * behavior. */ interactivePopGestureEnabled: PropTypes.bool, @@ -488,7 +598,8 @@ var NavigatorIOS = React.createClass({ }, /** - * Navigate forward to a new route + * Navigate forward to a new route. + * @param route The new route to navigate to. */ push: function(route: Route) { invariant(!!route, 'Must supply route to push'); @@ -513,7 +624,8 @@ var NavigatorIOS = React.createClass({ }, /** - * Go back N pages at once. When N=1, behavior matches `pop()` + * Go back N scenes at once. When N=1, behavior matches `pop()`. + * @param n The number of scenes to pop. */ popN: function(n: number) { if (n === 0) { @@ -537,7 +649,7 @@ var NavigatorIOS = React.createClass({ }, /** - * Go back one page + * Pop back to the previous scene. */ pop: function() { this.popN(1); @@ -546,8 +658,9 @@ var NavigatorIOS = React.createClass({ /** * Replace a route in the navigation stack. * - * `index` specifies the route in the stack that should be replaced. - * If it's negative, it counts from the back. + * @param route The new route that will replace the specified one. + * @param index The route into the stack that should be replaced. + * If it is negative, it counts from the back of the stack. */ replaceAtIndex: function(route: Route, index: number) { invariant(!!route, 'Must supply route to replace'); @@ -578,29 +691,32 @@ var NavigatorIOS = React.createClass({ }, /** - * Replace the route for the current page and immediately + * Replace the route for the current scene and immediately * load the view for the new route. + * @param route The new route to navigate to. */ replace: function(route: Route) { this.replaceAtIndex(route, -1); }, /** - * Replace the route/view for the previous page. + * Replace the route/view for the previous scene. + * @param route The new route to will replace the previous scene. */ replacePrevious: function(route: Route) { this.replaceAtIndex(route, -2); }, /** - * Go back to the top item + * Go back to the topmost item in the navigation stack. */ popToTop: function() { this.popToRoute(this.state.routeStack[0]); }, /** - * Go back to the item for a particular route object + * Go back to the item for a particular route object. + * @param route The new route to navigate to. */ popToRoute: function(route: Route) { var indexOfRoute = this.state.routeStack.indexOf(route); @@ -614,6 +730,7 @@ var NavigatorIOS = React.createClass({ /** * Replaces the previous route/view and transitions back to it. + * @param route The new route that replaces the previous scene. */ replacePreviousAndPop: function(route: Route) { // Make sure all previous requests are caught up first. Otherwise reject. @@ -633,7 +750,8 @@ var NavigatorIOS = React.createClass({ }, /** - * Replaces the top item and popToTop + * Replaces the top item and pop to it. + * @param route The new route that will replace the topmost item. */ resetTo: function(route: Route) { invariant(!!route, 'Must supply route to push'); diff --git a/Libraries/Components/StatusBar/StatusBar.js b/Libraries/Components/StatusBar/StatusBar.js index e49f7c930a087b..8c0b65a0b1c632 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -19,14 +19,35 @@ const processColor = require('processColor'); const StatusBarManager = require('NativeModules').StatusBarManager; +/** + * Status bar style + */ export type StatusBarStyle = $Enum<{ + /** + * Default status bar style + */ 'default': string, + /** + * Dark background style + */ 'light-content': string, }>; +/** + * Status bar animation + */ export type StatusBarAnimation = $Enum<{ + /** + * No animation + */ 'none': string, + /** + * Fade animation + */ 'fade': string, + /** + * Slide animation + */ 'slide': string, }>; @@ -135,6 +156,13 @@ const StatusBar = React.createClass({ // Provide an imperative API as static functions of the component. // See the corresponding prop for more detail. + + /** + * Show or hide the status bar + * @param hidden The dialog's title. + * @param animation Optional animation when + * changing the status bar hidden property. + */ setHidden(hidden: boolean, animation?: StatusBarAnimation) { animation = animation || 'none'; StatusBar._defaultProps.hidden.value = hidden; @@ -145,6 +173,11 @@ const StatusBar = React.createClass({ } }, + /** + * Set the status bar style + * @param style Status bar style to set + * @param animated Animate the style change. + */ setBarStyle(style: StatusBarStyle, animated?: boolean) { if (Platform.OS !== 'ios') { console.warn('`setBarStyle` is only available on iOS'); @@ -155,6 +188,10 @@ const StatusBar = React.createClass({ StatusBarManager.setStyle(style, animated); }, + /** + * Control the visibility of the network activity indicator + * @param visible Show the indicator. + */ setNetworkActivityIndicatorVisible(visible: boolean) { if (Platform.OS !== 'ios') { console.warn('`setNetworkActivityIndicatorVisible` is only available on iOS'); @@ -164,6 +201,11 @@ const StatusBar = React.createClass({ StatusBarManager.setNetworkActivityIndicatorVisible(visible); }, + /** + * Set the background color for the status bar + * @param color Background color. + * @param animated Animate the style change. + */ setBackgroundColor(color: string, animated?: boolean) { if (Platform.OS !== 'android') { console.warn('`setBackgroundColor` is only available on Android'); @@ -174,6 +216,10 @@ const StatusBar = React.createClass({ StatusBarManager.setColor(processColor(color), animated); }, + /** + * Control the translucency of the status bar + * @param translucent Set as translucent. + */ setTranslucent(translucent: boolean) { if (Platform.OS !== 'android') { console.warn('`setTranslucent` is only available on Android'); diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 346e93b3770270..5f42d5e71c9e3a 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -61,12 +61,29 @@ type Event = Object; * such as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple * example: * - * ``` - * this.setState({text})} - * value={this.state.text} - * /> + * ```ReactNativeWebPlayer + * import React, { Component } from 'react'; + * import { AppRegistry, TextInput } from 'react-native'; + * + * class UselessTextInput extends Component { + * constructor(props) { + * super(props); + * this.state = { text: 'Useless Placeholder' }; + * } + * + * render() { + * return ( + * this.setState({text})} + * value={this.state.text} + * /> + * ); + * } + * } + * + * // App registration and rendering + * AppRegistry.registerComponent('AwesomeProject', () => UselessTextInput); * ``` * * Note that some props are only available with `multiline={true/false}`. @@ -75,11 +92,64 @@ type Event = Object; * `multiline=false`. To achieve the same effect, you can wrap your `TextInput` * in a `View`: * + * ```ReactNativeWebPlayer + * import React, { Component } from 'react'; + * import { AppRegistry, View, TextInput } from 'react-native'; + * + * class UselessTextInput extends Component { + * render() { + * return ( + * + * ); + * } + * } + * + * class UselessTextInputMultiline extends Component { + * constructor(props) { + * super(props); + * this.state = { + * text: 'Useless Multiline Placeholder', + * }; + * } + * + * // If you type something in the text box that is a color, the background will change to that + * // color. + * render() { + * return ( + * + * this.setState({text})} + * value={this.state.text} + * /> + * + * ); + * } + * } + * + * // App registration and rendering + * AppRegistry.registerComponent( + * 'AwesomeProject', + * () => UselessTextInputMultiline + * ); * ``` - * - * - * - * ``` + * + * `TextInput` has by default a border at the bottom of its view. This border + * has its padding set by the background image provided by the system, and it + * cannot be changed. Solutions to avoid this is to either not set height + * explicitly, case in which the system will take care of displaying the border + * in the correct position, or to not display the border by setting + * `underlineColorAndroid` to transparent. + * */ var TextInput = React.createClass({ statics: { @@ -90,12 +160,12 @@ var TextInput = React.createClass({ propTypes: { ...View.propTypes, /** - * Can tell TextInput to automatically capitalize certain characters. + * Can tell `TextInput` to automatically capitalize certain characters. * - * - characters: all characters, - * - words: first letter of each word - * - sentences: first letter of each sentence (default) - * - none: don't auto capitalize anything + * - `characters`: all characters. + * - `words`: first letter of each word. + * - `sentences`: first letter of each sentence (*default*). + * - `none`: don't auto capitalize anything. */ autoCapitalize: PropTypes.oneOf([ 'none', @@ -104,16 +174,16 @@ var TextInput = React.createClass({ 'characters', ]), /** - * If false, disables auto-correct. The default value is true. + * If `false`, disables auto-correct. The default value is `true`. */ autoCorrect: PropTypes.bool, /** - * If true, focuses the input on componentDidMount. - * The default value is false. + * If `true`, focuses the input on `componentDidMount`. + * The default value is `false`. */ autoFocus: PropTypes.bool, /** - * If false, text is not editable. The default value is true. + * If `false`, text is not editable. The default value is `true`. */ editable: PropTypes.bool, /** @@ -121,9 +191,9 @@ var TextInput = React.createClass({ * * The following values work across platforms: * - * - default - * - numeric - * - email-address + * - `default` + * - `numeric` + * - `email-address` */ keyboardType: PropTypes.oneOf([ // Cross-platform @@ -154,27 +224,33 @@ var TextInput = React.createClass({ * Determines how the return key should look. On Android you can also use * `returnKeyLabel`. * + * *Cross platform* + * * The following values work across platforms: * - * - done - * - go - * - next - * - search - * - send + * - `done` + * - `go` + * - `next` + * - `search` + * - `send` + * + * *Android Only* * * The following values work on Android only: * - * - none - * - previous + * - `none` + * - `previous` + * + * *iOS Only* * * The following values work on iOS only: * - * - default - * - emergency-call - * - google - * - join - * - route - * - yahoo + * - `default` + * - `emergency-call` + * - `google` + * - `join` + * - `route` + * - `yahoo` */ returnKeyType: PropTypes.oneOf([ // Cross-platform @@ -205,28 +281,28 @@ var TextInput = React.createClass({ */ maxLength: PropTypes.number, /** - * Sets the number of lines for a TextInput. Use it with multiline set to - * true to be able to fill the lines. + * Sets the number of lines for a `TextInput`. Use it with multiline set to + * `true` to be able to fill the lines. * @platform android */ numberOfLines: PropTypes.number, /** - * If true, the keyboard disables the return key when there is no text and - * automatically enables it when there is text. The default value is false. + * If `true`, the keyboard disables the return key when there is no text and + * automatically enables it when there is text. The default value is `false`. * @platform ios */ enablesReturnKeyAutomatically: PropTypes.bool, /** - * If true, the text input can be multiple lines. - * The default value is false. + * If `true`, the text input can be multiple lines. + * The default value is `false`. */ multiline: PropTypes.bool, /** - * Callback that is called when the text input is blurred + * Callback that is called when the text input is blurred. */ onBlur: PropTypes.func, /** - * Callback that is called when the text input is focused + * Callback that is called when the text input is focused. */ onFocus: PropTypes.func, /** @@ -243,18 +319,18 @@ var TextInput = React.createClass({ */ onEndEditing: PropTypes.func, /** - * Callback that is called when the text input selection is changed + * Callback that is called when the text input selection is changed. */ onSelectionChange: PropTypes.func, /** * Callback that is called when the text input's submit button is pressed. - * Invalid if multiline={true} is specified. + * Invalid if `multiline={true}` is specified. */ onSubmitEditing: PropTypes.func, /** * Callback that is called when a key is pressed. * Pressed key value is passed as an argument to the callback handler. - * Fires before onChange callbacks. + * Fires before `onChange` callbacks. * @platform ios */ onKeyPress: PropTypes.func, @@ -263,32 +339,42 @@ var TextInput = React.createClass({ */ onLayout: PropTypes.func, /** - * The string that will be rendered before text input has been entered + * The string that will be rendered before text input has been entered. */ placeholder: PropTypes.string, /** - * The text color of the placeholder string + * The text color of the placeholder string. */ placeholderTextColor: PropTypes.string, /** - * If true, the text input obscures the text entered so that sensitive text - * like passwords stay secure. The default value is false. + * If `true`, the text input obscures the text entered so that sensitive text + * like passwords stay secure. The default value is `false`. */ secureTextEntry: PropTypes.bool, /** - * The highlight (and cursor on ios) color of the text input + * The highlight (and cursor on iOS) color of the text input. */ selectionColor: PropTypes.string, /** - * See DocumentSelectionState.js, some state that is responsible for - * maintaining selection information for a document + * An instance of `DocumentSelectionState`, this is some state that is responsible for + * maintaining selection information for a document. + * + * Some functionality that can be performed with this instance is: + * + * - `blur()` + * - `focus()` + * - `update()` + * + * > You can reference `DocumentSelectionState` in + * > [`vendor/document/selection/DocumentSelectionState.js`](https://github.com/facebook/react-native/blob/master/Libraries/vendor/document/selection/DocumentSelectionState.js) + * * @platform ios */ selectionState: PropTypes.instanceOf(DocumentSelectionState), /** - * The value to show for the text input. TextInput is a controlled + * The value to show for the text input. `TextInput` is a controlled * component, which means the native value will be forced to match this - * value prop if provided. For most uses this works great, but in some + * value prop if provided. For most uses, this works great, but in some * cases this may cause flickering - one common cause is preventing edits * by keeping value the same. In addition to simply setting the same value, * either set `editable={false}`, or set/update `maxLength` to prevent @@ -297,12 +383,12 @@ var TextInput = React.createClass({ value: PropTypes.string, /** * Provides an initial value that will change when the user starts typing. - * Useful for simple use-cases where you don't want to deal with listening + * Useful for simple use-cases where you do not want to deal with listening * to events and updating the value prop to keep the controlled state in sync. */ defaultValue: PropTypes.string, /** - * When the clear button should appear on the right side of the text view + * When the clear button should appear on the right side of the text view. * @platform ios */ clearButtonMode: PropTypes.oneOf([ @@ -312,28 +398,28 @@ var TextInput = React.createClass({ 'always', ]), /** - * If true, clears the text field automatically when editing begins + * If `true`, clears the text field automatically when editing begins. * @platform ios */ clearTextOnFocus: PropTypes.bool, /** - * If true, all text will automatically be selected on focus + * If `true`, all text will automatically be selected on focus. */ selectTextOnFocus: PropTypes.bool, /** - * If true, the text field will blur when submitted. + * If `true`, the text field will blur when submitted. * The default value is true for single-line fields and false for - * multiline fields. Note that for multiline fields, setting blurOnSubmit - * to true means that pressing return will blur the field and trigger the - * onSubmitEditing event instead of inserting a newline into the field. + * multiline fields. Note that for multiline fields, setting `blurOnSubmit` + * to `true` means that pressing return will blur the field and trigger the + * `onSubmitEditing` event instead of inserting a newline into the field. */ blurOnSubmit: PropTypes.bool, /** - * Styles + * [Styles](/react-native/docs/style.html) */ style: Text.propTypes.style, /** - * The color of the textInput underline. + * The color of the `TextInput` underline. * @platform android */ underlineColorAndroid: PropTypes.string, @@ -353,7 +439,7 @@ var TextInput = React.createClass({ {})) : Object), /** - * Returns if the input is currently focused. + * Returns `true` if the input is currently focused; `false` otherwise. */ isFocused: function(): boolean { return TextInputState.currentlyFocusedField() === @@ -407,7 +493,7 @@ var TextInput = React.createClass({ }, /** - * Removes all text from the input. + * Removes all text from the `TextInput`. */ clear: function() { this.setNativeProps({text: ''}); diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index b9e698f63c4576..eb6618e0a4e45a 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -66,26 +66,56 @@ const statics = { }; /** - * The most fundamental component for building UI, `View` is a - * container that supports layout with flexbox, style, some touch handling, and - * accessibility controls, and is designed to be nested inside other views and - * to have 0 to many children of any type. `View` maps directly to the native - * view equivalent on whatever platform React is running on, whether that is a - * `UIView`, `
`, `android.view`, etc. This example creates a `View` that - * wraps two colored boxes and custom component in a row with padding. + * The most fundamental component for building a UI, `View` is a container that supports layout with + * [flexbox](/react-native/docs/flexbox.html), [style](/react-native/docs/style.html), + * [some touch handling](/react-native/docs/handling-touches.html), and + * [accessibility](/react-native/docs/accessibility.html) controls. `View` maps directly to the + * native view equivalent on whatever platform React Native is running on, whether that is a + * `UIView`, `
`, `android.view`, etc. * + * `View` is designed to be nested inside other views and can have 0 to many children of any type. + * + * This example creates a `View` that wraps two colored boxes and a text component in a row with + * padding. + * + * ```javascript + * class ViewColoredBoxesWithText extends Component { + * render() { + * return ( + * + * + * + * Hello World! + * + * ); + * } + * } * ``` - * - * - * - * - * - * ``` * - * `View`s are designed to be used with `StyleSheet`s for clarity and - * performance, although inline styles are also supported. + * > `View`s are designed to be used with [`StyleSheet`](/react-native/docs/style.html) for clarity + * > and performance, although inline styles are also supported. + * + * ### Synthetic Touch Events + * + * For `View` repsonder props (e.g., `onResponderMove`), the synthetic touch event passed to them + * are of the following form: + * + * - `nativeEvent` + * - `changedTouches` - Array of all touch events that have changed since the last event. + * - `identifier` - The ID of the touch. + * - `locationX` - The X position of the touch, relative to the element. + * - `locationY` - The Y position of the touch, relative to the element. + * - `pageX` - The X position of the touch, relative to the root element. + * - `pageY` - The Y position of the touch, relative to the root element. + * - `target` - The node id of the element receiving the touch event. + * - `timestamp` - A time identifier for the touch, useful for velocity calculation. + * - `touches` - Array of all current touches on the screen. */ const View = React.createClass({ + // TODO: We should probably expose the mixins, viewConfig, and statics publicly. For example, + // one of the props is of type AccessibilityComponentType. That is defined as a const[] above, + // but it is not rendered by the docs, since `statics` below is not rendered. So its Possible + // values had to be hardcoded. mixins: [NativeMethodsMixin], /** @@ -103,7 +133,7 @@ const View = React.createClass({ propTypes: { /** - * When true, indicates that the view is an accessibility element. By default, + * When `true`, indicates that the view is an accessibility element. By default, * all the touchable elements are accessible. */ accessible: PropTypes.bool, @@ -111,13 +141,21 @@ const View = React.createClass({ /** * Overrides the text that's read by the screen reader when the user interacts * with the element. By default, the label is constructed by traversing all the - * children and accumulating all the Text nodes separated by space. + * children and accumulating all the `Text` nodes separated by space. */ accessibilityLabel: PropTypes.string, /** * Indicates to accessibility services to treat UI component like a * native one. Works for Android only. + * + * Possible values are one of: + * + * - `'none'` + * - `'button'` + * - `'radiobutton_checked'` + * - `'radiobutton_unchecked'` + * * @platform android */ accessibilityComponentType: PropTypes.oneOf(AccessibilityComponentType), @@ -125,8 +163,15 @@ const View = React.createClass({ /** * Indicates to accessibility services whether the user should be notified * when this view changes. Works for Android API >= 19 only. - * See http://developer.android.com/reference/android/view/View.html#attr_android:accessibilityLiveRegion - * for references. + * Possible values: + * + * - `'none'` - Accessibility services should not announce changes to this view. + * - `'polite'`- Accessibility services should announce changes to this view. + * - `'assertive'` - Accessibility services should interrupt ongoing speech to immediately announce changes to this view. + * + * See the [Android `View` docs](http://developer.android.com/reference/android/view/View.html#attr_android:accessibilityLiveRegion) + * for reference. + * * @platform android */ accessibilityLiveRegion: PropTypes.oneOf([ @@ -139,16 +184,19 @@ const View = React.createClass({ * Controls how view is important for accessibility which is if it * fires accessibility events and if it is reported to accessibility services * that query the screen. Works for Android only. - * See http://developer.android.com/reference/android/R.attr.html#importantForAccessibility - * for references. + * * Possible values: - * 'auto' - The system determines whether the view is important for accessibility - + * + * - `'auto'` - The system determines whether the view is important for accessibility - * default (recommended). - * 'yes' - The view is important for accessibility. - * 'no' - The view is not important for accessibility. - * 'no-hide-descendants' - The view is not important for accessibility, + * - `'yes'` - The view is important for accessibility. + * - `'no'` - The view is not important for accessibility. + * - `'no-hide-descendants'` - The view is not important for accessibility, * nor are any of its descendant views. * + * See the [Android `importantForAccessibility` docs]( [http://developer.android.com/reference/android/R.attr.html#importantForAccessibility) + * for reference. + * * @platform android */ importantForAccessibility: PropTypes.oneOf([ @@ -160,7 +208,33 @@ const View = React.createClass({ /** * Provides additional traits to screen reader. By default no traits are - * provided unless specified otherwise in element + * provided unless specified otherwise in element. + * + * You can provide one trait or an array of many traits. + * + * Possible values for `AccessibilityTraits` are: + * + * - `'none'` - The element has no traits. + * - `'button'` - The element should be treated as a button. + * - `'link'` - The element should be treated as a link. + * - `'header'` - The element is a header that divides content into sections. + * - `'search'` - The element should be treated as a search field. + * - `'image'` - The element should be treated as an image. + * - `'selected'` - The element is selected. + * - `'plays'` - The element plays sound. + * - `'key'` - The element should be treated like a keyboard key. + * - `'text'` - The element should be treated as text. + * - `'summary'` - The element provides app summary information. + * - `'disabled'` - The element is disabled. + * - `'frequentUpdates'` - The element frequently changes its value. + * - `'startsMedia'` - The element starts a media session. + * - `'adjustable'` - The element allows adjustment over a range of values. + * - `'allowsDirectInteraction'` - The element allows direct touch interaction for VoiceOver users. + * - `'pageTurn'` - Informs VoiceOver that it should scroll to the next page when it finishes reading the contents of the element. + * + * See the [Accessibility guide](/react-native/docs/accessibility.html#accessibilitytraits-ios) + * for more information. + * * @platform ios */ accessibilityTraits: PropTypes.oneOfType([ @@ -175,14 +249,15 @@ const View = React.createClass({ onAccessibilityTap: PropTypes.func, /** - * When `accessible` is true, the system will invoke this function when the + * When `accessible` is `true`, the system will invoke this function when the * user performs the magic tap gesture. */ onMagicTap: PropTypes.func, /** - * Used to locate this view in end-to-end tests. NB: disables the 'layout-only - * view removal' optimization for this view! + * Used to locate this view in end-to-end tests. + * + * > This disables the 'layout-only view removal' optimization for this view! */ testID: PropTypes.string, @@ -191,34 +266,113 @@ const View = React.createClass({ * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`, * `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion. */ + + /** + * The View is now responding for touch events. This is the time to highlight and show the user + * what is happening. + * + * `View.props.onResponderGrant: (event) => {}`, where `event` is a synthetic touch event as + * described above. + */ onResponderGrant: PropTypes.func, + + /** + * The user is moving their finger. + * + * `View.props.onResponderMove: (event) => {}`, where `event` is a synthetic touch event as + * described above. + */ onResponderMove: PropTypes.func, + + /** + * Another responder is already active and will not release it to that `View` asking to be + * the responder. + * + * `View.props.onResponderReject: (event) => {}`, where `event` is a synthetic touch event as + * described above. + */ onResponderReject: PropTypes.func, + + /** + * Fired at the end of the touch. + * + * `View.props.onResponderRelease: (event) => {}`, where `event` is a synthetic touch event as + * described above. + */ onResponderRelease: PropTypes.func, + + /** + * The responder has been taken from the `View`. Might be taken by other views after a call to + * `onResponderTerminationRequest`, or might be taken by the OS without asking (e.g., happens + * with control center/ notification center on iOS) + * + * `View.props.onResponderTerminate: (event) => {}`, where `event` is a synthetic touch event as + * described above. + */ onResponderTerminate: PropTypes.func, + + /** + * Some other `View` wants to become responder and is asking this `View` to release its + * responder. Returning `true` allows its release. + * + * `View.props.onResponderTerminationRequest: (event) => {}`, where `event` is a synthetic touch + * event as described above. + */ onResponderTerminationRequest: PropTypes.func, + + /** + * Does this view want to become responder on the start of a touch? + * + * `View.props.onStartShouldSetResponder: (event) => [true | false]`, where `event` is a + * synthetic touch event as described above. + */ onStartShouldSetResponder: PropTypes.func, + + /** + * If a parent `View` wants to prevent a child `View` from becoming responder on a touch start, + * it should have this handler which returns `true`. + * + * `View.props.onStartShouldSetResponderCapture: (event) => [true | false]`, where `event` is a + * synthetic touch event as described above. + */ onStartShouldSetResponderCapture: PropTypes.func, + + /** + * Does this view want to "claim" touch responsiveness? This is called for every touch move on + * the `View` when it is not the responder. + * + * `View.props.onMoveShouldSetResponder: (event) => [true | false]`, where `event` is a + * synthetic touch event as described above. + */ onMoveShouldSetResponder: PropTypes.func, + + /** + * If a parent `View` wants to prevent a child `View` from becoming responder on a move, + * it should have this handler which returns `true`. + * + * `View.props.onMoveShouldSetResponderCapture: (event) => [true | false]`, where `event` is a + * synthetic touch event as described above. + */ onMoveShouldSetResponderCapture: PropTypes.func, /** * This defines how far a touch event can start away from the view. * Typical interface guidelines recommend touch targets that are at least - * 30 - 40 points/density-independent pixels. If a Touchable view has a - * height of 20 the touchable height can be extended to 40 with - * `hitSlop={{top: 10, bottom: 10, left: 0, right: 0}}` - * ** NOTE ** - * The touch area never extends past the parent view bounds and the Z-index - * of sibling views always takes precedence if a touch hits two overlapping - * views. + * 30 - 40 points/density-independent pixels. + * + * For example, if a touchable view has a height of 20 the touchable height can be extended to + * 40 with `hitSlop={{top: 10, bottom: 10, left: 0, right: 0}}` + * + * > The touch area never extends past the parent view bounds and the Z-index + * > of sibling views always takes precedence if a touch hits two overlapping + * > views. */ hitSlop: EdgeInsetsPropType, /** - * Invoked on mount and layout changes with + * Invoked on mount and layout changes with: * - * {nativeEvent: { layout: {x, y, width, height}}}. + * `{nativeEvent: { layout: {x, y, width, height}}}` * * This event is fired immediately once the layout has been calculated, but * the new layout may not yet be reflected on the screen at the time the @@ -227,11 +381,11 @@ const View = React.createClass({ onLayout: PropTypes.func, /** - * Controls whether the View can be the target of touch events. + * Controls whether the `View` can be the target of touch events. * - * - 'auto': The View can be the target of touch events. - * - 'none': The View is never the target of touch events. - * - 'box-none': The View is never the target of touch events but it's + * - `'auto'`: The View can be the target of touch events. + * - `'none'`: The View is never the target of touch events. + * - `'box-none'`: The View is never the target of touch events but it's * subviews can be. It behaves like if the view had the following classes * in CSS: * ``` @@ -242,7 +396,7 @@ const View = React.createClass({ * pointer-events: all; * } * ``` - * - 'box-only': The view can be the target of touch events but it's + * - `'box-only'`: The view can be the target of touch events but it's * subviews cannot be. It behaves like if the view had the following classes * in CSS: * ``` @@ -253,12 +407,12 @@ const View = React.createClass({ * pointer-events: none; * } * ``` + * > Since `pointerEvents` does not affect layout/appearance, and we are + * > already deviating from the spec by adding additional modes, we opt to not + * > include `pointerEvents` on `style`. On some platforms, we would need to + * > implement it as a `className` anyways. Using `style` or not is an + * > implementation detail of the platform. */ - // Since `pointerEvents` does not affect layout/appearance, and we are - // already deviating from the spec by adding additional modes, we opt to not - // include `pointerEvents` on `style`. On some platforms, we would need to - // implement it as a `className` anyways. Using `style` or not is an - // implementation detail of the platform. pointerEvents: PropTypes.oneOf([ 'box-none', 'none', @@ -268,17 +422,17 @@ const View = React.createClass({ style: stylePropType, /** - * This is a special performance property exposed by RCTView and is useful + * This is a special performance property exposed by `RCTView` and is useful * for scrolling content when there are many subviews, most of which are * offscreen. For this property to be effective, it must be applied to a * view that contains many subviews that extend outside its bound. The - * subviews must also have overflow: hidden, as should the containing view + * subviews must also have `overflow: hidden`, as should the containing view * (or one of its superviews). */ removeClippedSubviews: PropTypes.bool, /** - * Whether this view should render itself (and all of its children) into a + * Whether this `View` should render itself (and all of its children) into a * single hardware texture on the GPU. * * On Android, this is useful for animations and interactions that only @@ -288,12 +442,13 @@ const View = React.createClass({ * different parameters. The downside is that this can use up limited video * memory, so this prop should be set back to false at the end of the * interaction/animation. + * * @platform android */ renderToHardwareTextureAndroid: PropTypes.bool, /** - * Whether this view should be rendered as a bitmap before compositing. + * Whether this `View` should be rendered as a bitmap before compositing. * * On iOS, this is useful for animations and interactions that do not * modify this component's dimensions nor its children; for example, when @@ -303,6 +458,7 @@ const View = React.createClass({ * * Rasterization incurs an off-screen drawing pass and the bitmap consumes * memory. Test and measure when using this property. + * * @platform ios */ shouldRasterizeIOS: PropTypes.bool, @@ -311,20 +467,21 @@ const View = React.createClass({ * Views that are only used to layout their children or otherwise don't draw * anything may be automatically removed from the native hierarchy as an * optimization. Set this property to `false` to disable this optimization and - * ensure that this View exists in the native view hierarchy. + * ensure that this `View` exists in the native view hierarchy. + * * @platform android */ collapsable: PropTypes.bool, /** - * Whether this view needs to rendered offscreen and composited with an alpha + * Whether this `View` needs to rendered offscreen and composited with an alpha * in order to preserve 100% correct colors and blending behavior. The default - * (false) falls back to drawing the component and its children with an alpha + * (`false`) falls back to drawing the component and its children with an alpha * applied to the paint used to draw each element instead of rendering the full * component offscreen and compositing it back with an alpha value. This default - * may be noticeable and undesired in the case where the View you are setting + * may be noticeable and undesired in the case where the `View` you are setting * an opacity on has multiple overlapping elements (e.g. multiple overlapping - * Views, or text and a background). + * `View`s, or text and a background). * * Rendering offscreen to preserve correct alpha behavior is extremely * expensive and hard to debug for non-native developers, which is why it is diff --git a/Libraries/Components/WebView/WebView.ios.js b/Libraries/Components/WebView/WebView.ios.js index 9e8fd88ab0ffb0..fe82b90061a265 100644 --- a/Libraries/Components/WebView/WebView.ios.js +++ b/Libraries/Components/WebView/WebView.ios.js @@ -82,7 +82,26 @@ var defaultRenderError = (errorDomain, errorCode, errorDesc) => ( ); /** - * Renders a native WebView. + * `WebView` renders web content in a native view. + * + *``` + * import React, { Component } from 'react'; + * import { WebView } from 'react-native'; + * + * class MyWeb extends Component { + * render() { + * return ( + * + * ); + * } + * } + *``` + * + * You can use this component to navigate back and forth in the web view's + * history and configure various properties for the web content. */ var WebView = React.createClass({ statics: { @@ -109,7 +128,7 @@ var WebView = React.createClass({ source: PropTypes.oneOfType([ PropTypes.shape({ /* - * The URI to load in the WebView. Can be a local or remote file. + * The URI to load in the `WebView`. Can be a local or remote file. */ uri: PropTypes.string, /* @@ -155,96 +174,125 @@ var WebView = React.createClass({ */ renderLoading: PropTypes.func, /** - * Invoked when load finish + * Function that is invoked when the `WebView` has finished loading. */ onLoad: PropTypes.func, /** - * Invoked when load either succeeds or fails + * Function that is invoked when the `WebView` load succeeds or fails. */ onLoadEnd: PropTypes.func, /** - * Invoked on load start + * Function that is invoked when the `WebView` starts loading. */ onLoadStart: PropTypes.func, /** - * Invoked when load fails + * Function that is invoked when the `WebView` load fails. */ onError: PropTypes.func, /** + * Boolean value that determines whether the web view bounces + * when it reaches the edge of the content. The default value is `true`. * @platform ios */ bounces: PropTypes.bool, /** * A floating-point number that determines how quickly the scroll view - * decelerates after the user lifts their finger. You may also use string - * shortcuts `"normal"` and `"fast"` which match the underlying iOS settings - * for `UIScrollViewDecelerationRateNormal` and - * `UIScrollViewDecelerationRateFast` respectively. + * decelerates after the user lifts their finger. You may also use the + * string shortcuts `"normal"` and `"fast"` which match the underlying iOS + * settings for `UIScrollViewDecelerationRateNormal` and + * `UIScrollViewDecelerationRateFast` respectively: + * * - normal: 0.998 - * - fast: 0.99 (the default for iOS WebView) + * - fast: 0.99 (the default for iOS web view) * @platform ios */ decelerationRate: ScrollView.propTypes.decelerationRate, /** + * Boolean value that determines whether scrolling is enabled in the + * `WebView`. The default value is `true`. * @platform ios */ scrollEnabled: PropTypes.bool, + /** + * Controls whether to adjust the content inset for web views that are + * placed behind a navigation bar, tab bar, or toolbar. The default value + * is `true`. + */ automaticallyAdjustContentInsets: PropTypes.bool, + /** + * The amount by which the web view content is inset from the edges of + * the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}. + */ contentInset: EdgeInsetsPropType, + /** + * Function that is invoked when the `WebView` loading starts or ends. + */ onNavigationStateChange: PropTypes.func, - startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load + /** + * Boolean value that forces the `WebView` to show the loading view + * on the first load. + */ + startInLoadingState: PropTypes.bool, + /** + * The style to apply to the `WebView`. + */ style: View.propTypes.style, /** - * Used on Android only, JS is enabled by default for WebView on iOS + * Boolean value to enable JavaScript in the `WebView`. Used on Android only + * as JavaScript is enabled by default on iOS. The default value is `true`. * @platform android */ javaScriptEnabled: PropTypes.bool, /** - * Used on Android only, controls whether DOM Storage is enabled or not + * Boolean value to control whether DOM Storage is enabled. Used only in + * Android. * @platform android */ domStorageEnabled: PropTypes.bool, /** - * Sets the JS to be injected when the webpage loads. + * Set this to provide JavaScript that will be injected into the web page + * when the view loads. */ injectedJavaScript: PropTypes.string, /** - * Sets the user-agent for this WebView. The user-agent can also be set in native using - * WebViewConfig. This prop will overwrite that config. + * Sets the user-agent for the `WebView`. * @platform android */ userAgent: PropTypes.string, /** - * Sets whether the webpage scales to fit the view and the user can change the scale. + * Boolean that controls whether the web content is scaled to fit + * the view and enables the user to change the scale. The default value + * is `true`. */ scalesPageToFit: PropTypes.bool, /** - * Allows custom handling of any webview requests by a JS handler. Return true - * or false from this method to continue loading the request. + * Function that allows custom handling of any web view requests. Return + * `true` from the function to continue loading the request and `false` + * to stop loading. * @platform ios */ onShouldStartLoadWithRequest: PropTypes.func, /** - * Determines whether HTML5 videos play inline or use the native full-screen - * controller. - * default value `false` - * **NOTE** : "In order for video to play inline, not only does this - * property need to be set to true, but the video element in the HTML - * document must also include the webkit-playsinline attribute." + * Boolean that determines whether HTML5 videos play inline or use the + * native full-screen controller. The default value is `false`. + * + * **NOTE** : In order for video to play inline, not only does this + * property need to be set to `true`, but the video element in the HTML + * document must also include the `webkit-playsinline` attribute. * @platform ios */ allowsInlineMediaPlayback: PropTypes.bool, /** - * Determines whether HTML5 audio & videos require the user to tap before they can - * start playing. The default value is `false`. + * Boolean that determines whether HTML5 audio and video requires the user + * to tap them before they start playing. The default value is `false`. */ mediaPlaybackRequiresUserAction: PropTypes.bool, }, @@ -337,7 +385,7 @@ var WebView = React.createClass({ }, /** - * Go forward one page in the webview's history. + * Go forward one page in the web view's history. */ goForward: function() { UIManager.dispatchViewManagerCommand( @@ -348,7 +396,7 @@ var WebView = React.createClass({ }, /** - * Go back one page in the webview's history. + * Go back one page in the web view's history. */ goBack: function() { UIManager.dispatchViewManagerCommand( @@ -369,6 +417,9 @@ var WebView = React.createClass({ ); }, + /** + * Stop loading the current page. + */ stopLoading: function() { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), @@ -388,7 +439,7 @@ var WebView = React.createClass({ }, /** - * Returns the native webview node. + * Returns the native `WebView` node. */ getWebViewHandle: function(): any { return ReactNative.findNodeHandle(this.refs[RCT_WEBVIEW_REF]); diff --git a/Libraries/CustomComponents/Navigator/Navigator.js b/Libraries/CustomComponents/Navigator/Navigator.js index 1a685bb29e0d72..b79bd56fb777fd 100644 --- a/Libraries/CustomComponents/Navigator/Navigator.js +++ b/Libraries/CustomComponents/Navigator/Navigator.js @@ -129,54 +129,168 @@ var GESTURE_ACTIONS = [ ]; /** - * Use `Navigator` to transition between different scenes in your app. To - * accomplish this, provide route objects to the navigator to identify each - * scene, and also a `renderScene` function that the navigator can use to - * render the scene for a given route. + * `Navigator` handles the transition between different scenes in your app. + * You should consider using this component instead of `NavigatorIOS` if you're + * building a cross-platform app. `Navigator` is implemented in JavaScript + * whereas `NavigatorIOS` is a wrapper around `UINavigationController`. * - * To change the animation or gesture properties of the scene, provide a - * `configureScene` prop to get the config object for a given route. See - * `Navigator.SceneConfigs` for default animations and more info on - * scene config options. + * To set up the `Navigator` you provide one or more objects called routes, + * to identify each scene. You also provide a `renderScene` function that + * renders the scene for each route object. + * + * ``` + * import React, { Component } from 'react'; + * import { Text, Navigator } from 'react-native'; + * + * class NavAllDay extends Component { + * render() { + * return ( + * + * Hello {route.name}! + * } + * style={{padding: 100}} + * /> + * ); + * } + * } + * ``` + * + * In the above example, `initialRoute` is used to specify the first route. It + * contains a `name` property that identifies the route. The `renderScene` + * prop returns a function that displays text based on the route's name. + * + * ### Additional Scenes * - * ### Basic Usage + * The first example demonstrated one scene. To set up multiple scenes, you pass + * the `initialRouteStack` prop to `Navigator`: * * ``` - * - * { - * var nextIndex = route.index + 1; - * navigator.push({ - * name: 'Scene ' + nextIndex, - * index: nextIndex, - * }); - * }} - * onBack={() => { - * if (route.index > 0) { + * render() { + * const routes = [ + * {name: 'First Scene', index: 0}, + * {name: 'Second Scene', index: 1}, + * ]; + * return ( + * + * { + * if (route.index === 0) { + * navigator.push(routes[1]); + * } else { * navigator.pop(); * } - * }} - * /> + * }}> + * Hello {route.name}! + * + * } + * style={{padding: 100}} + * /> + * ); + * } + * ``` + * + * In the above example, a `routes` variable is defined with two route objects + * representing two scenes. Each route has an `index` property that is used to + * manage the scene being rendered. The `renderScene` method is changed to + * either push or pop the navigator depending on the current route's index. + * Finally, the `Text` component in the scene is now wrapped in a + * `TouchableHighlight` component to help trigger the navigator transitions. + * + * ### Navigation Bar + * + * You can optionally pass in your own navigation bar by returning a + * `Navigator.NavigationBar` component to the `navigationBar` prop in + * `Navigator`. You can configure the navigation bar properties, through + * the `routeMapper` prop. There you set up the left, right, and title + * properties of the navigation bar: + * + * ``` + * + * // ... + * } + * navigationBar={ + * + * { return (Cancel); }, + * RightButton: (route, navigator, index, navState) => + * { return (Done); }, + * Title: (route, navigator, index, navState) => + * { return (Awesome Nav Bar); }, + * }} + * style={{backgroundColor: 'gray'}} + * /> + * } + * /> + * ``` + * + * When configuring the left, right, and title items for the navigation bar, + * you have access to info such as the current route object and navigation + * state. This allows you to customize the title for each scene as well as + * the buttons. For example, you can choose to hide the left button for one of + * the scenes. + * + * Typically you want buttons to represent the left and right buttons. Building + * on the previous example, you can set this up as follows: + * + * ``` + * LeftButton: (route, navigator, index, navState) => + * { + * if (route.index === 0) { + * return null; + * } else { + * return ( + * navigator.pop()}> + * Back + * + * ); * } - * /> + * }, * ``` + * + * This sets up a left navigator bar button that's visible on scenes after the + * the first one. When the button is tapped the navigator is popped. + * + * ### Scene Transitions + * + * To change the animation or gesture properties of the scene, provide a + * `configureScene` prop to get the config object for a given route: + * + * ``` + * + * // ... + * } + * configureScene={(route, routeStack) => + * Navigator.SceneConfigs.FloatFromBottom} + * /> + * ``` + * In the above example, the newly pushed scene will float up from the bottom. + * See `Navigator.SceneConfigs` for default animations and more info on + * available [scene config options](/react-native/docs/navigator.html#configurescene). */ var Navigator = React.createClass({ propTypes: { /** - * Optional function that allows configuration about scene animations and - * gestures. Will be invoked with the route and the routeStack and should - * return a scene configuration object + * Optional function where you can configure scene animations and + * gestures. Will be invoked with `route` and `routeStack` parameters, + * where `route` corresponds to the current scene being rendered by the + * `Navigator` and `routeStack` is the set of currently mounted routes + * that the navigator could transition to. + * + * The function should return a scene configuration object. * * ``` * (route, routeStack) => Navigator.SceneConfigs.FloatFromRight * ``` * - * Available options are: + * Available scene configutation options are: * * - Navigator.SceneConfigs.PushFromRight (default) * - Navigator.SceneConfigs.FloatFromRight @@ -194,7 +308,7 @@ var Navigator = React.createClass({ /** * Required function which renders the scene for a given route. Will be - * invoked with the route and the navigator object + * invoked with the `route` and the `navigator` object. * * ``` * (route, navigator) => @@ -204,45 +318,53 @@ var Navigator = React.createClass({ renderScene: PropTypes.func.isRequired, /** - * Specify a route to start on. A route is an object that the navigator - * will use to identify each scene to render. `initialRoute` must be - * a route in the `initialRouteStack` if both props are provided. The - * `initialRoute` will default to the last item in the `initialRouteStack`. + * The initial route for navigation. A route is an object that the navigator + * will use to identify each scene it renders. + * + * If both `initialRoute` and `initialRouteStack` props are passed to + * `Navigator`, then `initialRoute` must be in a route in + * `initialRouteStack`. If `initialRouteStack` is passed as a prop but + * `initialRoute` is not, then `initialRoute` will default internally to + * the last item in `initialRouteStack`. */ initialRoute: PropTypes.object, /** - * Provide a set of routes to initially mount. Required if no initialRoute - * is provided. Otherwise, it will default to an array containing only the - * `initialRoute` + * Pass this in to provide a set of routes to initially mount. This prop + * is required if `initialRoute` is not provided to the navigator. If this + * prop is not passed in, it will default internally to an array + * containing only `initialRoute`. */ initialRouteStack: PropTypes.arrayOf(PropTypes.object), /** - * Will emit the target route upon mounting and before each nav transition + * Pass in a function to get notified with the target route when + * the navigator component is mounted and before each navigator transition. */ onWillFocus: PropTypes.func, /** * Will be called with the new route of each scene after the transition is - * complete or after the initial mounting + * complete or after the initial mounting. */ onDidFocus: PropTypes.func, /** - * Optionally provide a component as navigation bar that persists across scene - * transitions. The component will receive two props: `navigator` and `navState`. - * It will be rerendered when the routes change. + * Use this to provide an optional component representing a navigation bar + * that is persisted across scene transitions. This component will receive + * two props: `navigator` and `navState` representing the navigator + * component and its state. The component is re-rendered when the route + * changes. */ navigationBar: PropTypes.node, /** - * Optionally provide the navigator object from a parent Navigator + * Optionally pass in the navigator object from a parent `Navigator`. */ navigator: PropTypes.object, /** - * Styles to apply to the container of each scene + * Styles to apply to the container of each scene. */ sceneStyle: View.propTypes.style, }, @@ -348,11 +470,10 @@ var Navigator = React.createClass({ /** * Reset every scene with an array of routes. * - * @param {RouteStack} nextRouteStack Next route stack to reinitialize. This - * doesn't accept stack item `id`s, which implies that all existing items are - * destroyed, and then potentially recreated according to `routeStack`. Does - * not animate, immediately replaces and rerenders navigation bar and stack - * items. + * @param {RouteStack} nextRouteStack Next route stack to reinitialize. + * All existing route stacks are destroyed an potentially recreated. There + * is no accompanying animation and this method immediately replaces and + * re-renders the navigation bar and the stack items. */ immediatelyResetRouteStack: function(nextRouteStack) { var destIndex = nextRouteStack.length - 1; @@ -889,7 +1010,9 @@ var Navigator = React.createClass({ }, /** - * Transition to an existing scene without unmounting + * Transition to an existing scene without unmounting. + * @param {object} route Route to transition to. The specified route must + * be in the currently mounted set of routes defined in `routeStack`. */ jumpTo: function(route) { var destIndex = this.state.routeStack.indexOf(route); @@ -916,7 +1039,8 @@ var Navigator = React.createClass({ /** * Navigate forward to a new scene, squashing any scenes that you could - * `jumpForward` to. + * jump forward to. + * @param {object} route Route to push into the navigator stack. */ push: function(route) { invariant(!!route, 'Must supply route to push'); @@ -980,10 +1104,11 @@ var Navigator = React.createClass({ }, /** - * Replace a scene as specified by an index - * - * `index` specifies the route in the stack that should be replaced. - * If it's negative, it counts from the back. + * Replace a scene as specified by an index. + * @param {object} route Route representing the new scene to render. + * @param {number} index The route in the stack that should be replaced. + * If negative, it counts from the back of the stack. + * @param {Function} cb Callback function when the scene has been replaced. */ replaceAtIndex: function(route, index, cb) { invariant(!!route, 'Must supply route to replace'); @@ -1016,6 +1141,7 @@ var Navigator = React.createClass({ /** * Replace the current scene with a new route. + * @param {object} route Route that replaces the current scene. */ replace: function(route) { this.replaceAtIndex(route, this.state.presentedIndex); @@ -1023,6 +1149,7 @@ var Navigator = React.createClass({ /** * Replace the previous scene. + * @param {object} route Route that replaces the previous scene. */ replacePrevious: function(route) { this.replaceAtIndex(route, this.state.presentedIndex - 1); @@ -1038,6 +1165,7 @@ var Navigator = React.createClass({ /** * Pop to a particular scene, as specified by its route. * All scenes after it will be unmounted. + * @param {object} route Route to pop to. */ popToRoute: function(route) { var indexOfRoute = this.state.routeStack.indexOf(route); @@ -1051,6 +1179,7 @@ var Navigator = React.createClass({ /** * Replace the previous scene and pop to it. + * @param {object} route Route that replaces the previous scene. */ replacePreviousAndPop: function(route) { if (this.state.routeStack.length < 2) { @@ -1062,6 +1191,7 @@ var Navigator = React.createClass({ /** * Navigate to a new scene and reset route stack. + * @param {object} route Route to navigate to. */ resetTo: function(route) { invariant(!!route, 'Must supply route to push'); diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 86ae5e1920c2a9..8176566eef649f 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -34,27 +34,72 @@ const ImageViewManager = NativeModules.ImageViewManager; * including network images, static resources, temporary local images, and * images from local disk, such as the camera roll. * - * Example usage: + * This exmaples shows both fetching and displaying an image from local storage as well as on from + * network. * + * ```ReactNativeWebPlayer + * import React, { Component } from 'react'; + * import { AppRegistry, View, Image } from 'react-native'; + * + * class DisplayAnImage extends Component { + * render() { + * return ( + * + * + * + * + * ); + * } + * } + * + * // App registration and rendering + * AppRegistry.registerComponent('DisplayAnImage', () => DisplayAnImage); * ``` - * renderImages: function() { - * return ( - * - * - * - * - * ); - * }, + * + * You can also add `style` to an image: + * + * ```ReactNativeWebPlayer + * import React, { Component } from 'react'; + * import { AppRegistry, View, Image, StyleSheet} from 'react-native'; + * + * const styles = StyleSheet.create({ + * stretch: { + * width: 50, + * height: 200 + * } + * }); + * + *class DisplayAnImageWithStyle extends Component { + * render() { + * return ( + * + * + * + * ); + * } + * } + * + * // App registration and rendering + * AppRegistry.registerComponent( + * 'DisplayAnImageWithStyle', + * () => DisplayAnImageWithStyle + * ); * ``` */ const Image = React.createClass({ propTypes: { + /** + * > `ImageResizeMode` is an `Enum` for different image resizing modes, set via the + * > `resizeMode` style property on `Image` components. The values are `contain`, `cover`, + * > `stretch`, `center`, `repeat`. + */ style: StyleSheetPropType(ImageStylePropTypes), /** * The image source (either a remote URL or a local file resource). @@ -62,29 +107,26 @@ const Image = React.createClass({ source: ImageSourcePropType, /** * A static image to display while loading the image source. + * + * - `uri` - a string representing the resource identifier for the image, which + * should be either a local file path or the name of a static image resource + * (which should be wrapped in the `require('./path/to/image.png')` function). + * - `width`, `height` - can be specified if known at build time, in which case + * these will be used to set the default `` component dimensions. + * - `scale` - used to indicate the scale factor of the image. Defaults to 1.0 if + * unspecified, meaning that one image pixel equates to one display point / DIP. + * - `number` - Opaque type returned by something like `require('./image.jpg')`. + * * @platform ios */ defaultSource: PropTypes.oneOfType([ + // TODO: Tooling to support documenting these directly and having them display in the docs. PropTypes.shape({ - /** - * `uri` is a string representing the resource identifier for the image, which - * should be either a local file path or the name of a static image resource - * (which should be wrapped in the `require('./path/to/image.png')` function). - */ uri: PropTypes.string, - /** - * `width` and `height` can be specified if known at build time, in which case - * these will be used to set the default `` component dimensions. - */ width: PropTypes.number, height: PropTypes.number, - /** - * `scale` is used to indicate the scale factor of the image. Defaults to 1.0 if - * unspecified, meaning that one image pixel equates to one display point / DIP. - */ scale: PropTypes.number, }), - // Opaque type returned by require('./image.jpg') PropTypes.number, ]), /** @@ -105,10 +147,11 @@ const Image = React.createClass({ blurRadius: PropTypes.number, /** * When the image is resized, the corners of the size specified - * by capInsets will stay a fixed size, but the center content and borders + * by `capInsets` will stay a fixed size, but the center content and borders * of the image will be stretched. This is useful for creating resizable - * rounded buttons, shadows, and other resizable assets. More info on - * [Apple documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets) + * rounded buttons, shadows, and other resizable assets. More info in the + * [official Apple documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets). + * * @platform ios */ capInsets: EdgeInsetsPropType, @@ -116,16 +159,19 @@ const Image = React.createClass({ * Determines how to resize the image when the frame doesn't match the raw * image dimensions. * - * 'cover': Scale the image uniformly (maintain the image's aspect ratio) + * - `cover`: Scale the image uniformly (maintain the image's aspect ratio) * so that both dimensions (width and height) of the image will be equal * to or larger than the corresponding dimension of the view (minus padding). * - * 'contain': Scale the image uniformly (maintain the image's aspect ratio) + * - `contain`: Scale the image uniformly (maintain the image's aspect ratio) * so that both dimensions (width and height) of the image will be equal to * or less than the corresponding dimension of the view (minus padding). * - * 'stretch': Scale width and height independently, This may change the + * - `stretch`: Scale width and height independently, This may change the * aspect ratio of the src. + * + * - `repeat`: Repeat the image to cover the frame of the view. The + * image will keep it's size and aspect ratio. (iOS only) */ resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']), /** @@ -139,25 +185,27 @@ const Image = React.createClass({ */ onLayout: PropTypes.func, /** - * Invoked on load start + * Invoked on load start. + * + * e.g., `onLoadStart={(e) => this.setState({loading: true})}` */ onLoadStart: PropTypes.func, /** - * Invoked on download progress with `{nativeEvent: {loaded, total}}` + * Invoked on download progress with `{nativeEvent: {loaded, total}}`. * @platform ios */ onProgress: PropTypes.func, /** - * Invoked on load error with `{nativeEvent: {error}}` + * Invoked on load error with `{nativeEvent: {error}}`. * @platform ios */ onError: PropTypes.func, /** - * Invoked when load completes successfully + * Invoked when load completes successfully. */ onLoad: PropTypes.func, /** - * Invoked when load either succeeds or fails + * Invoked when load either succeeds or fails. */ onLoadEnd: PropTypes.func, }, @@ -175,6 +223,14 @@ const Image = React.createClass({ * does not fully load/download the image data. A proper, supported way to * preload images will be provided as a separate API. * + * @param uri The location of the image. + * @param success The function that will be called if the image was sucessfully found and width + * and height retrieved. + * @param failure The function that will be called if there was an error, such as failing to + * to retrieve the image. + * + * @returns void + * * @platform ios */ getSize: function( @@ -189,6 +245,10 @@ const Image = React.createClass({ /** * Prefetches a remote image for later use by downloading it to the disk * cache + * + * @param url The remote location of the image. + * + * @return The prefetched image. */ prefetch(url: string) { return ImageViewManager.prefetchImage(url); diff --git a/Libraries/Modal/Modal.js b/Libraries/Modal/Modal.js index 30b5954d0881f5..208ffdee71ca30 100644 --- a/Libraries/Modal/Modal.js +++ b/Libraries/Modal/Modal.js @@ -23,29 +23,93 @@ const requireNativeComponent = require('requireNativeComponent'); const RCTModalHostView = requireNativeComponent('RCTModalHostView', null); /** - * A Modal component covers the native view (e.g. UIViewController, Activity) - * that contains the React Native root. + * The Modal component is a simple way to present content above an enclosing view. * - * Use Modal in hybrid apps that embed React Native; Modal allows the portion of - * your app written in React Native to present content above the enclosing - * native view hierarchy. + * _Note: If you need more control over how to present modals over the rest of your app, + * then consider using a top-level Navigator. Go [here](/react-native/docs/navigator-comparison.html) to compare navigation options._ * - * In apps written with React Native from the root view down, you should use - * Navigator instead of Modal. With a top-level Navigator, you have more control - * over how to present the modal scene over the rest of your app by using the - * configureScene property. + * ```javascript + * import React, { Component } from 'react'; + * import { Modal, Text, TouchableHighlight, View } from 'react-native'; + * + * class ModalExample extends Component { + * + * constructor(props) { + * super(props); + * this.state = {modalVisible: false}; + * } + * + * setModalVisible(visible) { + * this.setState({modalVisible: visible}); + * } + * + * render() { + * return ( + * + * {alert("Modal has been closed.")}} + * > + * + * + * Hello World! + * + * { + * this.setModalVisible(!this.state.modalVisible) + * }}> + * Hide Modal + * + * + * + * + * + * + * { + * this.setModalVisible(true) + * }}> + * Show Modal + * + * + * + * ); + * } + * } + * ``` */ class Modal extends React.Component { static propTypes = { - animated: deprecatedPropType( - PropTypes.bool, - 'Use the `animationType` prop instead.' - ), + /** + * The `animationType` prop controls how the modal animates. + * + * - `slide` slides in from the bottom + * - `fade` fades into view + * - `none` appears without an animation + */ animationType: PropTypes.oneOf(['none', 'slide', 'fade']), + /** + * The `transparent` prop determines whether your modal will fill the entire view. Setting this to `true` will render the modal over a transparent background. + */ transparent: PropTypes.bool, + /** + * The `visible` prop determines whether your modal is visible. + */ visible: PropTypes.bool, + /** + * The `onRequestClose` prop allows passing a function that will be called once the modal has been dismissed. + * + * _On the Android platform, this is a required function._ + */ onRequestClose: Platform.OS === 'android' ? PropTypes.func.isRequired : PropTypes.func, + /** + * The `onShow` prop allows passing a function that will be called once the modal has been shown. + */ onShow: PropTypes.func, + animated: deprecatedPropType( + PropTypes.bool, + 'Use the `animationType` prop instead.' + ), }; static defaultProps = { diff --git a/Libraries/Storage/AsyncStorage.js b/Libraries/Storage/AsyncStorage.js index 01d76748d86869..471c5304c9f9af 100644 --- a/Libraries/Storage/AsyncStorage.js +++ b/Libraries/Storage/AsyncStorage.js @@ -9,6 +9,7 @@ * @providesModule AsyncStorage * @noflow * @flow-weak + * @jsdoc */ 'use strict'; @@ -21,18 +22,45 @@ var RCTAsyncFileStorage = NativeModules.AsyncLocalStorage; var RCTAsyncStorage = RCTAsyncRocksDBStorage || RCTAsyncSQLiteStorage || RCTAsyncFileStorage; /** - * AsyncStorage is a simple, asynchronous, persistent, key-value storage + * @class + * @description + * `AsyncStorage` is a simple, asynchronous, persistent, key-value storage * system that is global to the app. It should be used instead of LocalStorage. * - * It is recommended that you use an abstraction on top of AsyncStorage instead - * of AsyncStorage directly for anything more than light usage since it - * operates globally. + * It is recommended that you use an abstraction on top of `AsyncStorage` + * instead of `AsyncStorage` directly for anything more than light usage since + * it operates globally. * - * On iOS, AsyncStorage is backed by native code that stores small values in a serialized - * dictionary and larger values in separate files. On Android, AsyncStorage will use either - * RocksDB or SQLite based on what is available. This JS code is a simple facade that - * provides a clear JS API, real Error objects, and simple non-multi functions. Each - * method returns a `Promise` object. + * On iOS, `AsyncStorage` is backed by native code that stores small values in a + * serialized dictionary and larger values in separate files. On Android, + * `AsyncStorage` will use either [RocksDB](http://rocksdb.org/) or SQLite + * based on what is available. + * + * The `AsyncStorage` JavaScript code is a simple facade that provides a clear + * JavaScript API, real `Error` objects, and simple non-multi functions. Each + * method in the API returns a `Promise` object. + * + * Persisting data: + * ``` + * try { + * await AsyncStorage.setItem('@MySuperStore:key', 'I like to save it.'); + * } catch (error) { + * // Error saving data + * } + * ``` + * + * Fetching data: + * ``` + * try { + * const value = await AsyncStorage.getItem('@MySuperStore:key'); + * if (value !== null){ + * // We have data!! + * console.log(value); + * } + * } catch (error) { + * // Error retrieving data + * } + * ``` */ var AsyncStorage = { _getRequests: ([]: Array), @@ -40,8 +68,12 @@ var AsyncStorage = { _immediate: (null: ?number), /** - * Fetches `key` and passes the result to `callback`, along with an `Error` if - * there is any. Returns a `Promise` object. + * Fetches an item for a `key` and invokes a callback upon completion. + * Returns a `Promise` object. + * @param key Key of the item to fetch. + * @param callback Function that will be called with a result if found or + * any error. + * @returns A `Promise` object. */ getItem: function( key: string, @@ -63,8 +95,12 @@ var AsyncStorage = { }, /** - * Sets `value` for `key` and calls `callback` on completion, along with an - * `Error` if there is any. Returns a `Promise` object. + * Sets the value for a `key` and invokes a callback upon completion. + * Returns a `Promise` object. + * @param key Key of the item to set. + * @param value Value to set for the `key`. + * @param callback Function that will be called with any error. + * @returns A `Promise` object. */ setItem: function( key: string, @@ -85,7 +121,11 @@ var AsyncStorage = { }, /** + * Removes an item for a `key` and invokes a callback upon completion. * Returns a `Promise` object. + * @param key Key of the item to remove. + * @param callback Function that will be called with any error. + * @returns A `Promise` object. */ removeItem: function( key: string, @@ -105,32 +145,39 @@ var AsyncStorage = { }, /** - * Merges existing value with input value, assuming they are stringified json. - * Returns a `Promise` object. Not supported by all native implementations. + * Merges an existing `key` value with an input value, assuming both values + * are stringified JSON. Returns a `Promise` object. * - * Example: - * ```javascript + * **NOTE:** This is not supported by all native implementations. + * + * @param key Key of the item to modify. + * @param value New value to merge for the `key`. + * @param callback Function that will be called with any error. + * @returns A `Promise` object. + * + * @example Example * let UID123_object = { * name: 'Chris', * age: 30, * traits: {hair: 'brown', eyes: 'brown'}, * }; - - // need only define what will be added or updated + * // You only need to define what will be added or updated * let UID123_delta = { * age: 31, * traits: {eyes: 'blue', shoe_size: 10} * }; - + * * AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => { * AsyncStorage.mergeItem('UID123', JSON.stringify(UID123_delta), () => { * AsyncStorage.getItem('UID123', (err, result) => { * console.log(result); - * // => {'name':'Chris','age':31,'traits':{'shoe_size':10,'hair':'brown','eyes':'blue'}} * }); * }); * }); - * ``` + * + * // Console log result: + * // => {'name':'Chris','age':31,'traits': + * // {'shoe_size':10,'hair':'brown','eyes':'blue'}} */ mergeItem: function( key: string, @@ -151,9 +198,11 @@ var AsyncStorage = { }, /** - * Erases *all* AsyncStorage for all clients, libraries, etc. You probably - * don't want to call this - use removeItem or multiRemove to clear only your - * own keys instead. Returns a `Promise` object. + * Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably + * don't want to call this; use `removeItem` or `multiRemove` to clear only + * your app's keys. Returns a `Promise` object. + * @param callback Function that will be called with any error. + * @returns A `Promise` object. */ clear: function(callback?: ?(error: ?Error) => void): Promise { return new Promise((resolve, reject) => { @@ -169,9 +218,12 @@ var AsyncStorage = { }, /** - * Gets *all* keys known to the app, for all callers, libraries, etc. Returns a `Promise` object. + * Gets *all* keys known to your app; for all callers, libraries, etc. + * Returns a `Promise` object. + * @param callback Function that will be called the keys found and any error. + * @returns A `Promise` object. * - * Example: see multiGet for example + * Example: see the `multiGet` example. */ getAllKeys: function(callback?: ?(error: ?Error, keys: ?Array) => void): Promise { return new Promise((resolve, reject) => { @@ -196,7 +248,7 @@ var AsyncStorage = { * indicate which key caused the error. */ - /** Flushes any pending requests using a single multiget */ + /** Flushes any pending requests using a single batch call to get the data. */ flushGetRequests: function(): void { const getRequests = this._getRequests; const getKeys = this._getKeys; @@ -225,13 +277,23 @@ var AsyncStorage = { }, /** - * multiGet invokes callback with an array of key-value pair arrays that - * matches the input format of multiSet. Returns a `Promise` object. + * This allows you to batch the fetching of items given an array of `key` + * inputs. Your callback will be invoked with an array of corresponding + * key-value pairs found: * - * multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']]) + * ``` + * multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']]) + * ``` + * + * The method returns a `Promise` object. + * + * @param keys Array of key for the items to get. + * @param callback Function that will be called with a key-value array of + * the results, plus an array of any key-specific errors found. + * @returns A `Promise` object. + * + * @example Example * - * Example: - * ```javascript * AsyncStorage.getAllKeys((err, keys) => { * AsyncStorage.multiGet(keys, (err, stores) => { * stores.map((result, i, store) => { @@ -241,7 +303,6 @@ var AsyncStorage = { * }); * }); * }); - * ``` */ multiGet: function( keys: Array, @@ -280,12 +341,20 @@ var AsyncStorage = { }, /** - * multiSet and multiMerge take arrays of key-value array pairs that match - * the output of multiGet, e.g. Returns a `Promise` object. + * Use this as a batch operation for storing multiple key-value pairs. When + * the operation completes you'll get a single callback with any errors: * - * multiSet([['k1', 'val1'], ['k2', 'val2']], cb); + * ``` + * multiSet([['k1', 'val1'], ['k2', 'val2']], cb); + * ``` + * + * The method returns a `Promise` object. * - * Example: see multiMerge for an example + * @param keyValuePairs Array of key-value array for the items to set. + * @param callback Function that will be called with an array of any + * key-specific errors found. + * @returns A `Promise` object. + * Example: see the `multiMerge` example. */ multiSet: function( keyValuePairs: Array>, @@ -305,16 +374,20 @@ var AsyncStorage = { }, /** - * Delete all the keys in the `keys` array. Returns a `Promise` object. + * Call this to batch the deletion of all keys in the `keys` array. Returns + * a `Promise` object. * - * Example: - * ```javascript + * @param keys Array of key for the items to delete. + * @param callback Function that will be called an array of any key-specific + * errors found. + * @returns A `Promise` object. + * + * @example Example * let keys = ['k1', 'k2']; * AsyncStorage.multiRemove(keys, (err) => { * // keys k1 & k2 removed, if they existed * // do most stuff after removal (if you want) * }); - * ``` */ multiRemove: function( keys: Array, @@ -334,42 +407,47 @@ var AsyncStorage = { }, /** - * Merges existing values with input values, assuming they are stringified - * json. Returns a `Promise` object. + * Batch operation to merge in existing and new values for a given set of + * keys. This assumes that the values are stringified JSON. Returns a + * `Promise` object. * - * Not supported by all native implementations. + * **NOTE**: This is not supported by all native implementations. * - * Example: - * ```javascript - // first user, initial values + * @param keyValuePairs Array of key-value array for the items to merge. + * @param callback Function that will be called with an array of any + * key-specific errors found. + * @returns A `Promise` object. + * + * @example Example + * // first user, initial values * let UID234_object = { * name: 'Chris', * age: 30, * traits: {hair: 'brown', eyes: 'brown'}, * }; - + * * // first user, delta values * let UID234_delta = { * age: 31, * traits: {eyes: 'blue', shoe_size: 10}, * }; - + * * // second user, initial values * let UID345_object = { * name: 'Marge', * age: 25, * traits: {hair: 'blonde', eyes: 'blue'}, * }; - + * * // second user, delta values * let UID345_delta = { * age: 26, * traits: {eyes: 'green', shoe_size: 6}, * }; - + * * let multi_set_pairs = [['UID234', JSON.stringify(UID234_object)], ['UID345', JSON.stringify(UID345_object)]] * let multi_merge_pairs = [['UID234', JSON.stringify(UID234_delta)], ['UID345', JSON.stringify(UID345_delta)]] - + * * AsyncStorage.multiSet(multi_set_pairs, (err) => { * AsyncStorage.multiMerge(multi_merge_pairs, (err) => { * AsyncStorage.multiGet(['UID234','UID345'], (err, stores) => { @@ -377,13 +455,14 @@ var AsyncStorage = { * let key = store[i][0]; * let val = store[i][1]; * console.log(key, val); - * // => UID234 {"name":"Chris","age":31,"traits":{"shoe_size":10,"hair":"brown","eyes":"blue"}} - * // => UID345 {"name":"Marge","age":26,"traits":{"shoe_size":6,"hair":"blonde","eyes":"green"}} * }); * }); * }); * }); - * ``` + * + * // Console log results: + * // => UID234 {"name":"Chris","age":31,"traits":{"shoe_size":10,"hair":"brown","eyes":"blue"}} + * // => UID345 {"name":"Marge","age":26,"traits":{"shoe_size":6,"hair":"blonde","eyes":"green"}} */ multiMerge: function( keyValuePairs: Array>, diff --git a/Libraries/StyleSheet/LayoutPropTypes.js b/Libraries/StyleSheet/LayoutPropTypes.js index 3d6b7345fbf08c..384c4581bc34b6 100644 --- a/Libraries/StyleSheet/LayoutPropTypes.js +++ b/Libraries/StyleSheet/LayoutPropTypes.js @@ -20,48 +20,252 @@ var ReactPropTypes = require('ReactPropTypes'); * * The implementation in css-layout is slightly different from what the * Flexbox spec defines - for example, we chose more sensible default - * values. Please refer to the css-layout README for details. + * values. Since our layout docs are generated from the comments in this + * file, please keep a brief comment describing each prop type. * * These properties are a subset of our styles that are consumed by the layout * algorithm and affect the positioning and sizing of views. */ var LayoutPropTypes = { + /** `width` sets the width of this component. + * + * It works similarly to `width` in CSS, but in React Native you + * must use logical pixel units, rather than percents, ems, or any of that. + * See http://www.w3schools.com/cssref/pr_dim_width.asp for more details. + */ width: ReactPropTypes.number, + + /** `height` sets the height of this component. + * + * It works similarly to `height` in CSS, but in React Native you + * must use logical pixel units, rather than percents, ems, or any of that. + * See http://www.w3schools.com/cssref/pr_dim_width.asp for more details. + */ height: ReactPropTypes.number, + + /** `top` is the number of logical pixels to offset the top edge of + * this component. + * + * It works similarly to `top` in CSS, but in React Native you must + * use logical pixel units, rather than percents, ems, or any of that. + * + * See https://developer.mozilla.org/en-US/docs/Web/CSS/top + * for more details of how `top` affects layout. + */ top: ReactPropTypes.number, + + /** `left` is the number of logical pixels to offset the left edge of + * this component. + * + * It works similarly to `left` in CSS, but in React Native you must + * use logical pixel units, rather than percents, ems, or any of that. + * + * See https://developer.mozilla.org/en-US/docs/Web/CSS/left + * for more details of how `left` affects layout. + */ left: ReactPropTypes.number, + + /** `right` is the number of logical pixels to offset the right edge of + * this component. + * + * It works similarly to `right` in CSS, but in React Native you must + * use logical pixel units, rather than percents, ems, or any of that. + * + * See https://developer.mozilla.org/en-US/docs/Web/CSS/right + * for more details of how `right` affects layout. + */ right: ReactPropTypes.number, + + /** `bottom` is the number of logical pixels to offset the bottom edge of + * this component. + * + * It works similarly to `bottom` in CSS, but in React Native you must + * use logical pixel units, rather than percents, ems, or any of that. + * + * See https://developer.mozilla.org/en-US/docs/Web/CSS/bottom + * for more details of how `top` affects layout. + */ bottom: ReactPropTypes.number, + + /** `minWidth` is the minimum width for this component, in logical pixels. + * + * It works similarly to `min-width` in CSS, but in React Native you + * must use logical pixel units, rather than percents, ems, or any of that. + * + * See http://www.w3schools.com/cssref/pr_dim_min-width.asp + * for more details. + */ minWidth: ReactPropTypes.number, + + /** `maxWidth` is the maximum width for this component, in logical pixels. + * + * It works similarly to `max-width` in CSS, but in React Native you + * must use logical pixel units, rather than percents, ems, or any of that. + * + * See http://www.w3schools.com/cssref/pr_dim_max-width.asp + * for more details. + */ maxWidth: ReactPropTypes.number, + + /** `minHeight` is the minimum height for this component, in logical pixels. + * + * It works similarly to `min-height` in CSS, but in React Native you + * must use logical pixel units, rather than percents, ems, or any of that. + * + * See http://www.w3schools.com/cssref/pr_dim_min-height.asp + * for more details. + */ minHeight: ReactPropTypes.number, + + /** `maxHeight` is the maximum height for this component, in logical pixels. + * + * It works similarly to `max-height` in CSS, but in React Native you + * must use logical pixel units, rather than percents, ems, or any of that. + * + * See http://www.w3schools.com/cssref/pr_dim_max-height.asp + * for more details. + */ maxHeight: ReactPropTypes.number, + + /** Setting `margin` has the same effect as setting each of + * `marginTop`, `marginLeft`, `marginBottom`, and `marginRight`. + */ margin: ReactPropTypes.number, + + /** Setting `marginVertical` has the same effect as setting both + * `marginTop` and `marginBottom`. + */ marginVertical: ReactPropTypes.number, + + /** Setting `marginHorizontal` has the same effect as setting + * both `marginLeft` and `marginRight`. + */ marginHorizontal: ReactPropTypes.number, + + /** `marginTop` works like `margin-top` in CSS. + * See http://www.w3schools.com/cssref/pr_margin-top.asp + * for more details. + */ marginTop: ReactPropTypes.number, + + /** `marginBottom` works like `margin-bottom` in CSS. + * See http://www.w3schools.com/cssref/pr_margin-bottom.asp + * for more details. + */ marginBottom: ReactPropTypes.number, + + /** `marginLeft` works like `margin-left` in CSS. + * See http://www.w3schools.com/cssref/pr_margin-left.asp + * for more details. + */ marginLeft: ReactPropTypes.number, + + /** `marginRight` works like `margin-right` in CSS. + * See http://www.w3schools.com/cssref/pr_margin-right.asp + * for more details. + */ marginRight: ReactPropTypes.number, + + /** `padding` works like `padding` in CSS. + * It's like setting each of `paddingTop`, `paddingBottom`, + * `paddingLeft`, and `paddingRight` to the same thing. + * See http://www.w3schools.com/css/css_padding.asp + * for more details. + */ padding: ReactPropTypes.number, + + /** Setting `paddingVertical` is like setting both of + * `paddingTop` and `paddingBottom`. + */ paddingVertical: ReactPropTypes.number, + + /** Setting `paddingHorizontal` is like setting both of + * `paddingLeft` and `paddingRight`. + */ paddingHorizontal: ReactPropTypes.number, + + /** `paddingTop` works like `padding-top` in CSS. + * See http://www.w3schools.com/cssref/pr_padding-top.asp + * for more details. + */ paddingTop: ReactPropTypes.number, + + /** `paddingBottom` works like `padding-bottom` in CSS. + * See http://www.w3schools.com/cssref/pr_padding-bottom.asp + * for more details. + */ paddingBottom: ReactPropTypes.number, + + /** `paddingLeft` works like `padding-left` in CSS. + * See http://www.w3schools.com/cssref/pr_padding-left.asp + * for more details. + */ paddingLeft: ReactPropTypes.number, + + /** `paddingRight` works like `padding-right` in CSS. + * See http://www.w3schools.com/cssref/pr_padding-right.asp + * for more details. + */ paddingRight: ReactPropTypes.number, + + /** `borderWidth` works like `border-width` in CSS. + * See http://www.w3schools.com/cssref/pr_border-width.asp + * for more details. + */ borderWidth: ReactPropTypes.number, + + /** `borderTopWidth` works like `border-top-width` in CSS. + * See http://www.w3schools.com/cssref/pr_border-top_width.asp + * for more details. + */ borderTopWidth: ReactPropTypes.number, + + /** `borderRightWidth` works like `border-right-width` in CSS. + * See http://www.w3schools.com/cssref/pr_border-right_width.asp + * for more details. + */ borderRightWidth: ReactPropTypes.number, + + /** `borderBottomWidth` works like `border-bottom-width` in CSS. + * See http://www.w3schools.com/cssref/pr_border-bottom_width.asp + * for more details. + */ borderBottomWidth: ReactPropTypes.number, + + /** `borderLeftWidth` works like `border-left-width` in CSS. + * See http://www.w3schools.com/cssref/pr_border-bottom_width.asp + * for more details. + */ borderLeftWidth: ReactPropTypes.number, + /** `position` in React Native is similar to regular CSS, but + * everything is set to `relative` by default, so `absolute` + * positioning is always just relative to the parent. + * + * If you want to position a child using specific numbers of logical + * pixels relative to its parent, set the child to have `absolute` + * position. + * + * If you want to position a child relative to something + * that is not its parent, just don't use styles for that. Use the + * component tree. + * + * See https://github.com/facebook/css-layout + * for more details on how `position` differs between React Native + * and CSS. + */ position: ReactPropTypes.oneOf([ 'absolute', 'relative' ]), - // https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction + /** `flexDirection` controls which directions children of a container go. + * `row` goes left to right, `column` goes top to bottom, and you may + * be able to guess what the other two do. It works like `flex-direction` + * in CSS, except the default is `column`. See + * https://css-tricks.com/almanac/properties/f/flex-direction/ + * for more detail. + */ flexDirection: ReactPropTypes.oneOf([ 'row', 'row-reverse', @@ -69,14 +273,24 @@ var LayoutPropTypes = { 'column-reverse' ]), - // https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap + /** `flexWrap` controls whether children can wrap around after they + * hit the end of a flex container. + * It works like `flex-wrap` in CSS. See + * https://css-tricks.com/almanac/properties/f/flex-wrap/ + * for more detail. + */ flexWrap: ReactPropTypes.oneOf([ 'wrap', 'nowrap' ]), - // How to align children in the main direction - // https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content + /** `justifyContent` aligns children in the main direction. + * For example, if children are flowing vertically, `justifyContent` + * controls how they align vertically. + * It works like `justify-content` in CSS. See + * https://css-tricks.com/almanac/properties/j/justify-content/ + * for more detail. + */ justifyContent: ReactPropTypes.oneOf([ 'flex-start', 'flex-end', @@ -85,8 +299,14 @@ var LayoutPropTypes = { 'space-around' ]), - // How to align children in the cross direction - // https://developer.mozilla.org/en-US/docs/Web/CSS/align-items + /** `alignItems` aligns children in the cross direction. + * For example, if children are flowing vertically, `alignItems` + * controls how they align horizontally. + * It works like `align-items` in CSS, except the default value + * is `stretch` instead of `flex-start`. See + * https://css-tricks.com/almanac/properties/a/align-items/ + * for more detail. + */ alignItems: ReactPropTypes.oneOf([ 'flex-start', 'flex-end', @@ -94,8 +314,12 @@ var LayoutPropTypes = { 'stretch' ]), - // How to align the element in the cross direction - // https://developer.mozilla.org/en-US/docs/Web/CSS/align-items + /** `alignSelf` controls how a child aligns in the cross direction, + * overriding the `alignItems` of the parent. It works like `align-self` + * in CSS. See + * https://css-tricks.com/almanac/properties/a/align-self/ + * for more detail. + */ alignSelf: ReactPropTypes.oneOf([ 'auto', 'flex-start', @@ -104,10 +328,37 @@ var LayoutPropTypes = { 'stretch' ]), - // https://developer.mozilla.org/en-US/docs/Web/CSS/flex + /** In React Native `flex` does not work the same way that it does in CSS. + * `flex` is a number rather than a string, and it works + * according to the `css-layout` library + * at https://github.com/facebook/css-layout . + * + * When `flex` is a positive number, it makes the component flexible + * and it will be sized proportional to its flex value. So a + * component with `flex` set to 2 will take twice the space as a + * component with `flex` set to 1. + * + * When `flex` is 0, the component is sized according to `width` + * and `height` and it is inflexible. + * + * When `flex` is -1, the component is normally sized according + * `width` and `height`. However, if there's not enough space, + * the component will shrink to its `minWidth` and `minHeight`. + */ flex: ReactPropTypes.number, - // https://developer.mozilla.org/en-US/docs/Web/CSS/z-index + /** `zIndex` controls which components display on top of others. + * Normally, you don't use `zIndex`. Components render according to + * their order in the document tree, so later components draw over + * earlier ones. `zIndex` may be useful if you have animations or custom + * modal interfaces where you don't want this behavior. + * + * It works like the CSS `z-index` property - components with a larger + * `zIndex` will render on top. Think of the z-direction like it's + * pointing from the phone into your eyeball. See + * https://developer.mozilla.org/en-US/docs/Web/CSS/z-index for + * more detail. + */ zIndex: ReactPropTypes.number, }; diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index aab015b6b3252e..0ebfac844f77c7 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -36,27 +36,42 @@ const viewConfig = { }; /** - * A React component for displaying text which supports nesting, - * styling, and touch handling. In the following example, the nested title and - * body text will inherit the `fontFamily` from `styles.baseText`, but the title - * provides its own additional styles. The title and body will stack on top of - * each other on account of the literal newlines: + * A React component for displaying text. * - * ``` - * renderText: function() { - * return ( - * - * - * {this.state.titleText + '\n\n'} - * - * - * {this.state.bodyText} + * `Text` supports nesting, styling, and touch handling. + * + * In the following example, the nested title and body text will inherit the `fontFamily` from + *`styles.baseText`, but the title provides its own additional styles. The title and body will + * stack on top of each other on account of the literal newlines: + * + * ```ReactNativeWebPlayer + * import React, { Component } from 'react'; + * import { AppRegistry, Text, StyleSheet } from 'react-native'; + * + * class TextInANest extends Component { + * constructor(props) { + * super(props); + * this.state = { + * titleText: "Bird's Nest", + * bodyText: 'This is not really a bird nest.' + * }; + * } + * + * render() { + * return ( + * + * + * {this.state.titleText}

+ *
+ * + * {this.state.bodyText} + * *
- *
- * ); - * }, - * ... - * var styles = StyleSheet.create({ + * ); + * } + * } + * + * const styles = StyleSheet.create({ * baseText: { * fontFamily: 'Cochin', * }, @@ -64,21 +79,39 @@ const viewConfig = { * fontSize: 20, * fontWeight: 'bold', * }, - * }; + * }); + * + * // App registration and rendering + * AppRegistry.registerComponent('TextInANest', () => TextInANest); * ``` */ const Text = React.createClass({ propTypes: { /** - * Line Break mode. Works only with numberOfLines. - * clip is working only for iOS + * Line Break mode. This can be one of the following values: + * + * - `head` - The line is displayed so that the end fits in the container and the missing text + * at the beginning of the line is indicated by an ellipsis glyph. e.g., "...wxyz" + * - `middle` - The line is displayed so that the beginning and end fit in the container and the + * missing text in the middle is indicated by an ellipsis glyph. "ab...yz" + * - `tail` - The line is displayed so that the beginning fits in the container and the + * missing text at the end of the line is indicated by an ellipsis glyph. e.g., "abcd..." + * - `clip` - Lines are not drawn past the edge of the text container. + * + * The default is `tail`. + * + * `numberOfLines` must be set in conjunction with this prop. + * + * > `clip` is working only for iOS */ lineBreakMode: React.PropTypes.oneOf(['head', 'middle', 'tail', 'clip']), /** * Used to truncate the text with an ellipsis after computing the text * layout, including line wrapping, such that the total number of lines * does not exceed this number. + * + * This prop is commonly used with `lineBreakMode`. */ numberOfLines: React.PropTypes.number, /** @@ -89,15 +122,26 @@ const Text = React.createClass({ onLayout: React.PropTypes.func, /** * This function is called on press. + * + * e.g., `onPress={() => console.log('1st')}`` */ onPress: React.PropTypes.func, /** * This function is called on long press. + * + * e.g., `onLongPress={this.increaseSize}>`` */ onLongPress: React.PropTypes.func, /** - * When true, no visual change is made when text is pressed down. By + * Lets the user select text, to use the native copy and paste functionality. + * + * @platform android + */ + selectable: React.PropTypes.bool, + /** + * When `true`, no visual change is made when text is pressed down. By * default, a gray oval highlights the text on press down. + * * @platform ios */ suppressHighlighting: React.PropTypes.bool, @@ -107,10 +151,21 @@ const Text = React.createClass({ */ testID: React.PropTypes.string, /** - * Specifies should fonts scale to respect Text Size accessibility setting on iOS. + * Specifies whether fonts should scale to respect Text Size accessibility setting on iOS. The + * default is `true`. + * * @platform ios */ allowFontScaling: React.PropTypes.bool, + /** + * When set to `true`, indicates that the view is an accessibility element. The default value + * for a `Text` element is `true`. + * + * See the + * [Accessibility guide](/react-native/docs/accessibility.html#accessible-ios-android) + * for more information. + */ + accessible: React.PropTypes.bool, }, getDefaultProps(): Object { return { diff --git a/Libraries/Utilities/AlertIOS.js b/Libraries/Utilities/AlertIOS.js index 1da237b0c23e5f..50a5accc42670d 100644 --- a/Libraries/Utilities/AlertIOS.js +++ b/Libraries/Utilities/AlertIOS.js @@ -8,64 +8,129 @@ * * @providesModule AlertIOS * @flow + * @jsdoc */ 'use strict'; var RCTAlertManager = require('NativeModules').AlertManager; +/** + * An Alert button type + */ export type AlertType = $Enum<{ + /** + * Default alert with no inputs + */ 'default': string; + /** + * Plain text input alert + */ 'plain-text': string; + /** + * Secure text input alert + */ 'secure-text': string; + /** + * Login and password alert + */ 'login-password': string; }>; +/** + * An Alert button style + */ export type AlertButtonStyle = $Enum<{ + /** + * Default button style + */ 'default': string; + /** + * Cancel button style + */ 'cancel': string; + /** + * Destructive button style + */ 'destructive': string; }>; +/** + * Array or buttons + * @typedef {Array} ButtonsArray + * @property {string=} text Button label + * @property {Function=} onPress Callback function when button pressed + * @property {AlertButtonStyle=} style Button style + */ type ButtonsArray = Array<{ + /** + * Button label + */ text?: string; + /** + * Callback function when button pressed + */ onPress?: ?Function; + /** + * Button style + */ style?: AlertButtonStyle; }>; /** - * The AlertsIOS utility provides two functions: `alert` and `prompt`. All - * functionality available through `AlertIOS.alert` is also available in the - * cross-platform `Alert.alert`, which we recommend you use if you don't need - * iOS-specific functionality. + * @description + * `AlertIOS` provides functionality to create an iOS alert dialog with a + * message or create a prompt for user input. + * + * Creating an iOS alert: * - * `AlertIOS.prompt` allows you to prompt the user for input inside of an - * alert popup. + * ``` + * AlertIOS.alert( + * 'Sync Complete', + * 'All your data are belong to us.' + * ); + * ``` + * + * Creating an iOS prompt: + * + * ``` + * AlertIOS.prompt( + * 'Enter a value', + * null, + * text => console.log("You entered "+text) + * ); + * ``` + * + * We recommend using the [`Alert.alert`](/docs/alert.html) method for + * cross-platform support if you don't need to create iOS-only prompts. * */ class AlertIOS { /** - * Creates a popup to alert the user. See - * [Alert](docs/alert.html). - * - * - title: string -- The dialog's title. - * - message: string -- An optional message that appears above the text input. - * - callbackOrButtons -- This optional argument should be either a - * single-argument function or an array of buttons. If passed a function, - * it will be called when the user taps 'OK'. + * Create and display a popup alert. + * @static + * @method alert + * @param title The dialog's title. + * @param message An optional message that appears below + * the dialog's title. + * @param callbackOrButtons This optional argument should + * be either a single-argument function or an array of buttons. If passed + * a function, it will be called when the user taps 'OK'. * * If passed an array of button configurations, each button should include - * a `text` key, as well as optional `onPress` and `style` keys. - * `style` should be one of 'default', 'cancel' or 'destructive'. - * - type -- *deprecated, do not use* + * a `text` key, as well as optional `onPress` and `style` keys. `style` + * should be one of 'default', 'cancel' or 'destructive'. + * @param type Deprecated, do not use. * - * Example: + * @example Example with custom buttons * - * ``` * AlertIOS.alert( - * 'Sync Complete', - * 'All your data are belong to us.' + * 'Update available', + * 'Keep your app up to date to enjoy the latest features', + * [ + * {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'}, + * {text: 'Install', onPress: () => console.log('Install Pressed')}, + * ], * ); - * ``` */ static alert( title: ?string, @@ -82,23 +147,26 @@ class AlertIOS { } /** - * Prompt the user to enter some text. - * - * - title: string -- The dialog's title. - * - message: string -- An optional message that appears above the text input. - * - callbackOrButtons -- This optional argument should be either a - * single-argument function or an array of buttons. If passed a function, - * it will be called with the prompt's value when the user taps 'OK'. + * Create and display a prompt to enter some text. + * @static + * @method prompt + * @param title The dialog's title. + * @param message An optional message that appears above the text + * input. + * @param callbackOrButtons This optional argument should + * be either a single-argument function or an array of buttons. If passed + * a function, it will be called with the prompt's value when the user + * taps 'OK'. * * If passed an array of button configurations, each button should include - * a `text` key, as well as optional `onPress` and `style` keys (see example). - * `style` should be one of 'default', 'cancel' or 'destructive'. - * - type: string -- This configures the text input. One of 'plain-text', + * a `text` key, as well as optional `onPress` and `style` keys (see + * example). `style` should be one of 'default', 'cancel' or 'destructive'. + * @param type This configures the text input. One of 'plain-text', * 'secure-text' or 'login-password'. - * - defaultValue: string -- the default value for the text field. + * @param defaultValue The dialog's title. + * + * @example Example with custom buttons * - * Example with custom buttons: - * ``` * AlertIOS.prompt( * 'Enter password', * 'Enter your password to claim your $1.5B in lottery winnings', @@ -108,18 +176,16 @@ class AlertIOS { * ], * 'secure-text' * ); - * ``` * - * Example with the default button and a custom callback: - * ``` + * @example Example with the default button and a custom callback + * * AlertIOS.prompt( * 'Update username', * null, * text => console.log("Your username is "+text), * null, * 'default' - * ) - * ``` + * ); */ static prompt( title: ?string, diff --git a/docs/Accessibility.md b/docs/Accessibility.md index 0c5f110689b357..a1807b10842af7 100644 --- a/docs/Accessibility.md +++ b/docs/Accessibility.md @@ -4,7 +4,7 @@ title: Accessibility layout: docs category: Guides permalink: docs/accessibility.html -next: direct-manipulation +next: timers --- ## Native App Accessibility (iOS and Android) diff --git a/docs/AndroidBuildingFromSource.md b/docs/AndroidBuildingFromSource.md index 5336f668ed7d26..9c4cdb916fbb7a 100644 --- a/docs/AndroidBuildingFromSource.md +++ b/docs/AndroidBuildingFromSource.md @@ -20,13 +20,25 @@ Make sure you have the following installed: 3. Local Maven repository for Support Libraries (formerly `Android Support Repository`) >= 17 (for Android Support Library) 4. Android NDK (download links and installation instructions below) -Point Gradle to your Android SDK: either have `$ANDROID_SDK` and `$ANDROID_NDK ` defined, or create a local.properties file in the root of your react-native checkout with the following contents: +### Point Gradle to your Android SDK: + +**Step 1:** Set environment variables through your local shell. + +Note: Files may vary based on shell flavor. See below for examples from common shells. + +- bash: `.bash_profile` or `.bashrc` +- zsh: `.zprofile` or `.zshrc` +- ksh: `.profile` or `$ENV` + +Example: ``` -sdk.dir=absolute_path_to_android_sdk -ndk.dir=absolute_path_to_android_ndk +export ANDROID_SDK=/Users/your_unix_name/android-sdk-macosx +export ANDROID_NDK=/Users/your_unix_name/android-ndk/android-ndk-r10e ``` +**Step 2:** Create a `local.properties` file in the `android` directory of your react-native app with the following contents: + Example: ``` diff --git a/docs/Animations.md b/docs/Animations.md index 5eff3d3c53f6e8..19629b6cb8102f 100644 --- a/docs/Animations.md +++ b/docs/Animations.md @@ -24,13 +24,13 @@ component with a simple spring bounce on mount looks like this: ```javascript class Playground extends React.Component { - constructor(props: any) { + constructor(props) { super(props); this.state = { bounceValue: new Animated.Value(0), }; } - render(): ReactElement { + render() { return ( ); } -}; +} ``` [Run this example](https://rnplay.org/apps/uaQrGQ) diff --git a/docs/Colors.md b/docs/Colors.md index aba269085a2b22..9d863adfaac170 100644 --- a/docs/Colors.md +++ b/docs/Colors.md @@ -2,8 +2,9 @@ id: colors title: Colors layout: docs -category: Polyfills +category: Guides permalink: docs/colors.html +next: images --- The following formats are supported: diff --git a/docs/Debugging.md b/docs/Debugging.md index a3143a77811157..55a940f0dcb015 100644 --- a/docs/Debugging.md +++ b/docs/Debugging.md @@ -7,73 +7,91 @@ permalink: docs/debugging.html next: testing --- -## In-app Errors and Warnings +## Accessing the In-App Developer Menu -Errors and warnings are displayed inside your app in development builds. +You can access the developer menu by shaking your device or by selecting "Shake Gesture" inside the Hardware menu in the iOS Simulator. You can also use the **`Command`**`⌘` + **`D`** keyboard shortcut when your app is running in the iPhone Simulator, or **`Command`**`⌘` + **`M`** when running in an Android emulator. -### Errors +![](img/DeveloperMenu.png) -In-app errors are displayed in a full screen alert with a red background inside your app. This screen is known as a RedBox. You can use `console.error()` to manually trigger one. +> The Developer Menu is disabled in release (production) builds. -### Warnings +## Reloading JavaScript -Warnings will be displayed on screen with a yellow background. These alerts are known as YellowBoxes. Click on the alerts to show more information or to dismiss them. +Instead of recompiling your app every time you make a change, you can reload your app's JavaScript code instantly. To do so, select "Reload" from the Developer Menu. You can also press **`Command`**`⌘` + **`R`** in the iOS Simulator, or press **`R`** twice on Android emulators. -As with a RedBox, you can use `console.warn()` to trigger a YellowBox. +> If the **`Command`**`⌘` + **`R`** keyboard shortcut does not seem to reload the iOS Simulator, go to the Hardware menu, select Keyboard, and make sure that "Connect Hardware Keyboard" is checked. -YellowBoxes can be disabled during development by using `console.disableYellowBox = true;`. Specific warnings can be ignored programmatically by setting an array of prefixes that should be ignored: `console.ignoredYellowBox = ['Warning: ...'];` +### Automatic reloading -> RedBoxes and YellowBoxes are automatically disabled in release (production) builds. +You can speed up your development times by having your app reload automatically any time your code changes. Automatic reloading can be enabled by selecting "Enable Live Reload" from the Developer Menu. -## Accessing the In-App Developer Menu +You may even go a step further and keep your app running as new versions of your files are injected into the JavaScript bundle automatically by enabling [Hot Reloading](https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html) from the Developer Menu. This will allow you to persist the app's state through reloads. -You can access the developer menu by shaking your device. You can also use the `Command⌘ + D` keyboard shortcut when your app is running in the iPhone Simulator, or `Command⌘ + M` when running in an Android emulator. +> There are some instances where hot reloading cannot be implemented perfectly. If you run into any issues, use a full reload to reset your app. -> The Developer Menu is disabled in release (production) builds. +You will need to rebuild your app for changes to take effect in certain situations: -## Reloading JavaScript +* You have added new resources to your native app's bundle, such as an image in `Images.xcassets` on iOS or the `res/drawable` folder on Android. +* You have modified native code (Objective-C/Swift on iOS or Java/C++ on Android). + +## In-app Errors and Warnings -Selecting `Reload` from the Developer Menu will reload the JavaScript that powers your application. You can also press `Command⌘ + R` in the iOS Simulator, or press `R` twice on Android emulators. +Errors and warnings are displayed inside your app in development builds. -You will need to rebuild your app for changes to take effect in certain situations: +### Errors -* You have added new resources to your native app's bundle, such as an image in `Images.xcassets` on iOS or in `res/drawable` folder on Android. -* You have modified native code (Objective-C/Swift on iOS or Java/C++ on Android). +In-app errors are displayed in a full screen alert with a red background inside your app. This screen is known as a RedBox. You can use `console.error()` to manually trigger one. -### Automatic reloading +### Warnings -You may enable Live Reload to automatically trigger a reload whenever your JavaScript code changes. +Warnings will be displayed on screen with a yellow background. These alerts are known as YellowBoxes. Click on the alerts to show more information or to dismiss them. -Live Reload is available on iOS via the Developer Menu. On Android, select "Dev Settings" from the Developer Menu and enable "Auto reload on JS change". +As with a RedBox, you can use `console.warn()` to trigger a YellowBox. -## Accessing logs +YellowBoxes can be disabled during development by using `console.disableYellowBox = true;`. Specific warnings can be ignored programmatically by setting an array of prefixes that should be ignored: `console.ignoredYellowBox = ['Warning: ...'];` + +> RedBoxes and YellowBoxes are automatically disabled in release (production) builds. + +## Accessing console logs + +You can display the console logs for an iOS or Android app by using the following commands in a terminal while the app is running: -To view detailed logs on iOS, open your app in Xcode, then Build and Run your app on a device or the iPhone Simulator. The console should appear automatically after the app launches. +``` +$ react-native log-ios +$ react-native log-android +``` -Run `adb logcat *:S ReactNative:V ReactNativeJS:V` in a terminal to display the logs for an Android app running on a device or an emulator. +You may also access these through `Debug → Open System Log...` in the iOS Simulator or by running `adb logcat *:S ReactNative:V ReactNativeJS:V` in a terminal while an Android app is running on a device or emulator. ## Chrome Developer Tools -To debug the JavaScript code in Chrome, select `Debug JS Remotely` from the Developer Menu. This will open a new tab at [http://localhost:8081/debugger-ui](http://localhost:8081/debugger-ui). +To debug the JavaScript code in Chrome, select "Debug JS Remotely" from the Developer Menu. This will open a new tab at [http://localhost:8081/debugger-ui](http://localhost:8081/debugger-ui). -In Chrome, press `Command⌘ + Option⌥ + I` or select `View` → `Developer` → `Developer Tools` to toggle the developer tools console. Enable [Pause On Caught Exceptions](http://stackoverflow.com/questions/2233339/javascript-is-there-a-way-to-get-chrome-to-break-on-all-errors/17324511#17324511) for a better debugging experience. +Select `Tools → Developer Tools` from the Chrome Menu to open the [Developer Tools](https://developer.chrome.com/devtools). You may also access the DevTools using keyboard shortcuts (**`Command`**`⌘` + **`Option`**`⌥` + **`I`** on Mac, **`Ctrl`** + **`Shift`** + **`I`** on Windows). You may also want to enable [Pause On Caught Exceptions](http://stackoverflow.com/questions/2233339/javascript-is-there-a-way-to-get-chrome-to-break-on-all-errors/17324511#17324511) for a better debugging experience. + +> It is [currently not possible](https://github.com/facebook/react-devtools/issues/229) to use the "React" tab in the Chrome Developer Tools to inspect app widgets. You can use Nuclide's "React Native Inspector" as a workaround. ### Debugging on a device with Chrome Developer Tools -On iOS devices, open the file [`RCTWebSocketExecutor.m`](https://github.com/facebook/react-native/blob/master/Libraries/WebSocket/RCTWebSocketExecutor.m) and change `localhost` to the IP address of your computer, then select `Debug JS Remotely` from the Developer Menu. +On iOS devices, open the file [`RCTWebSocketExecutor.m`](https://github.com/facebook/react-native/blob/master/Libraries/WebSocket/RCTWebSocketExecutor.m) and change "localhost" to the IP address of your computer, then select "Debug JS Remotely" from the Developer Menu. On Android 5.0+ devices connected via USB, you can use the [`adb` command line tool](http://developer.android.com/tools/help/adb.html) to setup port forwarding from the device to your computer: `adb reverse tcp:8081 tcp:8081` -Alternatively, select `Dev Settings` from the Developer Menu, then update the `Debug server host for device` setting to match the IP address of your computer. +Alternatively, select "Dev Settings" from the Developer Menu, then update the "Debug server host for device" setting to match the IP address of your computer. + +> If you run into any issues, it may be possible that one of your Chrome extensions is interacting in unexpected ways with the debugger. Try disabling all of your extensions and re-enabling them one-by-one until you find the problematic extension. + ### Debugging using a custom JavaScript debugger -To use a custom JavaScript debugger in place of Chrome Developer Tools, set the `REACT_DEBUGGER` environment variable to a command that will start your custom debugger. You can then select `Debug JS Remotely` from the Developer Menu to start debugging. +To use a custom JavaScript debugger in place of Chrome Developer Tools, set the `REACT_DEBUGGER` environment variable to a command that will start your custom debugger. You can then select "Debug JS Remotely" from the Developer Menu to start debugging. + +The debugger will receive a list of all project roots, separated by a space. For example, if you set `REACT_DEBUGGER="node /path/to/launchDebugger.js --port 2345 --type ReactNative"`, then the command `node /path/to/launchDebugger.js --port 2345 --type ReactNative /path/to/reactNative/app` will be used to start your debugger. -> The debugger will receive a list of all project roots, separated by a space. For example, if you set `REACT_DEBUGGER="node /path/to/launchDebugger.js --port 2345 --type ReactNative"`, then the command `node /path/to/launchDebugger.js --port 2345 --type ReactNative /path/to/reactNative/app` will be used to start your debugger. Custom debugger commands executed this way should be short-lived processes, and they shouldn't produce more than 200 kilobytes of output. +> Custom debugger commands executed this way should be short-lived processes, and they shouldn't produce more than 200 kilobytes of output. -## FPS (Frames per Second) Monitor +## Performance Monitor -You can enable a FPS graph overlay in the Developer Menu in order to help you debug performance problems. +You can enable a performance overlay to help you debug performance problems by selecting "Perf Monitor" in the Developer Menu. diff --git a/docs/DirectManipulation.md b/docs/DirectManipulation.md index c3fb6f7f871255..1d4f6f0416ca87 100644 --- a/docs/DirectManipulation.md +++ b/docs/DirectManipulation.md @@ -32,7 +32,7 @@ uses `setNativeProps` internally to update the opacity of its child component: ```javascript -setOpacityTo: function(value) { +setOpacityTo(value) { // Redacted: animation related code this.refs[CHILD_REF].setNativeProps({ opacity: value @@ -57,9 +57,10 @@ might implement it with that constraint is to store the opacity value in the state, then update that value whenever `onPress` is fired: ```javascript -getInitialState() { - return { myButtonOpacity: 1, } -}, +constructor(props) { + super(props); + this.state = { myButtonOpacity: 1, }; +} render() { return ( @@ -93,25 +94,25 @@ Composite components are not backed by a native view, so you cannot call `setNativeProps` on them. Consider this example: ```javascript -var MyButton = React.createClass({ +class MyButton extends React.Component { render() { return ( {this.props.label} ) - }, -}); + } +} -var App = React.createClass({ +class App extends React.Component { render() { return ( ) - }, -}); + } +} ``` [Run this example](https://rnplay.org/apps/JXkgmQ) @@ -132,10 +133,10 @@ that calls `setNativeProps` on the appropriate child with the given arguments. ```javascript -var MyButton = React.createClass({ +class MyButton extends React.Component { setNativeProps(nativeProps) { this._root.setNativeProps(nativeProps); - }, + } render() { return ( @@ -143,8 +144,8 @@ var MyButton = React.createClass({ {this.props.label}
) - }, -}); + } +} ``` [Run this example](https://rnplay.org/apps/YJxnEQ) @@ -172,10 +173,15 @@ necessary. For example, the following code demonstrates clearing the input when you tap a button: ```javascript -var App = React.createClass({ +class App extends React.Component { + constructor(props) { + super(props); + this.clearText = this.clearText.bind(this); + } + clearText() { this._textInput.setNativeProps({text: ''}); - }, + } render() { return ( @@ -188,7 +194,7 @@ var App = React.createClass({
); } -}); +} ``` [Run this example](https://rnplay.org/plays/pOI9bA) diff --git a/docs/GestureResponderSystem.md b/docs/GestureResponderSystem.md index b7c8dbc40e19ee..7a61929538d6ba 100644 --- a/docs/GestureResponderSystem.md +++ b/docs/GestureResponderSystem.md @@ -4,7 +4,7 @@ title: Gesture Responder System layout: docs category: Guides permalink: docs/gesture-responder-system.html -next: animations +next: native-modules-ios --- Gesture recognition on mobile devices is much more complicated than web. A touch can go through several phases as the app determines what the user's intention is. For example, the app needs to determine if the touch is scrolling, sliding on a widget, or tapping. This can even change during the duration of a touch. There can also be multiple simultaneous touches. diff --git a/docs/QuickStart-GettingStarted.md b/docs/GettingStarted.md similarity index 65% rename from docs/QuickStart-GettingStarted.md rename to docs/GettingStarted.md index 249296abf0e91f..2532eff21a6734 100644 --- a/docs/QuickStart-GettingStarted.md +++ b/docs/GettingStarted.md @@ -2,11 +2,19 @@ id: quick-start-getting-started title: Getting Started layout: docs -category: Quick Start +category: The Basics permalink: docs/getting-started.html -next: tutorial-core-components +next: tutorial --- +Welcome to React Native! This page will help you install React Native on +your system, so that you can build apps with it right away. If you already +have React Native installed, you can skip ahead to the +[Tutorial](/react-native/docs/tutorial.html). + +The instructions are a bit different depending on your development operating system, and whether you want to start developing for iOS or Android. If you +want to develop for both iOS and Android, that's fine - you just have to pick +one to start with, since the setup is a bit different.
-Target: +Mobile OS: iOS Android Development OS: @@ -50,7 +58,7 @@ block { display: none; } ## Unsupported -
Unfortunately, Apple only lets you develop for iOS on a Mac machine. Please check out the Android instructions instead.
+
Unfortunately, Apple only lets you develop for iOS on a Mac. If you want to build an iOS app but you don't have a Mac yet, you can try starting with the Android instructions instead.
@@ -58,74 +66,57 @@ block { display: none; } -## Installing React Native +## Dependencies for Mac + iOS -There's a few things you need to install first. You will need Node.js, the React Native command line tools, Watchman, and Xcode. +You will need Xcode, node.js, the React Native command line tools, and Watchman. -## Installing React Native +## Dependencies for Mac + Android -There's a few things you need to install first. You will need Node.js, the React Native command line tools, Watchman, and Android Studio. +You will need Android Studio, node.js, the React Native command line tools, and Watchman. -#### Node.js - -We recommend installing Node.js via [Homebrew](http://brew.sh/), a popular package manager for OS X: +We recommend installing node and watchman via [Homebrew](http://brew.sh/). ``` brew install node +brew install watchman ``` -#### React Native command line tools - -Use Node's package manager to install the React Native command line tools. These will allow you to easily create your first React Native project. +Node comes with npm, which lets you install the React Native command line interface. ``` npm install -g react-native-cli ``` -> If you see the error, `EACCES: permission denied`, please run the command: -> `sudo npm install -g react-native-cli`. - -#### Watchman - -[Watchman](https://facebook.github.io/watchman/docs/install.html) is a tool by Facebook for watching -changes in the filesystem. It is recommended you install it for better performance. - -``` -brew install watchman -``` +If you get a permission error, try with sudo: `sudo npm install -g react-native-cli`. -#### Xcode - -You can install Xcode via the [Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?mt=12), or download it directly from the [Apple Developer portal](https://developer.apple.com/xcode/downloads/). +The easiest way to install Xcode is via the [Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?mt=12). -#### Android Studio - Download and install [Android Studio](https://developer.android.com/studio/install.html). -#### Gradle Daemon - -While optional, enabling [Gradle Daemon](https://docs.gradle.org/2.9/userguide/gradle_daemon.html) will greatly improve incremental build times for changes in Java code. +If you plan to make changes in Java code, we recommend [Gradle Daemon](https://docs.gradle.org/2.9/userguide/gradle_daemon.html) which speeds up the build. - + + +## Dependencies for Linux + Android -## Installing React Native + -There's a few things you need to install first. You will need Node.js, the React Native command line tools, Watchman, and Android Studio. +## Dependencies for Windows + Android -#### Node.js +You will need node.js, the React Native command line tools, Watchman, and Android Studio. @@ -133,51 +124,33 @@ Follow the [installation instructions for your Linux distribution](https://nodej -We recommend installing Node.js via [Chocolatey](https://chocolatey.org), a popular package manager for Windows. Open a Command Prompt as Administrator, then run the following command: +We recommend installing node.js and Python2 via [Chocolatey](https://chocolatey.org), a popular package manager for Windows. Open a Command Prompt as Administrator, then run: ``` choco install nodejs.install -``` - -##### Python - -The React Native command line tools require Python2. Install it using Chocolatey: - -``` choco install python2 ``` -#### React Native command line tools - -Use Node's package manager to install the React Native command line tools. These will allow you to easily create your first React Native project. +Node comes with npm, which lets you install the React Native command line interface. ``` npm install -g react-native-cli ``` -> If you see the error, `EACCES: permission denied`, please run the command: -> `sudo npm install -g react-native-cli`. - -#### Android Studio - Download and install [Android Studio](https://developer.android.com/studio/install.html). -#### Watchman - -[Watchman](https://facebook.github.io/watchman) is a tool by Facebook for watching changes in the filesystem. It is recommended you install -it for better performance. You can follow the [Watchman installation guide](https://facebook.github.io/watchman/docs/install.html#installing-from-source) to compile and install from source. +[Watchman](https://facebook.github.io/watchman) is a tool by Facebook for watching changes in the filesystem. Installing it should +improve performance, but you can also try not installing it, if the installation process is too annoying. You can follow the [Watchman installation guide](https://facebook.github.io/watchman/docs/install.html#installing-from-source) to compile and install from source. -#### Gradle Daemon - -While optional, enabling [Gradle Daemon](https://docs.gradle.org/2.9/userguide/gradle_daemon.html) will greatly improve incremental build times for changes in Java code. +If you plan to make changes in Java code, we recommend [Gradle Daemon](https://docs.gradle.org/2.9/userguide/gradle_daemon.html) which speeds up the build. @@ -193,13 +166,7 @@ cd AwesomeProject react-native run-ios ``` -If everything is set up correctly, you should see your new app running in the iOS Simulator shortly. - -> You can also -> [open the `AwesomeProject`](http://nuclide.io/docs/quick-start/getting-started/#adding-a-project) -> folder in [Nuclide](http://nuclide.io) and -> [run the application](http://nuclide.io/docs/platforms/react-native/#command-line), or open -> `ios/AwesomeProject.xcodeproj` and hit the `Run` button in Xcode. +You should see your new app running in the iOS Simulator shortly. `react-native run-ios` is just one way to run your app - you can also run it directly from within Xcode or Nuclide. @@ -211,12 +178,7 @@ cd AwesomeProject react-native run-android ``` -If everything is set up correctly, you should see your new app running in your Android emulator shortly. - -> You can also -> [open the `AwesomeProject`](http://nuclide.io/docs/quick-start/getting-started/#adding-a-project) -> folder in [Nuclide](http://nuclide.io) and -> [run the application](http://nuclide.io/docs/platforms/react-native/#command-line). +If everything is set up correctly, you should see your new app running in your Android emulator shortly. `react-native run-android` is just one way to run your app - you can also run it directly from within Android Studio or Nuclide. @@ -274,33 +236,20 @@ Now that you have successfully run the app, let's modify it. ### That's it! -Congratulations! You've successfully run and modified your first React Native app. +Congratulations! You've successfully run and modified a React Native app.
- - -## Common Followups + - - -- If you want to run on a physical device, see the [Running on iOS Device page](docs/running-on-device-ios.html#content). - - - -- If you want to run on a physical device, see the [Running on Android Device page](docs/running-on-device-android.html#content). - - - -- If you run into any issues getting started, see the [Troubleshooting](docs/troubleshooting.html#content) and [Debugging](docs/debugging.html#content) pages. - - +## Now What? -## Common Followups +- If you want to add this new React Native code to an existing application, check out the [Integration guide](docs/integration-with-existing-apps.html). -- If you want to run on a physical device, see the [Running on Android Device page](docs/running-on-device-android.html#content). +- If you can't get this to work, see the [Troubleshooting](docs/troubleshooting.html#content) page. -- If you run into any issues getting started, see the [Troubleshooting](docs/troubleshooting.html#content) and [Debugging](docs/debugging.html#content) pages. +- If you're curious to learn more about React Native, continue on +to the [Tutorial](docs/tutorial.html). +The `style` prop can be a plain old JavaScript object. That's the simplest and what we usually use for example code. You can also pass an array of styles - the last style in the array has precedence, so you can use this to inherit styles. -## Declare Styles +As a component grows in complexity, it is often cleaner to use `StyleSheet.create` to define several styles in one place. Here's an example: -The way to declare styles in React Native is the following: +```ReactNativeWebPlayer +import React, { Component } from 'react'; +import { AppRegistry, StyleSheet, Text, View } from 'react-native'; -```javascript -var styles = StyleSheet.create({ - base: { - width: 38, - height: 38, - }, - background: { - backgroundColor: '#222222', - }, - active: { - borderWidth: 2, - borderColor: '#00ff00', - }, -}); -``` - -`StyleSheet.create` construct is optional but provides some key advantages. It ensures that the values are **immutable** and **opaque** by transforming them into plain numbers that reference an internal table. By putting it at the end of the file, you also ensure that they are only created once for the application and not on every render. - -All the attribute names and values are a subset of what works on the web. For layout, React Native implements [Flexbox](docs/flexbox.html). - -## Using Styles - -All the core components accept a style attribute. - -```javascript - - -``` - -They also accept an array of styles. - -```javascript - -``` - -The behavior is the same as `Object.assign`: in case of conflicting values, the one from the right-most element will have precedence and falsy values like `false`, `undefined` and `null` will be ignored. A common pattern is to conditionally add a style based on some condition. - -```javascript - -``` - -Finally, if you really have to, you can also create style objects in render, but they are highly discouraged. Put them last in the array definition. - -```javascript - -``` - -## Pass Styles Around - -In order to let a call site customize the style of your component children, you can pass styles around. Use `View.propTypes.style` and `Text.propTypes.style` in order to make sure only styles are being passed. - -```javascript -var List = React.createClass({ - propTypes: { - style: View.propTypes.style, - elementStyle: View.propTypes.style, - }, - render: function() { +class LotsOfStyles extends Component { + render() { return ( - - {elements.map((element) => - - )} + + just red + just bigblue + bigblue, then red + red, then bigblue ); } +} + +const styles = StyleSheet.create({ + bigblue: { + color: 'blue', + fontWeight: 'bold', + fontSize: 30, + }, + red: { + color: 'red', + }, }); -// ... in another file ... - +AppRegistry.registerComponent('LotsOfStyles', () => LotsOfStyles); ``` -## Supported Properties -You can checkout latest support of CSS Properties in following Links. +One common pattern is to make your component accept a `style` prop which in +turn is used to style subcomponents. You can use this to make styles "cascade" they way they do in CSS. + +There are a lot more ways to customize text style. Check out the [Text component reference](/react-native/docs/text.html) for a complete list. -- [View Properties](docs/view.html#style) -- [Image Properties](docs/image.html#style) -- [Text Properties](docs/text.html#style) -- [Flex Properties](docs/flexbox.html#content) -- [Transform Properties](docs/transforms.html#content) +Now you can make your text beautiful. The next step in becoming a style master is to [learn how to control component size](/react-native/docs/height-and-width.html). diff --git a/docs/Text.md b/docs/Text.md index 48853606e432fe..86537f8a20d07b 100644 --- a/docs/Text.md +++ b/docs/Text.md @@ -4,13 +4,24 @@ Both iOS and Android allow you to display formatted text by annotating ranges of a string with specific formatting like bold or colored text (`NSAttributedString` on iOS, `SpannableString` on Android). In practice, this is very tedious. For React Native, we decided to use web paradigm for this where you can nest text to achieve the same effect. -```javascript - - I am bold - - and red - - +```ReactNativeWebPlayer +import React, { Component } from 'react'; +import { AppRegistry, Text } from 'react-native'; + +class BoldAndBeautiful extends Component { + render() { + return ( + + I am bold + + and red + + + ); + } +} + +AppRegistry.registerComponent('BoldAndBeautiful', () => BoldAndBeautiful); ``` Behind the scenes, React Native converts this to a flat `NSAttributedString` or `SpannableString` that contains the following information: @@ -25,15 +36,26 @@ Behind the scenes, React Native converts this to a flat `NSAttributedString` or On iOS, you can nest views within your Text component. Here's an example: -```javascript - - There is a blue square - - in between my text. - +```ReactNativeWebPlayer +import React, { Component } from 'react'; +import { AppRegistry, Text, View } from 'react-native'; + +class BlueIsCool extends Component { + render() { + return ( + + There is a blue square + + in between my text. + + ); + } +} + +AppRegistry.registerComponent('BlueIsCool', () => BlueIsCool); ``` -In order to use this feature, you must give the view a `width` and a `height`. +> In order to use this feature, you must give the view a `width` and a `height`. ## Containers diff --git a/docs/Timers.md b/docs/Timers.md index 282946814e0503..ad0fe0e06090d5 100644 --- a/docs/Timers.md +++ b/docs/Timers.md @@ -2,9 +2,9 @@ id: timers title: Timers layout: docs -category: Polyfills +category: Guides permalink: docs/timers.html -next: colors +next: direct-manipulation --- Timers are an important part of an application and React Native implements the [browser timers](https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Timers). diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 8341349b9b6c46..41ec9be6ede7bd 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -6,69 +6,51 @@ category: Quick Start permalink: docs/troubleshooting.html --- -## Cmd-R does not reload the simulator -Enable iOS simulator's "Connect hardware keyboard" from menu Hardware > Keyboard menu. +These are some common issues you may run into while setting up React Native. If you encounter something that is not listed here, try [searching for the issue in GitHub](https://github.com/facebook/react-native/issues/). -![Keyboard Menu](https://cloud.githubusercontent.com/assets/1388454/6863127/03837824-d409-11e4-9251-e05bd31d978f.png) +### Port already in use +The React Native packager runs on port 8081. If another process is already using that port (such as McAfee Antivirus on Windows), you can either terminate that process, or change the port that the packager uses. -If you are using a non-QWERTY/AZERTY keyboard layout you can use the `Hardware > Shake Gesture` to bring up the dev menu and click "Refresh". Alternatively, you can hit `Cmd-P` on Dvorak/Colemak layouts to reload the simulator. +#### Terminating a process on port 8081 -You can use Cmd+M on Android to bring up the dev menu. +Run the following command on a Mac to find the id for the process that is listening on port 8081: -## Port already in use red-screen -![red-screen](https://cloud.githubusercontent.com/assets/602176/6857442/63fd4f0a-d3cc-11e4-871f-875b0c784611.png) - - -Something is probably already running on port 8081. You can either kill it or try to change which port the packager is listening to. - -##### Kill process on port 8081 `$ sudo lsof -n -i4TCP:8081 | grep LISTEN` -then +Then run the following to terminate the process: -`$ kill -9 ` +`$ kill -9 ` +#### Using a port other than 8081 -##### Change the port in Xcode -Edit `AppDelegate.m` to use a different port. -``` - // 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, and make sure your computer and - // iOS device are on the same Wi-Fi network. - jsCodeLocation = [NSURL URLWithString:@"http://localhost:9381/index.ios.bundle"]; - ``` +You can configure the packager to use a port other than 8081 by using the `port` parameter: + +`$ react-native start --port=8088` +You will also need to update your applications to load the JavaScript bundle from the new port. -## Watchman took too long to load -Permission settings prevent Watchman from loading. A recent update solves this, get a HEAD install of Watchman if you are experiencing this error. +To change the port used by an iOS application, edit the `AppDelegate.m` file in the `ios` folder. Scroll down to the line where the bundle location is defined, and replace 8081 with the new port. ``` -brew uninstall watchman -brew install --HEAD watchman +jsCodeLocation = [NSURL URLWithString:@"http://localhost:8088/index.ios.bundle"]; ``` -## NPM locking error +### NPM locking error + +If you encounter an error such as "npm WARN locking Error: EACCES" while using the React Native CLI, try running the following: -If in the `react-native init ` phase you saw npm fail with "npm WARN locking Error: EACCES" then try the following: ``` sudo chown -R $USER ~/.npm sudo chown -R $USER /usr/local/lib/node_modules ``` -## Debugging in Chrome hangs and/or does not work well -It is possible that one of your Chrome extensions is interacting in unexpected ways with the debugger. If you are having this issue, try disabling all of your extensions and re-enabling them one-by-one until you find the problematic extension. +### Missing libraries for React -## Xcode Build Failures +If you added React Native manually to your project, make sure you have included all the relevant dependencies that you are using, like `RCTText.xcodeproj`, `RCTImage.xcodeproj`. Next, the binaries built by these dependencies have to be linked to your app binary. Use the `Linked Frameworks and Binaries` section in the Xcode project settings. More detailed steps are here: [Linking Libraries](docs/linking-libraries-ios.html#content). -To see the exact error that is causing your build to fail, go into the Issues Navigator in the left sidebar. - -##### React libraries missing If you are using CocoaPods, verify that you have added React along with the subspecs to the `Podfile`. For example, if you were using the ``, `` and `fetch()` APIs, you would need to add these in your `Podfile`: + ``` pod 'React', :path => '../node_modules/react-native', :subspecs => [ 'RCTText', @@ -77,46 +59,39 @@ pod 'React', :path => '../node_modules/react-native', :subspecs => [ 'RCTWebSocket', ] ``` -Next, make sure you have run `pod install` and that a `Pods/` directory has been created in your project with React installed. CocoaPods will instruct you to use the generated `.xcworkspace` file henceforth to be able to use these installed dependencies. -If you are adding React manually, make sure you have included all the relevant dependencies, like `RCTText.xcodeproj`, `RCTImage.xcodeproj` depending on the ones you are using. Next, the binaries built by these dependencies have to be linked to your app binary. Use the `Linked Frameworks and Binaries` section in the Xcode project settings. More detailed steps are here: [Linking Libraries](docs/linking-libraries-ios.html#content). +Next, make sure you have run `pod install` and that a `Pods/` directory has been created in your project with React installed. CocoaPods will instruct you to use the generated `.xcworkspace` file henceforth to be able to use these installed dependencies. -##### Argument list too long: recursive header expansion failed +#### Argument list too long: recursive header expansion failed In the project's build settings, `User Search Header Paths` and `Header Search Paths` are two configs that specify where Xcode should look for `#import` header files specified in the code. For Pods, CocoaPods uses a default array of specific folders to look in. Verify that this particular config is not overwritten, and that none of the folders configured are too large. If one of the folders is a large folder, Xcode will attempt to recursively search the entire directory and throw above error at some point. To revert the `User Search Header Paths` and `Header Search Paths` build settings to their defaults set by CocoaPods - select the entry in the Build Settings panel, and hit delete. It will remove the custom override and return to the CocoaPod defaults. -## Unable to connect to development server - -##### iOS -Ensure that you are on the same WiFi network as your computer. If you're using a cell data plan, your phone can't access your computer's local IP address. +### No transports available -##### Android -You need to run `adb reverse tcp:8081 tcp:8081` to forward requests from the device to your computer. This works only on Android 5.0 and newer. +React Native implements a polyfill for WebSockets. These [polyfills](https://github.com/facebook/react-native/blob/master/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js) are initialized as part of the react-native module that you include in your application through `import React from 'react-native'`. If you load another module that requires WebSockets, such as [Firebase](https://github.com/facebook/react-native/issues/3645), be sure to load/require it after react-native: -## Module that uses `WebSocket` (such as Firebase) throws an exception - -React Native implements a polyfill for WebSockets. These polyfills are initialized as part of the react-native module that you include in your application through `import React from 'react-native'`. If you load another module that requires WebSockets, be sure to load/require it after react-native. - -So: ``` import React from 'react-native'; import Firebase from 'firebase'; ``` -Requiring firebase *before* react-native will result in a 'No transports available' redbox. - -Discovered thanks to issue [#3645](https://github.com/facebook/react-native/issues/3645). If you're curious, the polyfills are set up in [InitializeJavaScriptAppEngine.js](https://github.com/facebook/react-native/blob/master/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js). - - ## Shell Command Unresponsive Exception -If you encounter: +If you encounter a ShellCommandUnresponsiveException exception such as: ``` Execution failed for task ':app:installDebug'. com.android.builder.testing.api.DeviceException: com.android.ddmlib.ShellCommandUnresponsiveException ``` -Try downgrading your Gradle version to 1.2.3 in `/android/build.gradle` (https://github.com/facebook/react-native/issues/2720) +Try [downgrading your Gradle version to 1.2.3](https://github.com/facebook/react-native/issues/2720) in `android/build.gradle`. + +## react-native init hangs + +If you run into issues where running `react-native init` hangs in your system, try running it again in verbose mode and refering to [#2797](https://github.com/facebook/react-native/issues/2797) for common causes: + +``` +react-native init --verbose +``` diff --git a/docs/Tutorial-CoreComponents.md b/docs/Tutorial-CoreComponents.md deleted file mode 100644 index a0440dc2cc3eb0..00000000000000 --- a/docs/Tutorial-CoreComponents.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: tutorial-core-components -title: Core Components -layout: docs -category: Tutorials -permalink: docs/tutorial-core-components.html -next: tutorial-integration-with-existing-apps ---- - -Components are the building blocks for a React Native application. A React Native user interface (UI) is specified by declaring components, possibly nested, and then those components are mapped to the native UI on the targeted platform. - -React Native has a number of core components that are commonly used in applications, either on their own or combined to build new components. - -## Text - -The most basic component in React Native is the [`Text`](/react-native/docs/text.html#content) component. The `Text` component simply renders text. - -This example displays the `string` `"Hello World!"` on the device. - -```JavaScript -import React from 'react'; -import { AppRegistry, Text } from 'react-native'; - -const App = () => { - return ( - Hello World! - ); -} - -// App registration and rendering -AppRegistry.registerComponent('MyApp', () => App); -``` - -## Image - -The other basic React Native component is the [`Image`](/react-native/docs/image.html#content) component. Like `Text`, the `Image` component simply renders an image. - -> An `Image` is analogous to using `img` when building websites. - -The simplest way to render an image is to provide a source file to that image via the `source` attribute. - -This example displays a checkbox `Image` on the device. - -```JavaScript -import React from 'react'; -import { AppRegistry, Image } from 'react-native'; - -const App = () => { - return ( - - ); -} - -// App registration and rendering -AppRegistry.registerComponent('MyApp', () => App); -``` - -## View - -A [`View`](/react-native/docs/view.html#content) is the most basic building block for a React Native application. The `View` is an abstraction on top of the target platform's native equivalent, such as iOS's `UIView`. - -> A `View` is analogous to using a `div` for building websites. - -While basic components such as `Text` and `Image`, can be displayed without a `View`, this is not generally recommended since the `View` gives you the control for styling and layout of those components. - -This example creates a `View` that aligns the `string` `Hello` in the top center of the device, something which could not be done with a `Text` component alone (i.e., a `Text` component without a `View` would place the `string` in a fixed location in the upper corner): - -```JavaScript -import React from 'react'; -import { AppRegistry, Text, View } from 'react-native'; - -const App = () => { - return ( - - Hello! - - ); -} - -// App registration and rendering -AppRegistry.registerComponent('MyApp', () => App); -``` - -## TextInput - -Direct text-based user input is a foundation for many apps. Writing a post or comment on a page is a canonical example of this. [`TextInput`](/react-native/docs/textinput.html#content) is a basic component that allows the user to enter text. - -This example creates a simple `TextInput` box with the `string` `Hello` as the placeholder when the `TextInput` is empty. - -```JavaScript -import React from 'react'; -import { AppRegistry, TextInput, View } from 'react-native'; - -const App = () => { - return ( - - - - ); -} - -// App registration and rendering -AppRegistry.registerComponent('MyApp', () => App); -``` - -## ListView - -On mobile devices, lists are a core element in many applications. The [`ListView`](/react-native/docs/listview.html#content) component is a special type of [`View`](/react-native/docs/tutorials/core-components.html#view) that displays a vertically scrolling list of changing data. - -The `ListView` component requires two properties, `dataSource` and `renderRow`. `dataSource` is the actual source of information that will be part of the list. `renderRow` takes the data and returns a renderable component to display. - -This example creates a simple `ListView` of hardcoded data. It first initializes the `datasource` that will be used to populate the `ListView`. Then it renders that `ListView` with that data. - -> A `rowHasChanged` function is required to use `ListView`. Here we just say a row has changed if the row we are on is not the same as the previous row. - -```JavaScript -import React from 'react'; -import { AppRegistry, Text, View, ListView} from 'react-native'; - -var SimpleList = React.createClass({ - // Initialize the hardcoded data - getInitialState: function() { - var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); - return { - dataSource: ds.cloneWithRows(['John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie']) - }; - }, - render: function() { - return ( - - {rowData}} - /> - - ); - } -}); - -// App registration and rendering -AppRegistry.registerComponent('MyApp', () => SimpleList); -``` diff --git a/docs/Tutorial.md b/docs/Tutorial.md new file mode 100644 index 00000000000000..5007fec876e649 --- /dev/null +++ b/docs/Tutorial.md @@ -0,0 +1,53 @@ +--- +id: tutorial +title: Tutorial +layout: docs +category: The Basics +permalink: docs/tutorial.html +next: props +--- + +React Native is like React, but it uses native components instead of web components as building blocks. So to understand the basic structure of a React Native app, you need to understand some of the basic React concepts, like JSX, components, `state`, and `props`. If you already know React, you still need to learn some React-Native-specific stuff, like the native components. This +tutorial is aimed at all audiences, whether you have React experience or not. + +Let's do this thing. + +## Hello World + +In accordance with the ancient traditions of our people, we must first build an app that does nothing except say "Hello world". Here it is: + +```ReactNativeWebPlayer +import React, { Component } from 'react'; +import { AppRegistry, Text } from 'react-native'; + +class HelloWorldApp extends Component { + render() { + return ( + Hello world! + ); + } +} + +AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp); +``` + +If you are feeling curious, you can play around with sample code directly in the web simulators. You can also paste it into your `index.ios.js` or `index.android.js` file to create a real app on your local machine. + +## What's going on here? + +Some of the things in here might not look like JavaScript to you. Don't panic. This is the future. + +First of all, ES2015 (also known as ES6) is a set of improvements to JavaScript that is now part of the official standard, but not yet supported by all browsers, so often it isn't used yet in web development. React Native ships with ES2015 support, so you can use this stuff without worrying about compatibility. `import`, `from`, `class`, `extends`, and the `() =>` syntax in the example above are all ES2015 features. If you aren't familiar with ES2015, you can probably pick it up just by reading through sample code like this tutorial has. If you want, [this page](https://babeljs.io/docs/learn-es2015/) has a good overview of ES2015 features. + +The other unusual thing in this code example is `Hello world!`. This is JSX - a syntax for embedding XML within JavaScript. Many frameworks use a special templating language which lets you embed code inside markup language. In React, this is reversed. JSX lets you write your markup language inside code. It looks like HTML on the web, except instead of web things like `
` or ``, you use React components. In this case, `` +is a built-in component that just displays some text. + +## Component and AppRegistry + +So this code is defining `HelloWorldApp`, a new `Component`, and it's registering it with the `AppRegistry`. When you're building a React Native app, you'll be making new components a lot. Anything you see on the screen is some sort of component. A component can be pretty simple - the only thing that's required is a `render` function which returns some JSX to render. + +The `AppRegistry` just tells React Native which component is the root one for the whole application. You won't be thinking about `AppRegistry` a lot - there will probably just be one call to `AppRegistry.registerComponent` in your whole app. It's included in these examples so you can paste the whole thing into your `index.ios.js` or `index.android.js` file and get it running. + +## This App Doesn't Do Very Much + +Good point. To make components do more interesting things, you need to [learn about Props](/react-native/docs/props.html). diff --git a/docs/UsingAListView.md b/docs/UsingAListView.md new file mode 100644 index 00000000000000..1c3b9d689a0d6a --- /dev/null +++ b/docs/UsingAListView.md @@ -0,0 +1,51 @@ +--- +id: using-a-listview +title: Using a ListView +layout: docs +category: The Basics +permalink: docs/using-a-listview.html +next: network +--- + +The `ListView` component displays a vertically scrolling list of changing, but similarly structured, data. + +`ListView` works well for long lists of data, where the number of items might change over time. Unlike the more generic [`ScrollView`](/react-native/docs/using-a-scrollview.html), the `ListView` only renders elements that are currently showing on the screen, not all the elements at once. + +The `ListView` component requires two props: `dataSource` and `renderRow`. `dataSource` is the source of information for the list. `renderRow` takes one item from the source and returns a formatted component to render. + +This example creates a simple `ListView` of hardcoded data. It first initializes the `dataSource` that will be used to populate the `ListView`. Each item in the `dataSource` is then rendered as a `Text` component. Finally it renders the `ListView` and all `Text` components. + +> A `rowHasChanged` function is required to use `ListView`. Here we just say a row has changed if the row we are on is not the same as the previous row. + +```JavaScript +import React, { Component } from 'react'; +import { AppRegistry, ListView, Text, View } from 'react-native'; + +class ListViewBasics extends Component { + // Initialize the hardcoded data + constructor(props) { + super(props); + const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); + this.state = { + dataSource: ds.cloneWithRows([ + 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin' + ]) + }; + } + render() { + return ( + + {rowData}} + /> + + ); + } +} + +// App registration and rendering +AppRegistry.registerComponent('AwesomeProject', () => ListViewBasics); +``` + +One of the most common uses for a `ListView` is displaying data that you fetch from a server. To do that, you will need to [learn about networking in React Native](/react-native/docs/network.html). diff --git a/docs/UsingAScrollView.md b/docs/UsingAScrollView.md new file mode 100644 index 00000000000000..8c038e9a1d86c6 --- /dev/null +++ b/docs/UsingAScrollView.md @@ -0,0 +1,64 @@ +--- +id: using-a-scrollview +title: Using a ScrollView +layout: docs +category: The Basics +permalink: docs/using-a-scrollview.html +next: using-a-listview +--- + +The [`ScrollView`](/react-native/docs/scrollview.html) is a generic scrolling container that can host multiple components and views. The scrollable items need not be homogenous, and you can scroll both vertically and horizontally (by setting the `horizontal` property). + +This example creates a vertical `ScrollView` with both images and text mixed together. + +```ReactNativeWebPlayer +import React, { Component } from 'react'; +import{ AppRegistry, ScrollView, Image, Text, View } from 'react-native' + +class IScrolledDownAndWhatHappenedNextShockedMe extends Component { + render() { + return( + + Scroll me plz + + + + + + If you like + + + + + + Scrolling down + + + + + + What's the best + + + + + + Framework around? + + + + + + React Native + + ); + } +} + + +AppRegistry.registerComponent( + 'IScrolledDownAndWhatHappenedNextShockedMe', + () => IScrolledDownAndWhatHappenedNextShockedMe); +``` + +`ScrollView` works best to present a small amount of things of a limited size. All the elements and views of a `ScrollView` are rendered, even if they are not currently shown on the screen. If you have a long list of more items that can fit on the screen, you should use a `ListView` instead. So let's [learn about the ListView](/react-native/docs/using-a-listview.html) next. diff --git a/docs/Videos.md b/docs/Videos.md deleted file mode 100644 index 68537e117141de..00000000000000 --- a/docs/Videos.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -id: videos -title: Videos -layout: docs -category: Community Resources -permalink: docs/videos.html -next: newsletter ---- - -### React.js Conf 2016 - - - - - - - - - - - - - - - - - - - - - - - - - - -### React.js Conf 2015 - - - - - - - - - - - - - - - -### [The Changelog #149](https://thechangelog.com/149/) -With Christopher "vjeux" Chedeau and Spencer Ahrens - - - -### [JSJabber #146](http://devchat.tv/js-jabber/146-jsj-react-with-christopher-chedeau-and-jordan-walke) -With Christopher "vjeux" Chedeau and Jordan Walke - - diff --git a/website/core/Marked.js b/website/core/Marked.js index 7d3fa4626449eb..d123b874bdb636 100644 --- a/website/core/Marked.js +++ b/website/core/Marked.js @@ -8,6 +8,7 @@ var React = require('React'); var Prism = require('Prism'); +var WebPlayer = require('WebPlayer'); var Header = require('Header'); /** @@ -827,7 +828,16 @@ Parser.prototype.tok = function() { ); } case 'code': { - return {this.token.text}; + var lang = this.token.lang + , text = this.token.text; + + if (lang && lang.indexOf('ReactNativeWebPlayer') === 0) { + return ( + {text} + ); + } + + return {text}; } case 'table': { var table = [] diff --git a/website/core/WebPlayer.js b/website/core/WebPlayer.js new file mode 100644 index 00000000000000..76b51ad4fcffba --- /dev/null +++ b/website/core/WebPlayer.js @@ -0,0 +1,68 @@ +/** + * 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. + * + * @providesModule WebPlayer + */ + +var React = require('React'); +var Prism = require('Prism'); + +/** + * Use the WebPlayer by including a ```ReactNativeWebPlayer``` block in markdown. + * + * Optionally, include url parameters directly after the block's language. For + * the complete list of url parameters, see: https://github.com/dabbott/react-native-web-player + * + * E.g. + * ```ReactNativeWebPlayer?platform=android + * import React from 'react'; + * import { AppRegistry, Text } from 'react-native'; + * + * const App = () => Hello World!; + * + * AppRegistry.registerComponent('MyApp', () => App); + * ``` + */ +var WebPlayer = React.createClass({ + parseParams: function(paramString) { + var params = {}; + + if (paramString) { + var pairs = paramString.split('&'); + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i].split('='); + params[pair[0]] = pair[1]; + } + } + + return params; + }, + + render: function() { + var hash = `#code=${encodeURIComponent(this.props.children)}`; + + if (this.props.params) { + hash += `&${this.props.params}`; + } + + return ( +
+ {this.props.children} +