diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d9e9d7eccf64d..541ea2ea9206cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,11 +96,11 @@ Please make sure the following is done when submitting a pull request: 1. Fork [the repository](https://github.com/facebook/react-native) and create your branch from `master`. 2. Add the copyright notice to the top of any new files you've added. -3. Describe your [**test plan**](/react-native/docs/contributing.html#test-plan) in your pull request description. Make sure to [test your changes](/react-native/docs/testing.html)! +3. Describe your [**test plan**](https://facebook.github.io/react-native/docs/contributing.html#test-plan) in your pull request description. Make sure to [test your changes](https://facebook.github.io/react-native/docs/testing.html)! 4. Make sure your code lints (`npm run lint`). 5. If you haven't already, [sign the CLA](https://code.facebook.com/cla). -All pull requests should be opened against the `master` branch. After opening your pull request, ensure [**all tests pass**](/react-native/docs/contributing.html#contrinuous-integration-tests) on Circle CI. If a test fails and you believe it is unrelated to your change, leave a comment on the pull request explaining why. +All pull requests should be opened against the `master` branch. After opening your pull request, ensure [**all tests pass**](https://facebook.github.io/react-native/docs/contributing.html#contrinuous-integration-tests) on Circle CI. If a test fails and you believe it is unrelated to your change, leave a comment on the pull request explaining why. > **Note:** It is not necessary to keep clicking `Merge master to your branch` on the PR page. You would want to merge master if there are conflicts or tests are failing. The Facebook-GitHub-Bot ultimately squashes all commits to a single one before merging your PR. @@ -116,7 +116,7 @@ See [What is a Test Plan?](https://medium.com/@martinkonicek/what-is-a-test-plan #### Continuous integration tests -Make sure all **tests pass** on [Circle CI][circle]. PRs that break tests are unlikely to be merged. Learn more about [testing your changes here](/react-native/docs/testing.html). +Make sure all **tests pass** on [Circle CI][circle]. PRs that break tests are unlikely to be merged. Learn more about [testing your changes here](https://facebook.github.io/react-native/docs/testing.html). [circle]: http://circleci.com/gh/facebook/react-native diff --git a/docs/AndroidUIPerformance.md b/docs/AndroidUIPerformance.md deleted file mode 100644 index b19442995b1276..00000000000000 --- a/docs/AndroidUIPerformance.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: android-ui-performance -title: Profiling Android UI Performance -layout: redirect -permalink: docs/android-ui-performance.html -destinationUrl: performance.html ---- diff --git a/docs/Images.md b/docs/Images.md index 4e05595ebe3452..6a709d6d6997ae 100644 --- a/docs/Images.md +++ b/docs/Images.md @@ -4,7 +4,7 @@ title: Images layout: docs category: Guides permalink: docs/images.html -next: animations +next: animations previous: navigation --- diff --git a/docs/NativeMethodsMixin.md b/docs/NativeMethodsMixin.md deleted file mode 100644 index 0ec3d80e65f4a8..00000000000000 --- a/docs/NativeMethodsMixin.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: NativeMethodsMixin -title: NativeMethodsMixin -layout: redirect -permalink: docs/nativemethodsmixin.html -destinationUrl: direct-manipulation.html#other-native-methods ---- diff --git a/docs/RunningOnDeviceAndroid.md b/docs/RunningOnDeviceAndroid.md deleted file mode 100644 index cb8b3e58d9e4ea..00000000000000 --- a/docs/RunningOnDeviceAndroid.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: running-on-device-android -title: Running On Device -layout: redirect -permalink: docs/running-on-device-android.html -destinationUrl: running-on-device.html ---- diff --git a/docs/RunningOnDeviceIOS.md b/docs/RunningOnDeviceIOS.md deleted file mode 100644 index 886c000d6c4fcd..00000000000000 --- a/docs/RunningOnDeviceIOS.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: running-on-device-ios -title: Running On Device -layout: redirect -permalink: docs/running-on-device-ios.html -destinationUrl: running-on-device.html ---- diff --git a/docs/StyleGuide.md b/docs/StyleGuide.md deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/docs/accessibilityinfo.md b/docs/accessibilityinfo.md new file mode 100644 index 00000000000000..d85927eafc8040 --- /dev/null +++ b/docs/accessibilityinfo.md @@ -0,0 +1,156 @@ +--- +id: accessibilityinfo +title: AccessibilityInfo +layout: docs +category: APIs +permalink: docs/accessibilityinfo.html +next: actionsheetios +previous: webview +--- + +Sometimes it's useful to know whether or not the device has a screen reader that is currently active. The +`AccessibilityInfo` API is designed for this purpose. You can use it to query the current state of the +screen reader as well as to register to be notified when the state of the screen reader changes. + +Here's a small example illustrating how to use `AccessibilityInfo`: + +```javascript +class ScreenReaderStatusExample extends React.Component { + state = { + screenReaderEnabled: false, + } + + componentDidMount() { + AccessibilityInfo.addEventListener( + 'change', + this._handleScreenReaderToggled + ); + AccessibilityInfo.fetch().done((isEnabled) => { + this.setState({ + screenReaderEnabled: isEnabled + }); + }); + } + + componentWillUnmount() { + AccessibilityInfo.removeEventListener( + 'change', + this._handleScreenReaderToggled + ); + } + + _handleScreenReaderToggled = (isEnabled) => { + this.setState({ + screenReaderEnabled: isEnabled, + }); + } + + render() { + return ( + + + The screen reader is {this.state.screenReaderEnabled ? 'enabled' : 'disabled'}. + + + ); + } +} +``` + + +### Methods + +- [`fetch`](docs/accessibilityinfo.html#fetch) +- [`addEventListener`](docs/accessibilityinfo.html#addeventlistener) +- [`setAccessibilityFocus`](docs/accessibilityinfo.html#setaccessibilityfocus) +- [`announceForAccessibility`](docs/accessibilityinfo.html#announceforaccessibility) +- [`removeEventListener`](docs/accessibilityinfo.html#removeeventlistener) + + + + +--- + +# Reference + +## Methods + +### `fetch()` + +```javascript +static fetch() +``` + + +Query whether a screen reader is currently enabled. Returns a promise which +resolves to a boolean. The result is `true` when a screen reader is enabled +and `false` otherwise. + + + + +--- + +### `addEventListener()` + +```javascript +static addEventListener(eventName, handler) +``` + + +Add an event handler. Supported events: + +- `change`: Fires when the state of the screen reader changes. The argument + to the event handler is a boolean. The boolean is `true` when a screen + reader is enabled and `false` otherwise. +- `announcementFinished`: iOS-only event. Fires when the screen reader has + finished making an announcement. The argument to the event handler is a dictionary + with these keys: + - `announcement`: The string announced by the screen reader. + - `success`: A boolean indicating whether the announcement was successfully made. + + + + +--- + +### `setAccessibilityFocus()` + +```javascript +static setAccessibilityFocus(reactTag) +``` + + +iOS-Only. Set accessibility focus to a react component. + + + + +--- + +### `announceForAccessibility()` + +```javascript +static announceForAccessibility(announcement) +``` + + +iOS-Only. Post a string to be announced by the screen reader. + + + + +--- + +### `removeEventListener()` + +```javascript +static removeEventListener(eventName, handler) +``` + + +Remove an event handler. + + + + diff --git a/docs/actionsheetios.md b/docs/actionsheetios.md new file mode 100644 index 00000000000000..2d998d3f167c95 --- /dev/null +++ b/docs/actionsheetios.md @@ -0,0 +1,96 @@ +--- +id: actionsheetios +title: ActionSheetIOS +layout: docs +category: APIs +permalink: docs/actionsheetios.html +next: alert +previous: accessibilityinfo +--- + + + +### Methods + +- [`showActionSheetWithOptions`](docs/actionsheetios.html#showactionsheetwithoptions) +- [`showShareActionSheetWithOptions`](docs/actionsheetios.html#showshareactionsheetwithoptions) + + + + +--- + +# Reference + +## Methods + +### `showActionSheetWithOptions()` + +```javascript +static showActionSheetWithOptions(options, callback) +``` + + +Display an iOS action sheet. The `options` object must contain one or more +of: + +- `options` (array of strings) - a list of button titles (required) +- `cancelButtonIndex` (int) - index of cancel button in `options` +- `destructiveButtonIndex` (int) - index of destructive button in `options` +- `title` (string) - a title to show above the action sheet +- `message` (string) - a message to show below the title + +The 'callback' function takes one parameter, the zero-based index +of the selected item. + +Minimal example: + +``` +ActionSheetIOS.showActionSheetWithOptions({ + options: ['Remove', 'Cancel'], + destructiveButtonIndex: 1, + cancelButtonIndex: 0, +}, +(buttonIndex) => { + if (buttonIndex === 1) { // destructive action } +}); +``` + + + + + +--- + +### `showShareActionSheetWithOptions()` + +```javascript +static showShareActionSheetWithOptions(options, failureCallback, successCallback) +``` + + +Display the iOS share sheet. The `options` object should contain +one or both of `message` and `url` and can additionally have +a `subject` or `excludedActivityTypes`: + +- `url` (string) - a URL to share +- `message` (string) - a message to share +- `subject` (string) - a subject for the message +- `excludedActivityTypes` (array) - the activities to exclude from the ActionSheet + +NOTE: if `url` points to a local file, or is a base64-encoded +uri, the file it points to will be loaded and shared directly. +In this way, you can share images, videos, PDF files, etc. + +The 'failureCallback' function takes one parameter, an error object. +The only property defined on this object is an optional `stack` property +of type `string`. + +The 'successCallback' function takes two parameters: + +- a boolean value signifying success or failure +- a string that, in the case of success, indicates the method of sharing + + + + diff --git a/docs/activityindicator.md b/docs/activityindicator.md new file mode 100644 index 00000000000000..f00406d2911b00 --- /dev/null +++ b/docs/activityindicator.md @@ -0,0 +1,125 @@ +--- +id: activityindicator +title: ActivityIndicator +layout: docs +category: components +permalink: docs/activityindicator.html +next: button +previous: null +--- +Displays a circular loading indicator. + +### Example + +```ReactNativeWebPlayer +import React, { Component } from 'react' +import { + ActivityIndicator, + AppRegistry, + StyleSheet, + Text, + View, +} from 'react-native' + +class App extends Component { + render() { + return ( + + + + + + + ) + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center' + }, + horizontal: { + flexDirection: 'row', + justifyContent: 'space-around', + padding: 10 + } +}) + +AppRegistry.registerComponent('App', () => App) +``` + +### Props + +* [ViewPropTypes props...](docs/viewproptypes.html#props) +- [`animating`](docs/activityindicator.html#animating) +- [`color`](docs/activityindicator.html#color) +- [`size`](docs/activityindicator.html#size) +- [`hidesWhenStopped`](docs/activityindicator.html#hideswhenstopped) + + + + + + +--- + +# Reference + +## Props + +### `animating` + +Whether to show the indicator (true, the default) or hide it (false). + +| Type | Required | +| - | - | +| bool | No | + + + + +--- + +### `color` + +The foreground color of the spinner (default is gray). + +| Type | Required | +| - | - | +| [color](docs/colors.html) | No | + + + + +--- + +### `size` + +Size of the indicator (default is 'small'). +Passing a number to the size prop is only supported on Android. + +| Type | Required | +| - | - | +| enum('small', 'large'), ,number | No | + + + + +--- + +### `hidesWhenStopped` + +Whether the indicator should hide when not animating (true by default). + + + +| Type | Required | Platform | +| - | - | - | +| bool | No | iOS | + + + + + + diff --git a/docs/alert.md b/docs/alert.md new file mode 100644 index 00000000000000..87f67237581991 --- /dev/null +++ b/docs/alert.md @@ -0,0 +1,79 @@ +--- +id: alert +title: Alert +layout: docs +category: APIs +permalink: docs/alert.html +next: alertios +previous: actionsheetios +--- + +Launches an alert dialog with the specified title and message. + +Optionally provide a list of buttons. Tapping any button will fire the +respective onPress callback and dismiss the alert. By default, the only +button will be an 'OK' button. + +This is an API that works both on iOS and Android and can show static +alerts. To show an alert that prompts the user to enter some information, +see `AlertIOS`; entering text in an alert is common on iOS only. + +## iOS + +On iOS you can specify any number of buttons. Each button can optionally +specify a style, which is one of 'default', 'cancel' or 'destructive'. + +## Android + +On Android at most three buttons can be specified. Android has a concept +of a neutral, negative and a positive button: + + - If you specify one button, it will be the 'positive' one (such as 'OK') + - Two buttons mean 'negative', 'positive' (such as 'Cancel', 'OK') + - Three buttons mean 'neutral', 'negative', 'positive' (such as 'Later', 'Cancel', 'OK') + +By default alerts on Android can be dismissed by tapping outside of the alert +box. This event can be handled by providing an optional `options` parameter, +with an `onDismiss` callback property `{ onDismiss: () => {} }`. + +Alternatively, the dismissing behavior can be disabled altogether by providing +an optional `options` parameter with the `cancelable` property set to `false` +i.e. `{ cancelable: false }` + +Example usage: +``` +// Works on both iOS and Android +Alert.alert( + 'Alert Title', + 'My Alert Msg', + [ + {text: 'Ask me later', onPress: () => console.log('Ask me later pressed')}, + {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'}, + {text: 'OK', onPress: () => console.log('OK Pressed')}, + ], + { cancelable: false } +) +``` + + +### Methods + +- [`alert`](docs/alert.html#alert) + + + + +--- + +# Reference + +## Methods + +### `alert()` + +```javascript +static alert(title, message?, buttons?, options?, type?) +``` + + + diff --git a/docs/alertios.md b/docs/alertios.md new file mode 100644 index 00000000000000..7079e67bfde6ca --- /dev/null +++ b/docs/alertios.md @@ -0,0 +1,220 @@ +--- +id: alertios +title: AlertIOS +layout: docs +category: APIs +permalink: docs/alertios.html +next: animated +previous: alert +--- +`AlertIOS` provides functionality to create an iOS alert dialog with a +message or create a prompt for user input. + +Creating an iOS alert: + +``` +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. + +### Methods + +- [`alert`](docs/alertios.html#alert) +- [`prompt`](docs/alertios.html#prompt) + + +### Type Definitions + +- [`AlertType`](docs/alertios.html#alerttype) +- [`AlertButtonStyle`](docs/alertios.html#alertbuttonstyle) +- [`ButtonsArray`](docs/alertios.html#buttonsarray) + + + + +--- + +# Reference + +## Methods + +### `alert()` + +```javascript +static alert(title: string, [message]: string, [callbackOrButtons]: ?(() => void), ButtonsArray, [type]: AlertType): [object Object] +``` + +Create and display a popup alert. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| title | string | No | The dialog's title. Passing null or '' will hide the title. | +| message | string | Yes | An optional message that appears below the dialog's title. | +| callbackOrButtons | ?(() => void),[ButtonsArray](docs/alertios.html#buttonsarray) | Yes | 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 | [AlertType](docs/alertios.html#alerttype) | Yes | Deprecated, do not use. | + + + + +Example with custom buttons: + +```javascript +AlertIOS.alert( + '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')}, + ], +); +``` + + + +--- + +### `prompt()` + +```javascript +static prompt(title: string, [message]: string, [callbackOrButtons]: ?((text: string) => void), ButtonsArray, [type]: AlertType, [defaultValue]: string, [keyboardType]: string): [object Object] +``` + +Create and display a prompt to enter some text. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| title | string | No | The dialog's title. | +| message | string | Yes | An optional message that appears above the text input. | +| callbackOrButtons | ?((text: string) => void),[ButtonsArray](docs/alertios.html#buttonsarray) | Yes | 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 | [AlertType](docs/alertios.html#alerttype) | Yes | This configures the text input. One of 'plain-text', 'secure-text' or 'login-password'. | +| defaultValue | string | Yes | The default text in text input. | +| keyboardType | string | Yes | The keyboard type of first text field(if exists). One of 'default', 'email-address', 'numeric', 'phone-pad', 'ascii-capable', 'numbers-and-punctuation', 'url', 'number-pad', 'name-phone-pad', 'decimal-pad', 'twitter' or 'web-search'. | + + + + +Example with custom buttons: + +```javascript +AlertIOS.prompt( + 'Enter password', + 'Enter your password to claim your $1.5B in lottery winnings', + [ + {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'}, + {text: 'OK', onPress: password => console.log('OK Pressed, password: ' + password)}, + ], + 'secure-text' +); +``` + +, + +Example with the default button and a custom callback: + +```javascript +AlertIOS.prompt( + 'Update username', + null, + text => console.log("Your username is "+text), + null, + 'default' +); +``` + + + +## Type Definitions + +### AlertType + +An Alert button type + +| Type | +| - | +| $Enum | + + +**Constants:** + +| Value | Description | +| - | - | +| default | Default alert with no inputs | +| plain-text | Plain text input alert | +| secure-text | Secure text input alert | +| login-password | Login and password alert | + + + + +--- + +### AlertButtonStyle + +An Alert button style + +| Type | +| - | +| $Enum | + + +**Constants:** + +| Value | Description | +| - | - | +| default | Default button style | +| cancel | Cancel button style | +| destructive | Destructive button style | + + + + +--- + +### ButtonsArray + +Array or buttons + +| Type | +| - | +| Array | + + +**Properties:** + +| Name | Type | Description | +| - | - | - | +| [text] | string | Button label | +| [onPress] | function | Callback function when button pressed | +| [style] | [AlertButtonStyle](docs/alertios.html#alertbuttonstyle) | Button style | + + +**Constants:** + +| Value | Description | +| - | - | +| text | Button label | +| onPress | Callback function when button pressed | +| style | Button style | + + + + diff --git a/docs/AndroidBuildingFromSource.md b/docs/android-building-from-source.md similarity index 99% rename from docs/AndroidBuildingFromSource.md rename to docs/android-building-from-source.md index d88c46cdef5340..62b7d37d9f5f31 100644 --- a/docs/AndroidBuildingFromSource.md +++ b/docs/android-building-from-source.md @@ -4,7 +4,6 @@ title: Building React Native from source layout: docs category: Guides (Android) permalink: docs/android-building-from-source.html -banner: ejected next: communication-android previous: android-ui-performance --- diff --git a/docs/animated.md b/docs/animated.md new file mode 100644 index 00000000000000..aa6b6ae915d17a --- /dev/null +++ b/docs/animated.md @@ -0,0 +1,557 @@ +--- +id: animated +title: Animated +layout: docs +category: APIs +permalink: docs/animated.html +next: appregistry +previous: alertios +--- + +The `Animated` library is designed to make animations fluid, powerful, and +easy to build and maintain. `Animated` focuses on declarative relationships +between inputs and outputs, with configurable transforms in between, and +simple `start`/`stop` methods to control time-based animation execution. + +The simplest workflow for creating an animation is to create an +`Animated.Value`, hook it up to one or more style attributes of an animated +component, and then drive updates via animations using `Animated.timing()`: + +```javascript +Animated.timing( // Animate value over time + this.state.fadeAnim, // The value to drive + { + toValue: 1, // Animate to final value of 1 + } +).start(); // Start the animation +``` + +Refer to the [Animations](docs/animations.html#animated-api) guide to see +additional examples of `Animated` in action. + +## Overview + +There are two value types you can use with `Animated`: + +- [`Animated.Value()`](docs/animated.html#value) for single values +- [`Animated.ValueXY()`](docs/animated.html#valuexy) for vectors + +`Animated.Value` can bind to style properties or other props, and can be +interpolated as well. A single `Animated.Value` can drive any number of +properties. + +### Configuring animations + +`Animated` provides three types of animation types. Each animation type +provides a particular animation curve that controls how your values animate +from their initial value to the final value: + +- [`Animated.decay()`](docs/animated.html#decay) starts with an initial + velocity and gradually slows to a stop. +- [`Animated.spring()`](docs/animated.html#spring) provides a simple + spring physics model. +- [`Animated.timing()`](docs/animated.html#timing) animates a value over time + using [easing functions](docs/easing.html). + +In most cases, you will be using `timing()`. By default, it uses a symmetric +easeInOut curve that conveys the gradual acceleration of an object to full +speed and concludes by gradually decelerating to a stop. + +### Working with animations + +Animations are started by calling `start()` on your animation. `start()` +takes a completion callback that will be called when the animation is done. +If the animation finished running normally, the completion callback will be +invoked with `{finished: true}`. If the animation is done because `stop()` +was called on it before it could finish (e.g. because it was interrupted by a +gesture or another animation), then it will receive `{finished: false}`. + +### Using the native driver + +By using the native driver, we send everything about the animation to native +before starting the animation, allowing native code to perform the animation +on the UI thread without having to go through the bridge on every frame. +Once the animation has started, the JS thread can be blocked without +affecting the animation. + +You can use the native driver by specifying `useNativeDriver: true` in your +animation configuration. See the +[Animations](docs/animations.html#using-the-native-driver) guide to learn +more. + +### Animatable components + +Only animatable components can be animated. These special components do the +magic of binding the animated values to the properties, and do targeted +native updates to avoid the cost of the react render and reconciliation +process on every frame. They also handle cleanup on unmount so they are safe +by default. + +- [`createAnimatedComponent()`](docs/animated.html#createanimatedcomponent) + can be used to make a component animatable. + +`Animated` exports the following animatable components using the above +wrapper: + +- `Animated.Image` +- `Animated.ScrollView` +- `Animated.Text` +- `Animated.View` + +### Composing animations + +Animations can also be combined in complex ways using composition functions: + +- [`Animated.delay()`](docs/animated.html#delay) starts an animation after + a given delay. +- [`Animated.parallel()`](docs/animated.html#parallel) starts a number of + animations at the same time. +- [`Animated.sequence()`](docs/animated.html#sequence) starts the animations + in order, waiting for each to complete before starting the next. +- [`Animated.stagger()`](docs/animated.html#stagger) starts animations in + order and in parallel, but with successive delays. + +Animations can also be chained together simply by setting the `toValue` of +one animation to be another `Animated.Value`. See +[Tracking dynamic values](docs/animations.html#tracking-dynamic-values) in +the Animations guide. + +By default, if one animation is stopped or interrupted, then all other +animations in the group are also stopped. + +### Combining animated values + +You can combine two animated values via addition, multiplication, division, +or modulo to make a new animated value: + +- [`Animated.add()`](docs/animated.html#add) +- [`Animated.divide()`](docs/animated.html#divide) +- [`Animated.modulo()`](docs/animated.html#modulo) +- [`Animated.multiply()`](docs/animated.html#multiply) + +### Interpolation + +The `interpolate()` function allows input ranges to map to different output +ranges. By default, it will extrapolate the curve beyond the ranges given, +but you can also have it clamp the output value. It uses lineal interpolation +by default but also supports easing functions. + +- [`interpolate()`](docs/animated.html#interpolate) + +Read more about interpolation in the +[Animation](docs/animations.html#interpolation) guide. + +### Handling gestures and other events + +Gestures, like panning or scrolling, and other events can map directly to +animated values using `Animated.event()`. This is done with a structured map +syntax so that values can be extracted from complex event objects. The first +level is an array to allow mapping across multiple args, and that array +contains nested objects. + +- [`Animated.event()`](docs/animated.html#event) + +For example, when working with horizontal scrolling gestures, you would do +the following in order to map `event.nativeEvent.contentOffset.x` to +`scrollX` (an `Animated.Value`): + +```javascript + onScroll={Animated.event( + // scrollX = e.nativeEvent.contentOffset.x + [{ nativeEvent: { + contentOffset: { + x: scrollX + } + } + }] + )} +``` + + + +### Methods + +- [`decay`](docs/animated.html#decay) +- [`timing`](docs/animated.html#timing) +- [`spring`](docs/animated.html#spring) +- [`add`](docs/animated.html#add) +- [`divide`](docs/animated.html#divide) +- [`multiply`](docs/animated.html#multiply) +- [`modulo`](docs/animated.html#modulo) +- [`diffClamp`](docs/animated.html#diffclamp) +- [`delay`](docs/animated.html#delay) +- [`sequence`](docs/animated.html#sequence) +- [`parallel`](docs/animated.html#parallel) +- [`stagger`](docs/animated.html#stagger) +- [`loop`](docs/animated.html#loop) +- [`event`](docs/animated.html#event) +- [`forkEvent`](docs/animated.html#forkevent) +- [`unforkEvent`](docs/animated.html#unforkevent) + + +### Properties + +- [`Value`](docs/animated.html#value) +- [`ValueXY`](docs/animated.html#valuexy) +- [`Interpolation`](docs/animated.html#interpolation) +- [`Node`](docs/animated.html#node) +- [`createAnimatedComponent`](docs/animated.html#createanimatedcomponent) +- [`attachNativeEvent`](docs/animated.html#attachnativeevent) + + + + +--- + +# Reference + +## Methods + +### `decay()` + +```javascript +static decay(value, config) +``` + + +Animates a value from an initial velocity to zero based on a decay +coefficient. + +Config is an object that may have the following options: + + - `velocity`: Initial velocity. Required. + - `deceleration`: Rate of decay. Default 0.997. + - `isInteraction`: Whether or not this animation creates an "interaction handle" on the + `InteractionManager`. Default true. + - `useNativeDriver`: Uses the native driver when true. Default false. + + + + +--- + +### `timing()` + +```javascript +static timing(value, config) +``` + + +Animates a value along a timed easing curve. The +[`Easing`](docs/easing.html) module has tons of predefined curves, or you +can use your own function. + +Config is an object that may have the following options: + + - `duration`: Length of animation (milliseconds). Default 500. + - `easing`: Easing function to define curve. + Default is `Easing.inOut(Easing.ease)`. + - `delay`: Start the animation after delay (milliseconds). Default 0. + - `isInteraction`: Whether or not this animation creates an "interaction handle" on the + `InteractionManager`. Default true. + - `useNativeDriver`: Uses the native driver when true. Default false. + + + + +--- + +### `spring()` + +```javascript +static spring(value, config) +``` + + +Animates a value according to an analytical spring model based on +[damped harmonic oscillation](https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator). +Tracks velocity state to create fluid motions as the `toValue` updates, and +can be chained together. + +Config is an object that may have the following options. + +Note that you can only define one of bounciness/speed, tension/friction, or +stiffness/damping/mass, but not more than one: + +The friction/tension or bounciness/speed options match the spring model in +[Facebook Pop](https://github.com/facebook/pop), [Rebound](http://facebook.github.io/rebound/), +and [Origami](http://origami.design/). + + - `friction`: Controls "bounciness"/overshoot. Default 7. + - `tension`: Controls speed. Default 40. + - `speed`: Controls speed of the animation. Default 12. + - `bounciness`: Controls bounciness. Default 8. + +Specifying stiffness/damping/mass as parameters makes `Animated.spring` use an +analytical spring model based on the motion equations of a [damped harmonic +oscillator](https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator). +This behavior is slightly more precise and faithful to the physics behind +spring dynamics, and closely mimics the implementation in iOS's +CASpringAnimation primitive. + + - `stiffness`: The spring stiffness coefficient. Default 100. + - `damping`: Defines how the spring’s motion should be damped due to the forces of friction. + Default 10. + - `mass`: The mass of the object attached to the end of the spring. Default 1. + +Other configuration options are as follows: + + - `velocity`: The initial velocity of the object attached to the spring. Default 0 (object + is at rest). + - `overshootClamping`: Boolean indiciating whether the spring should be clamped and not + bounce. Default false. + - `restDisplacementThreshold`: The threshold of displacement from rest below which the + spring should be considered at rest. Default 0.001. + - `restSpeedThreshold`: The speed at which the spring should be considered at rest in pixels + per second. Default 0.001. + - `delay`: Start the animation after delay (milliseconds). Default 0. + - `isInteraction`: Whether or not this animation creates an "interaction handle" on the + `InteractionManager`. Default true. + - `useNativeDriver`: Uses the native driver when true. Default false. + + + + +--- + +### `add()` + +```javascript +static add(a, b) +``` + + +Creates a new Animated value composed from two Animated values added +together. + + + + +--- + +### `divide()` + +```javascript +static divide(a, b) +``` + + +Creates a new Animated value composed by dividing the first Animated value +by the second Animated value. + + + + +--- + +### `multiply()` + +```javascript +static multiply(a, b) +``` + + +Creates a new Animated value composed from two Animated values multiplied +together. + + + + +--- + +### `modulo()` + +```javascript +static modulo(a, modulus) +``` + + +Creates a new Animated value that is the (non-negative) modulo of the +provided Animated value + + + + +--- + +### `diffClamp()` + +```javascript +static diffClamp(a, min, max) +``` + + +Create a new Animated value that is limited between 2 values. It uses the +difference between the last value so even if the value is far from the bounds +it will start changing when the value starts getting closer again. +(`value = clamp(value + diff, min, max)`). + +This is useful with scroll events, for example, to show the navbar when +scrolling up and to hide it when scrolling down. + + + + +--- + +### `delay()` + +```javascript +static delay(time) +``` + + +Starts an animation after the given delay. + + + + +--- + +### `sequence()` + +```javascript +static sequence(animations) +``` + + +Starts an array of animations in order, waiting for each to complete +before starting the next. If the current running animation is stopped, no +following animations will be started. + + + + +--- + +### `parallel()` + +```javascript +static parallel(animations, config?) +``` + + +Starts an array of animations all at the same time. By default, if one +of the animations is stopped, they will all be stopped. You can override +this with the `stopTogether` flag. + + + + +--- + +### `stagger()` + +```javascript +static stagger(time, animations) +``` + + +Array of animations may run in parallel (overlap), but are started in +sequence with successive delays. Nice for doing trailing effects. + + + + +--- + +### `loop()` + +```javascript +static loop(animation) +``` + + +Loops a given animation continuously, so that each time it reaches the +end, it resets and begins again from the start. Can specify number of +times to loop using the key `iterations` in the config. Will loop without +blocking the UI thread if the child animation is set to `useNativeDriver: true`. +In addition, loops can prevent `VirtualizedList`-based components from rendering +more rows while the animation is running. You can pass `isInteraction: false` in the +child animation config to fix this. + + + + +--- + +### `event()` + +```javascript +static event(argMapping, config?) +``` + + +Takes an array of mappings and extracts values from each arg accordingly, +then calls `setValue` on the mapped outputs. e.g. + +```javascript + onScroll={Animated.event( + [{nativeEvent: {contentOffset: {x: this._scrollX}}}], + {listener: (event) => console.log(event)}, // Optional async listener + )} + ... + onPanResponderMove: Animated.event([ + null, // raw event arg ignored + {dx: this._panX}, // gestureState arg +{listener: (event, gestureState) => console.log(event, gestureState)}, // Optional async listener + ]), +``` + +Config is an object that may have the following options: + + - `listener`: Optional async listener. + - `useNativeDriver`: Uses the native driver when true. Default false. + + + + +--- + +### `forkEvent()` + +```javascript +static forkEvent(event, listener) +``` + + +Advanced imperative API for snooping on animated events that are passed in through props. Use +values directly where possible. + + + + +--- + +### `unforkEvent()` + +```javascript +static unforkEvent(event, listener) +``` + + + +## Properties + + + +--- + + + +--- + + + +--- + + + +--- + + + +--- + + + diff --git a/docs/TodayWidget.md b/docs/app-extensions.md similarity index 100% rename from docs/TodayWidget.md rename to docs/app-extensions.md diff --git a/docs/appregistry.md b/docs/appregistry.md new file mode 100644 index 00000000000000..83d119244601d6 --- /dev/null +++ b/docs/appregistry.md @@ -0,0 +1,227 @@ +--- +id: appregistry +title: AppRegistry +layout: docs +category: APIs +permalink: docs/appregistry.html +next: appstate +previous: animated +--- + + + +`AppRegistry` is the JS entry point to running all React Native apps. App +root components should register themselves with +`AppRegistry.registerComponent`, then the native system can load the bundle +for the app and then actually run the app when it's ready by invoking +`AppRegistry.runApplication`. + +To "stop" an application when a view should be destroyed, call +`AppRegistry.unmountApplicationComponentAtRootTag` with the tag that was +passed into `runApplication`. These should always be used as a pair. + +`AppRegistry` should be `require`d early in the `require` sequence to make +sure the JS execution environment is setup before other modules are +`require`d. + + +### Methods + +- [`setWrapperComponentProvider`](docs/appregistry.html#setwrappercomponentprovider) +- [`registerConfig`](docs/appregistry.html#registerconfig) +- [`registerComponent`](docs/appregistry.html#registercomponent) +- [`registerRunnable`](docs/appregistry.html#registerrunnable) +- [`registerSection`](docs/appregistry.html#registersection) +- [`getAppKeys`](docs/appregistry.html#getappkeys) +- [`getSectionKeys`](docs/appregistry.html#getsectionkeys) +- [`getSections`](docs/appregistry.html#getsections) +- [`getRunnable`](docs/appregistry.html#getrunnable) +- [`getRegistry`](docs/appregistry.html#getregistry) +- [`setComponentProviderInstrumentationHook`](docs/appregistry.html#setcomponentproviderinstrumentationhook) +- [`runApplication`](docs/appregistry.html#runapplication) +- [`unmountApplicationComponentAtRootTag`](docs/appregistry.html#unmountapplicationcomponentatroottag) +- [`registerHeadlessTask`](docs/appregistry.html#registerheadlesstask) +- [`startHeadlessTask`](docs/appregistry.html#startheadlesstask) + + + + +--- + +# Reference + +## Methods + +### `setWrapperComponentProvider()` + +```javascript +static setWrapperComponentProvider(provider) +``` + + + +--- + +### `registerConfig()` + +```javascript +static registerConfig(config) +``` + + + +--- + +### `registerComponent()` + +```javascript +static registerComponent(appKey, componentProvider, section?) +``` + + + +--- + +### `registerRunnable()` + +```javascript +static registerRunnable(appKey, run) +``` + + + +--- + +### `registerSection()` + +```javascript +static registerSection(appKey, component) +``` + + + +--- + +### `getAppKeys()` + +```javascript +static getAppKeys() +``` + + + +--- + +### `getSectionKeys()` + +```javascript +static getSectionKeys() +``` + + + +--- + +### `getSections()` + +```javascript +static getSections() +``` + + + +--- + +### `getRunnable()` + +```javascript +static getRunnable(appKey) +``` + + + +--- + +### `getRegistry()` + +```javascript +static getRegistry() +``` + + + +--- + +### `setComponentProviderInstrumentationHook()` + +```javascript +static setComponentProviderInstrumentationHook(hook) +``` + + + +--- + +### `runApplication()` + +```javascript +static runApplication(appKey, appParameters) +``` + + + +--- + +### `unmountApplicationComponentAtRootTag()` + +```javascript +static unmountApplicationComponentAtRootTag(rootTag) +``` + + + +--- + +### `registerHeadlessTask()` + +```javascript +static registerHeadlessTask(taskKey, task) +``` + + +Register a headless task. A headless task is a bit of code that runs without a UI. +@param taskKey the key associated with this task +@param task a promise returning function that takes some data passed from the native side as + the only argument; when the promise is resolved or rejected the native side is + notified of this event and it may decide to destroy the JS context. + + + + +--- + +### `startHeadlessTask()` + +```javascript +static startHeadlessTask(taskId, taskKey, data) +``` + + +Only called from native code. Starts a headless task. + +@param taskId the native id for this task instance to keep track of its execution +@param taskKey the key for the task to start +@param data the data to pass to the task + + + + diff --git a/docs/appstate.md b/docs/appstate.md new file mode 100644 index 00000000000000..ee208e3d0f9906 --- /dev/null +++ b/docs/appstate.md @@ -0,0 +1,131 @@ +--- +id: appstate +title: AppState +layout: docs +category: APIs +permalink: docs/appstate.html +next: asyncstorage +previous: appregistry +--- + +`AppState` can tell you if the app is in the foreground or background, +and notify you when the state changes. + +AppState is frequently used to determine the intent and proper behavior when +handling push notifications. + +### App States + + - `active` - The app is running in the foreground + - `background` - The app is running in the background. The user is either + in another app or on the home screen + - `inactive` - This is a state that occurs when transitioning between + foreground & background, and during periods of inactivity such as + entering the Multitasking view or in the event of an incoming call + +For more information, see +[Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html) + +### Basic Usage + +To see the current state, you can check `AppState.currentState`, which +will be kept up-to-date. However, `currentState` will be null at launch +while `AppState` retrieves it over the bridge. + +``` +import React, {Component} from 'react' +import {AppState, Text} from 'react-native' + +class AppStateExample extends Component { + + state = { + appState: AppState.currentState + } + + componentDidMount() { + AppState.addEventListener('change', this._handleAppStateChange); + } + + componentWillUnmount() { + AppState.removeEventListener('change', this._handleAppStateChange); + } + + _handleAppStateChange = (nextAppState) => { + if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') { + console.log('App has come to the foreground!') + } + this.setState({appState: nextAppState}); + } + + render() { + return ( + Current state is: {this.state.appState} + ); + } + +} +``` + +This example will only ever appear to say "Current state is: active" because +the app is only visible to the user when in the `active` state, and the null +state will happen only momentarily. + + +### Methods + +- [`=`](docs/appstate.html#) +- [`addEventListener`](docs/appstate.html#addeventlistener) +- [`removeEventListener`](docs/appstate.html#removeeventlistener) + + + + +--- + +# Reference + +## Methods + +### `=()` + +```javascript +=(;, () +``` + + + +--- + +### `addEventListener()` + +```javascript +addEventListener(type, handler) +``` + + +Add a handler to AppState changes by listening to the `change` event type +and providing the handler + +TODO: now that AppState is a subclass of NativeEventEmitter, we could deprecate +`addEventListener` and `removeEventListener` and just use `addListener` and +`listener.remove()` directly. That will be a breaking change though, as both +the method and event names are different (addListener events are currently +required to be globally unique). + + + + +--- + +### `removeEventListener()` + +```javascript +removeEventListener(type, handler) +``` + + +Remove a handler by passing the `change` event type and the handler + + + + diff --git a/docs/asyncstorage.md b/docs/asyncstorage.md new file mode 100644 index 00000000000000..2a88f2d47d0b1e --- /dev/null +++ b/docs/asyncstorage.md @@ -0,0 +1,420 @@ +--- +id: asyncstorage +title: AsyncStorage +layout: docs +category: APIs +permalink: docs/asyncstorage.html +next: backandroid +previous: appstate +--- +`AsyncStorage` is a simple, unencrypted, 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. + +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 +} +``` + +### Methods + +- [`getItem`](docs/asyncstorage.html#getitem) +- [`setItem`](docs/asyncstorage.html#setitem) +- [`removeItem`](docs/asyncstorage.html#removeitem) +- [`mergeItem`](docs/asyncstorage.html#mergeitem) +- [`clear`](docs/asyncstorage.html#clear) +- [`getAllKeys`](docs/asyncstorage.html#getallkeys) +- [`flushGetRequests`](docs/asyncstorage.html#flushgetrequests) +- [`multiGet`](docs/asyncstorage.html#multiget) +- [`multiSet`](docs/asyncstorage.html#multiset) +- [`multiRemove`](docs/asyncstorage.html#multiremove) +- [`multiMerge`](docs/asyncstorage.html#multimerge) + + + + +--- + +# Reference + +## Methods + +### `getItem()` + +```javascript +static getItem(key: string, [callback]: ?(error: ?Error, result: ?string) => void) +``` + +Fetches an item for a `key` and invokes a callback upon completion. +Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| key | string | No | Key of the item to fetch. | +| callback | ?(error: ?Error, result: ?string) => void | Yes | Function that will be called with a result if found or any error. | + + + + +--- + +### `setItem()` + +```javascript +static setItem(key: string, value: string, [callback]: ?(error: ?Error) => void) +``` + +Sets the value for a `key` and invokes a callback upon completion. +Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| key | string | No | Key of the item to set. | +| value | string | No | Value to set for the `key`. | +| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. | + + + + +--- + +### `removeItem()` + +```javascript +static removeItem(key: string, [callback]: ?(error: ?Error) => void) +``` + +Removes an item for a `key` and invokes a callback upon completion. +Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| key | string | No | Key of the item to remove. | +| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. | + + + + +--- + +### `mergeItem()` + +```javascript +static mergeItem(key: string, value: string, [callback]: ?(error: ?Error) => void) +``` + +Merges an existing `key` value with an input value, assuming both values +are stringified JSON. Returns a `Promise` object. + +**NOTE:** This is not supported by all native implementations. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| key | string | No | Key of the item to modify. | +| value | string | No | New value to merge for the `key`. | +| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. | + + + + +Example: + +```javascript + +let UID123_object = { + name: 'Chris', + age: 30, + traits: {hair: 'brown', eyes: 'brown'}, +}; +// 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); + }); + }); +}); + +// Console log result: +// => {'name':'Chris','age':31,'traits': +// {'shoe_size':10,'hair':'brown','eyes':'blue'}} +``` + + + +--- + +### `clear()` + +```javascript +static clear([callback]: ?(error: ?Error) => void) +``` + +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. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. | + + + + +--- + +### `getAllKeys()` + +```javascript +static getAllKeys([callback]: ?(error: ?Error, keys: ?Array) => void) +``` + +Gets *all* keys known to your app; for all callers, libraries, etc. +Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| callback | ?(error: ?Error, keys: ?Array) => void | Yes | Function that will be called the keys found and any error. | + + + + +--- + +### `flushGetRequests()` + +```javascript +static flushGetRequests(): [object Object] +``` + +Flushes any pending requests using a single batch call to get the data. + + + +--- + +### `multiGet()` + +```javascript +static multiGet(keys: Array, [callback]: ?(errors: ?Array, result: ?Array>) => void) +``` + +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']]) +``` + +The method returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| keys | Array | No | Array of key for the items to get. | +| callback | ?(errors: ?Array, result: ?Array>) => void | Yes | Function that will be called with a key-value array of the results, plus an array of any key-specific errors found. | + + + + +Example: + +```javascript +AsyncStorage.getAllKeys((err, keys) => { + AsyncStorage.multiGet(keys, (err, stores) => { + stores.map((result, i, store) => { + // get at each store's key/value so you can work with it + let key = store[i][0]; + let value = store[i][1]; + }); + }); +}); +``` + + + +--- + +### `multiSet()` + +```javascript +static multiSet(keyValuePairs: Array>, [callback]: ?(errors: ?Array) => void) +``` + +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); +``` + +The method returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| keyValuePairs | Array> | No | Array of key-value array for the items to set. | +| callback | ?(errors: ?Array) => void | Yes | Function that will be called with an array of any key-specific errors found. | + + + + +--- + +### `multiRemove()` + +```javascript +static multiRemove(keys: Array, [callback]: ?(errors: ?Array) => void) +``` + +Call this to batch the deletion of all keys in the `keys` array. Returns +a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| keys | Array | No | Array of key for the items to delete. | +| callback | ?(errors: ?Array) => void | Yes | Function that will be called an array of any key-specific errors found. | + + + + +Example: + +```javascript + +let keys = ['k1', 'k2']; +AsyncStorage.multiRemove(keys, (err) => { + // keys k1 & k2 removed, if they existed + // do most stuff after removal (if you want) +}); +``` + + + +--- + +### `multiMerge()` + +```javascript +static multiMerge(keyValuePairs: Array>, [callback]: ?(errors: ?Array) => void) +``` + +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. + +**NOTE**: This is not supported by all native implementations. + +**Parameters:** + +| Name | Type | Required | Description | +| - | - | - | - | +| keyValuePairs | Array> | No | Array of key-value array for the items to merge. | +| callback | ?(errors: ?Array) => void | Yes | Function that will be called with an array of any key-specific errors found. | + + + + +Example: + +```javascript + +// 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) => { + stores.map( (result, i, store) => { + let key = store[i][0]; + let val = store[i][1]; + console.log(key, val); + }); + }); + }); +}); + +// 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"}} +``` + + + diff --git a/docs/backandroid.md b/docs/backandroid.md new file mode 100644 index 00000000000000..0ee553c67bc16c --- /dev/null +++ b/docs/backandroid.md @@ -0,0 +1,56 @@ +--- +id: backandroid +title: BackAndroid +layout: docs +category: APIs +permalink: docs/backandroid.html +next: backhandler +previous: asyncstorage +--- + +Deprecated. Use BackHandler instead. + + +### Methods + +- [`exitApp`](docs/backandroid.html#exitapp) +- [`addEventListener`](docs/backandroid.html#addeventlistener) +- [`removeEventListener`](docs/backandroid.html#removeeventlistener) + + + + +--- + +# Reference + +## Methods + +### `exitApp()` + +```javascript +static exitApp() +``` + + + +--- + +### `addEventListener()` + +```javascript +static addEventListener(eventName, handler) +``` + + + +--- + +### `removeEventListener()` + +```javascript +static removeEventListener(eventName, handler) +``` + + + diff --git a/docs/backhandler.md b/docs/backhandler.md new file mode 100644 index 00000000000000..890a9325ca6ca6 --- /dev/null +++ b/docs/backhandler.md @@ -0,0 +1,83 @@ +--- +id: backhandler +title: BackHandler +layout: docs +category: APIs +permalink: docs/backhandler.html +next: cameraroll +previous: backhandler +--- + +Detect hardware button presses for back navigation. + +Android: Detect hardware back button presses, and programmatically invoke the default back button +functionality to exit the app if there are no listeners or if none of the listeners return true. + +tvOS: Detect presses of the menu button on the TV remote. (Still to be implemented: +programmatically disable menu button handling +functionality to exit the app if there are no listeners or if none of the listeners return true.) + +iOS: Not applicable. + +The event subscriptions are called in reverse order (i.e. last registered subscription first), +and if one subscription returns true then subscriptions registered earlier will not be called. + +Example: + +```javascript +BackHandler.addEventListener('hardwareBackPress', function() { + // this.onMainScreen and this.goBack are just examples, you need to use your own implementation here + // Typically you would use the navigator here to go to the last state. + + if (!this.onMainScreen()) { + this.goBack(); + return true; + } + return false; +}); +``` + + +### Methods + +- [`exitApp`](docs/backhandler.html#exitapp) +- [`addEventListener`](docs/backhandler.html#addeventlistener) +- [`removeEventListener`](docs/backhandler.html#removeeventlistener) + + + + +--- + +# Reference + +## Methods + +### `exitApp()` + +```javascript +static exitApp() +``` + + + +--- + +### `addEventListener()` + +```javascript +static addEventListener(eventName, handler) +``` + + + +--- + +### `removeEventListener()` + +```javascript +static removeEventListener(eventName, handler) +``` + + + diff --git a/docs/BuildingForAppleTV.md b/docs/building-for-apple-tv.md similarity index 99% rename from docs/BuildingForAppleTV.md rename to docs/building-for-apple-tv.md index 0dc6128cb97c9b..1692353f2ca1eb 100644 --- a/docs/BuildingForAppleTV.md +++ b/docs/building-for-apple-tv.md @@ -4,7 +4,6 @@ title: Building For Apple TV layout: docs category: Guides (iOS) permalink: docs/building-for-apple-tv.html -banner: ejected next: app-extensions previous: communication-ios --- diff --git a/docs/button.md b/docs/button.md new file mode 100644 index 00000000000000..e3eb4e881d089a --- /dev/null +++ b/docs/button.md @@ -0,0 +1,148 @@ +--- +id: button +title: Button +layout: docs +category: components +permalink: docs/button.html +next: checkbox +previous: activityindicator +--- +A basic button component that should render nicely on any platform. Supports +a minimal level of customization. + +
+ +If this button doesn't look right for your app, you can build your own +button using [TouchableOpacity](docs/touchableopacity.html) +or [TouchableNativeFeedback](docs/touchablenativefeedback.html). +For inspiration, look at the [source code for this button component](https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js). +Or, take a look at the [wide variety of button components built by the community](https://js.coach/react-native?search=button). + +Example usage: + +``` +import { Button } from 'react-native'; +... + +