diff --git a/docgen/server/generate.js b/docgen/server/generate.js index 5014f5bf8d2..2410bbe7542 100644 --- a/docgen/server/generate.js +++ b/docgen/server/generate.js @@ -198,6 +198,9 @@ function checkOutDocs() { return extractMarkdownFromHTMLDocs(file); }).then((res) => { // console.log(res); + if (res.markdown === undefined) { + return; + } const { frontmatter, markdown } = res; const version = extractDocVersionFromFilename(file); @@ -211,13 +214,19 @@ function checkOutDocs() { sidebarMetadata[version] = { "docs": { "APIs": [] } }; } - if (frontmatter.attributes.original_id !== "404" && frontmatter.attributes.original_id !== "index") { + if (frontmatter.attributes.original_id !== "404" + && frontmatter.attributes.original_id !== "index" + && frontmatter.attributes.original_id !== "help" + && frontmatter.attributes.original_id !== "users" + && frontmatter.attributes.original_id !== "showcase" + && frontmatter.attributes.original_id !== "support" + && frontmatter.attributes.original_id !== "versions") { sidebarMetadata[version]["docs"]["APIs"].push(frontmatter.attributes.original_id); - return fs.outputFile(pathToOutputFile.toString(), markdown); + return fs.outputFile(pathToOutputFile.toString(), markdown).then(() => {return;}).catch((e) => {console.error(e)}); } return; - }) + }); }); return seq; }).then(() => { @@ -229,12 +238,14 @@ function checkOutDocs() { filepath.create(CWD, '..', 'website', SIDEBAR_DIR); for (var version in sidebarMetadata) { if (sidebarMetadata.hasOwnProperty(version)) { - var sidebar = sidebarMetadata[version]; - - const pathToSidebarFile = filepath.create(CWD, BUILD_DIR, SIDEBAR_DIR, `version-${version}-sidebar.json`); - console.log(`Writing ${pathToSidebarFile}: ${sidebar}`); + // TODO: Problem: this series of promises is just wiritng the same version over and over. Figure out jhow to serialize this correctly. seq = seq.then(() => { - return fs.outputFile(pathToSidebarFile.toString(), JSON.stringify(sidebar)); + var sidebar = sidebarMetadata[version]; + + const pathToSidebarFile = filepath.create(CWD, '..', 'website', SIDEBAR_DIR, `version-${version}-sidebars.json`); + console.log(`Writing ${pathToSidebarFile}: ${sidebar}`); + + return fs.outputFile(pathToSidebarFile.toString(), JSON.stringify(sidebar)); }); } } @@ -244,10 +255,7 @@ function checkOutDocs() { const versions = Object.keys(sidebarMetadata); const pathToVersionsFile = filepath.create(CWD, BUILD_DIR, `versions.json`); - return fs.outputFile(pathToVersionsFile.toString(), JSON.stringify(versions)); - - for (var version in sidebarMetadata) { - } + return fs.outputFile(pathToVersionsFile.toString(), JSON.stringify(versions.reverse())); }); } @@ -265,12 +273,16 @@ function extractComponentNameFromFilename(file) { function extractMarkdownFromHTMLDocs(file) { if (file.indexOf("404") !== -1) { - return { frontmatter: {attributes: { original_id: '404', id: '404', permalink: '404.html'}}, markdown: '' }; + return { }; } // console.log(`Processing ${file}`); return JSDOM.fromFile(filepath.create(file).toString()) .then((dom) => { const body = bodyContentFromDOM(dom); + + if (!body) { + return {}; + } const componentName = extractComponentNameFromFilename(file); const version = extractDocVersionFromFilename(file); const markdown = generateMarkdown(componentName, body, version); diff --git a/docs/Accessibility.md b/docs/Accessibility.md deleted file mode 100644 index 8309c503644..00000000000 --- a/docs/Accessibility.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -id: accessibility -title: Accessibility ---- - -## Native App Accessibility (iOS and Android) -Both iOS and Android provide APIs for making apps accessible to people with disabilities. In addition, both platforms provide bundled assistive technologies, like the screen readers VoiceOver (iOS) and TalkBack (Android) for the visually impaired. Similarly, in React Native we have included APIs designed to provide developers with support for making apps more accessible. Take note, iOS and Android differ slightly in their approaches, and thus the React Native implementations may vary by platform. - -In addition to this documentation, you might find [this blog post](https://code.facebook.com/posts/435862739941212/making-react-native-apps-accessible/) about React Native accessibility to be useful. - -## Making Apps Accessible - -### Accessibility properties - -#### accessible (iOS, Android) - -When `true`, indicates that the view is an accessibility element. When a view is an accessibility element, it groups its children into a single selectable component. By default, all touchable elements are accessible. - -On Android, ‘accessible={true}’ property for a react-native View will be translated into native ‘focusable={true}’. - -```javascript - - text one - text two - -``` - -In the above example, we can't get accessibility focus separately on 'text one' and 'text two'. Instead we get focus on a parent view with 'accessible' property. - - - -#### accessibilityLabel (iOS, Android) - -When a view is marked as accessible, it is a good practice to set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected. VoiceOver will read this string when a user selects the associated element. - -To use, set the `accessibilityLabel` property to a custom string on your View: - -```javascript - - - Press me! - - -``` - -In the above example, the `accessibilityLabel` on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces. - -#### accessibilityTraits (iOS) - -Accessibility traits tell a person using VoiceOver what kind of element they have selected. Is this element a label? A button? A header? These questions are answered by `accessibilityTraits`. - -To use, set the `accessibilityTraits` property to one of (or an array of) accessibility trait strings: - -* **none** Used when the element has no traits. -* **button** Used when the element should be treated as a button. -* **link** Used when the element should be treated as a link. -* **header** Used when an element acts as a header for a content section (e.g. the title of a navigation bar). -* **search** Used when the text field element should also be treated as a search field. -* **image** Used when the element should be treated as an image. Can be combined with button or link, for example. -* **selected** Used when the element is selected. For example, a selected row in a table or a selected button within a segmented control. -* **plays** Used when the element plays its own sound when activated. -* **key** Used when the element acts as a keyboard key. -* **text** Used when the element should be treated as static text that cannot change. -* **summary** Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches. For example, when Weather first launches, the element with today's weather conditions is marked with this trait. -* **disabled** Used when the control is not enabled and does not respond to user input. -* **frequentUpdates** Used when the element frequently updates its label or value, but too often to send notifications. Allows an accessibility client to poll for changes. A stopwatch would be an example. -* **startsMedia** Used when activating an element starts a media session (e.g. playing a movie, recording audio) that should not be interrupted by output from an assistive technology, like VoiceOver. -* **adjustable** Used when an element can be "adjusted" (e.g. a slider). -* **allowsDirectInteraction** Used when an element allows direct touch interaction for VoiceOver users (for example, a view representing a piano keyboard). -* **pageTurn** Informs VoiceOver that it should scroll to the next page when it finishes reading the contents of the element. - -#### accessibilityViewIsModal (iOS) - -A Boolean value indicating whether VoiceOver should ignore the elements within views that are siblings of the receiver. - -For example, in a window that contains sibling views `A` and `B`, setting `accessibilityViewIsModal` to `true` on view `B` causes VoiceOver to ignore the elements in the view `A`. -On the other hand, if view `B` contains a child view `C` and you set `accessibilityViewIsModal` to `true` on view `C`, VoiceOver does not ignore the elements in view `A`. - -#### onAccessibilityTap (iOS) - -Use this property to assign a custom function to be called when someone activates an accessible element by double tapping on it while it's selected. - -#### onMagicTap (iOS) - -Assign this property to a custom function which will be called when someone performs the "magic tap" gesture, which is a double-tap with two fingers. A magic tap function should perform the most relevant action a user could take on a component. In the Phone app on iPhone, a magic tap answers a phone call, or ends the current one. If the selected element does not have an `onMagicTap` function, the system will traverse up the view hierarchy until it finds a view that does. - -#### accessibilityComponentType (Android) - -In some cases, we also want to alert the end user of the type of selected component (i.e., that it is a “button”). If we were using native buttons, this would work automatically. Since we are using javascript, we need to provide a bit more context for TalkBack. To do so, you must specify the ‘accessibilityComponentType’ property for any UI component. For instances, we support ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’ and so on. - -```javascript - - - Press me! - - -``` - -In the above example, the TouchableWithoutFeedback is being announced by TalkBack as a native Button. - -#### accessibilityLiveRegion (Android) - -When components dynamically change, we want TalkBack to alert the end user. This is made possible by the ‘accessibilityLiveRegion’ property. It can be set to ‘none’, ‘polite’ and ‘assertive’: - -* **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. - -```javascript - - - Click me - - - - Clicked {this.state.count} times - -``` - -In the above example method _addOne changes the state.count variable. As soon as an end user clicks the TouchableWithoutFeedback, TalkBack reads text in the Text view because of its 'accessibilityLiveRegion=”polite”' property. - -#### importantForAccessibility (Android) - -In the case of two overlapping UI components with the same parent, default accessibility focus can have unpredictable behavior. The ‘importantForAccessibility’ property will resolve this by controlling if a view fires accessibility events and if it is reported to accessibility services. It can be set to ‘auto’, ‘yes’, ‘no’ and ‘no-hide-descendants’ (the last value will force accessibility services to ignore the component and all of its children). - -```javascript - - - First layout - - - Second layout - - -``` - -In the above example, the yellow layout and its descendants are completely invisible to TalkBack and all other accessibility services. So we can easily use overlapping views with the same parent without confusing TalkBack. - -### Checking if a Screen Reader is Enabled - -The `AccessibilityInfo` API allows you to determine whether or not a screen reader is currently active. See the [AccessibilityInfo documentation](docs/accessibilityinfo.html) for details. - -### Sending Accessibility Events (Android) - -Sometimes it is useful to trigger an accessibility event on a UI component (i.e. when a custom view appears on a screen or a custom radio button has been selected). Native UIManager module exposes a method ‘sendAccessibilityEvent’ for this purpose. It takes two arguments: view tag and a type of an event. - -```javascript -_onPress: function() { - this.state.radioButton = this.state.radioButton === “radiobutton_checked” ? - “radiobutton_unchecked” : “radiobutton_checked”; - if (this.state.radioButton === “radiobutton_checked”) { - RCTUIManager.sendAccessibilityEvent( - ReactNative.findNodeHandle(this), - RCTUIManager.AccessibilityEventTypes.typeViewClicked); - } -} - - -``` - -In the above example we've created a custom radio button that now behaves like a native one. More specifically, TalkBack now correctly announces changes to the radio button selection. - - -## Testing VoiceOver Support (iOS) - -To enable VoiceOver, go to the Settings app on your iOS device. Tap General, then Accessibility. There you will find many tools that people use to make their devices more usable, such as bolder text, increased contrast, and VoiceOver. - -To enable VoiceOver, tap on VoiceOver under "Vision" and toggle the switch that appears at the top. - -At the very bottom of the Accessibility settings, there is an "Accessibility Shortcut". You can use this to toggle VoiceOver by triple clicking the Home button. diff --git a/docs/Animations.md b/docs/Animations.md deleted file mode 100644 index 42037e37ba2..00000000000 --- a/docs/Animations.md +++ /dev/null @@ -1,505 +0,0 @@ ---- -id: animations -title: Animations ---- - -Animations are very important to create a great user experience. -Stationary objects must overcome inertia as they start moving. -Objects in motion have momentum and rarely come to a stop immediately. -Animations allow you to convey physically believable motion in your interface. - -React Native provides two complementary animation systems: -[`Animated`](docs/animations.html#animated-api) for granular and interactive control of specific values, and -[`LayoutAnimation`](docs/animations.html#layoutanimation) for animated global layout transactions. - -## `Animated` API - -The [`Animated`](docs/animated.html) API is designed to make it very easy to concisely express a wide variety of interesting animation and interaction patterns in a very performant way. -`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. - -`Animated` exports four animatable component types: `View`, `Text`, `Image`, and `ScrollView`, but you can also create your own using `Animated.createAnimatedComponent()`. - -For example, a container view that fades in when it is mounted may look like this: - -```SnackPlayer -import React from 'react'; -import { Animated, Text, View } from 'react-native'; - -class FadeInView extends React.Component { - state = { - fadeAnim: new Animated.Value(0), // Initial value for opacity: 0 - } - - componentDidMount() { - Animated.timing( // Animate over time - this.state.fadeAnim, // The animated value to drive - { - toValue: 1, // Animate to opacity: 1 (opaque) - duration: 10000, // Make it take a while - } - ).start(); // Starts the animation - } - - render() { - let { fadeAnim } = this.state; - - return ( - - {this.props.children} - - ); - } -} - -// You can then use your `FadeInView` in place of a `View` in your components: -export default class App extends React.Component { - render() { - return ( - - - Fading in - - - ) - } -} -``` - -Let's break down what's happening here. -In the `FadeInView` constructor, a new `Animated.Value` called `fadeAnim` is initialized as part of `state`. -The opacity property on the `View` is mapped to this animated value. -Behind the scenes, the numeric value is extracted and used to set opacity. - -When the component mounts, the opacity is set to 0. -Then, an easing animation is started on the `fadeAnim` animated value, -which will update all of its dependent mappings (in this case, just the opacity) on each frame as the value animates to the final value of 1. - -This is done in an optimized way that is faster than calling `setState` and re-rendering. -Because the entire configuration is declarative, we will be able to implement further optimizations that serialize the configuration and runs the animation on a high-priority thread. - -### Configuring animations - -Animations are heavily configurable. Custom and predefined easing functions, delays, durations, decay factors, spring constants, and more can all be tweaked depending on the type of animation. - -`Animated` provides several animation types, the most commonly used one being [`Animated.timing()`](docs/animated.html#timing). -It supports animating a value over time using one of various predefined easing functions, or you can use your own. -Easing functions are typically used in animation to convey gradual acceleration and deceleration of objects. - -By default, `timing` will use a easeInOut curve that conveys gradual acceleration to full speed and concludes by gradually decelerating to a stop. -You can specify a different easing function by passing a `easing` parameter. -Custom `duration` or even a `delay` before the animation starts is also supported. - -For example, if we want to create a 2-second long animation of an object that slightly backs up before moving to its final position: - -```javascript -Animated.timing( - this.state.xPosition, - { - toValue: 100, - easing: Easing.back, - duration: 2000, - } -).start(); -``` - -Take a look at the [Configuring animations](docs/animated.html#configuring-animations) section of the `Animated` API reference to learn more about all the config parameters supported by the built-in animations. - -### Composing animations - -Animations can be combined and played in sequence or in parallel. -Sequential animations can play immediately after the previous animation has finished, -or they can start after a specified delay. -The `Animated` API provides several methods, such as `sequence()` and `delay()`, -each of which simply take an array of animations to execute and automatically calls `start()`/`stop()` as needed. - -For example, the following animation coasts to a stop, then it springs back while twirling in parallel: - -```javascript -Animated.sequence([ // decay, then spring to start and twirl - Animated.decay(position, { // coast to a stop - velocity: {x: gestureState.vx, y: gestureState.vy}, // velocity from gesture release - deceleration: 0.997, - }), - Animated.parallel([ // after decay, in parallel: - Animated.spring(position, { - toValue: {x: 0, y: 0} // return to start - }), - Animated.timing(twirl, { // and twirl - toValue: 360, - }), - ]), -]).start(); // start the sequence group -``` - -If one animation is stopped or interrupted, then all other animations in the group are also stopped. -`Animated.parallel` has a `stopTogether` option that can be set to `false` to disable this. - -You can find a full list of composition methods in the [Composing animations](docs/animated.html#composing-animations) section of the `Animated` API reference. - -### Combining animated values - -You can [combine two animated values](docs/animated.html#combining-animated-values) via addition, multiplication, division, or modulo to make a new animated value. - -There are some cases where an animated value needs to invert another animated value for calculation. -An example is inverting a scale (2x --> 0.5x): - -```javascript -const a = Animated.Value(1); -const b = Animated.divide(1, a); - -Animated.spring(a, { - toValue: 2, -}).start(); -``` - -### Interpolation - -Each property can be run through an interpolation first. -An interpolation maps input ranges to output ranges, -typically using a linear interpolation but also supports easing functions. -By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value. - -A simple mapping to convert a 0-1 range to a 0-100 range would be: - -```javascript -value.interpolate({ - inputRange: [0, 1], - outputRange: [0, 100], -}); -``` - -For example, you may want to think about your `Animated.Value` as going from 0 to 1, -but animate the position from 150px to 0px and the opacity from 0 to 1. -This can easily be done by modifying `style` from the example above like so: - -```javascript - style={{ - opacity: this.state.fadeAnim, // Binds directly - transform: [{ - translateY: this.state.fadeAnim.interpolate({ - inputRange: [0, 1], - outputRange: [150, 0] // 0 : 150, 0.5 : 75, 1 : 0 - }), - }], - }} -``` - -[`interpolate()`](docs/animated.html#interpolate) supports multiple range segments as well, which is handy for defining dead zones and other handy tricks. -For example, to get an negation relationship at -300 that goes to 0 at -100, then back up to 1 at 0, and then back down to zero at 100 followed by a dead-zone that remains at 0 for everything beyond that, you could do: - -```javascript -value.interpolate({ - inputRange: [-300, -100, 0, 100, 101], - outputRange: [300, 0, 1, 0, 0], -}); -``` - -Which would map like so: - -``` -Input | Output -------|------- - -400| 450 - -300| 300 - -200| 150 - -100| 0 - -50| 0.5 - 0| 1 - 50| 0.5 - 100| 0 - 101| 0 - 200| 0 -``` - -`interpolate()` also supports mapping to strings, allowing you to animate colors as well as values with units. For example, if you wanted to animate a rotation you could do: - -```javascript -value.interpolate({ - inputRange: [0, 360], - outputRange: ['0deg', '360deg'] -}) -``` - -`interpolate()` also supports arbitrary easing functions, many of which are already implemented in the -[`Easing`](docs/easing.html) module. -`interpolate()` also has configurable behavior for extrapolating the `outputRange`. -You can set the extrapolation by setting the `extrapolate`, `extrapolateLeft`, or `extrapolateRight` options. -The default value is `extend` but you can use `clamp` to prevent the output value from exceeding `outputRange`. - -### Tracking dynamic values - -Animated values can also track other values. -Just set the `toValue` of an animation to another animated value instead of a plain number. -For example, a "Chat Heads" animation like the one used by Messenger on Android could be implemented with a `spring()` pinned on another animated value, or with `timing()` and a `duration` of 0 for rigid tracking. -They can also be composed with interpolations: - -```javascript -Animated.spring(follower, {toValue: leader}).start(); -Animated.timing(opacity, { - toValue: pan.x.interpolate({ - inputRange: [0, 300], - outputRange: [1, 0], - }), -}).start(); -``` - -The `leader` and `follower` animated values would be implemented using `Animated.ValueXY()`. -`ValueXY` is a handy way to deal with 2D interactions, such as panning or dragging. -It is a simple wrapper that basically contains two `Animated.Value` instances and some helper functions that call through to them, -making `ValueXY` a drop-in replacement for `Value` in many cases. -It allows us to track both x and y values in the example above. - -### Tracking gestures - -Gestures, like panning or scrolling, and other events can map directly to animated values using [`Animated.event`](docs/animated.html#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. - -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 - } - } - }] - )} -``` - -When using `PanResponder`, you could use the following code to extract the x and y positions from `gestureState.dx` and `gestureState.dy`. -We use a `null` in the first position of the array, as we are only interested in the second argument passed to the `PanResponder` handler, -which is the `gestureState`. - -```javascript -onPanResponderMove={Animated.event( - [null, // ignore the native event - // extract dx and dy from gestureState - // like 'pan.x = gestureState.dx, pan.y = gestureState.dy' - {dx: pan.x, dy: pan.y} -])} -``` - -### Responding to the current animation value - -You may notice that there is no obvious way to read the current value while animating. -This is because the value may only be known in the native runtime due to optimizations. -If you need to run JavaScript in response to the current value, there are two approaches: - -- `spring.stopAnimation(callback)` will stop the animation and invoke `callback` with the final value. This is useful when making gesture transitions. -- `spring.addListener(callback)` will invoke `callback` asynchronously while the animation is running, providing a recent value. - This is useful for triggering state changes, - for example snapping a bobble to a new option as the user drags it closer, - because these larger state changes are less sensitive to a few frames of lag compared to continuous gestures like panning which need to run at 60 fps. - -`Animated` is designed to be fully serializable so that animations can be run in a high performance way, independent of the normal JavaScript event loop. -This does influence the API, so keep that in mind when it seems a little trickier to do something compared to a fully synchronous system. -Check out `Animated.Value.addListener` as a way to work around some of these limitations, -but use it sparingly since it might have performance implications in the future. - -### Using the native driver - -The `Animated` API is designed to be serializable. -By using the [native driver](http://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html), -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. - -Using the native driver for normal animations is quite simple. -Just add `useNativeDriver: true` to the animation config when starting it. - -```javascript -Animated.timing(this.state.animatedValue, { - toValue: 1, - duration: 500, - useNativeDriver: true, // <-- Add this -}).start(); -``` - -Animated values are only compatible with one driver so if you use native driver when starting an animation on a value, -make sure every animation on that value also uses the native driver. - -The native driver also works with `Animated.event`. -This is specially useful for animations that follow the scroll position as without the native driver, -the animation will always run a frame behind the gesture due to the async nature of React Native. - -```javascript - - {content} - -``` - -You can see the native driver in action by running the [RNTester app](https://github.com/facebook/react-native/blob/master/RNTester/), -then loading the Native Animated Example. -You can also take a look at the [source code](https://github.com/facebook/react-native/blob/master/RNTester/js/NativeAnimationsExample.js) to learn how these examples were produced. - -#### Caveats - -Not everything you can do with `Animated` is currently supported by the native driver. -The main limitation is that you can only animate non-layout properties: -things like `transform` and `opacity` will work, but flexbox and position properties will not. -When using `Animated.event`, it will only work with direct events and not bubbling events. -This means it does not work with `PanResponder` but does work with things like `ScrollView#onScroll`. - -### Bear in mind - -While using transform styles such as `rotateY`, `rotateX`, and others ensure the transform style `perspective` is in place. -At this time some animations may not render on Android without it. Example below. - -```javascript - -``` - -### Additional examples - -The RNTester app has various examples of `Animated` in use: - -- [AnimatedGratuitousApp](https://github.com/facebook/react-native/tree/master/RNTester/js/AnimatedGratuitousApp) -- [NativeAnimationsExample](https://github.com/facebook/react-native/blob/master/RNTester/js/NativeAnimationsExample.js) - -## `LayoutAnimation` API - -`LayoutAnimation` allows you to globally configure `create` and `update` -animations that will be used for all views in the next render/layout cycle. -This is useful for doing flexbox layout updates without bothering to measure or -calculate specific properties in order to animate them directly, and is -especially useful when layout changes may affect ancestors, for example a "see -more" expansion that also increases the size of the parent and pushes down the -row below which would otherwise require explicit coordination between the -components in order to animate them all in sync. - -Note that although `LayoutAnimation` is very powerful and can be quite useful, -it provides much less control than `Animated` and other animation libraries, so -you may need to use another approach if you can't get `LayoutAnimation` to do -what you want. - -Note that in order to get this to work on **Android** you need to set the following flags via `UIManager`: - -```javascript -UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true); -``` - -```SnackPlayer -import React from 'react'; -import { - NativeModules, - LayoutAnimation, - Text, - TouchableOpacity, - StyleSheet, - View, -} from 'react-native'; - -const { UIManager } = NativeModules; - -UIManager.setLayoutAnimationEnabledExperimental && - UIManager.setLayoutAnimationEnabledExperimental(true); - -export default class App extends React.Component { - state = { - w: 100, - h: 100, - }; - - _onPress = () => { - // Animate the update - LayoutAnimation.spring(); - this.setState({w: this.state.w + 15, h: this.state.h + 15}) - } - - render() { - return ( - - - - - Press me! - - - - ); - } -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - box: { - width: 200, - height: 200, - backgroundColor: 'red', - }, - button: { - backgroundColor: 'black', - paddingHorizontal: 20, - paddingVertical: 15, - marginTop: 15, - }, - buttonText: { - color: '#fff', - fontWeight: 'bold', - }, -}); -``` - -This example uses a preset value, you can customize the animations as -you need, see [LayoutAnimation.js](https://github.com/facebook/react-native/blob/master/Libraries/LayoutAnimation/LayoutAnimation.js) -for more information. - -## Additional notes - -### `requestAnimationFrame` - -`requestAnimationFrame` is a polyfill from the browser that you might be -familiar with. It accepts a function as its only argument and calls that -function before the next repaint. It is an essential building block for -animations that underlies all of the JavaScript-based animation APIs. In -general, you shouldn't need to call this yourself - the animation APIs will -manage frame updates for you. - -### `setNativeProps` - -As mentioned [in the Direct Manipulation section](docs/direct-manipulation.html), -`setNativeProps` allows us to modify properties of native-backed -components (components that are actually backed by native views, unlike -composite components) directly, without having to `setState` and -re-render the component hierarchy. - -We could use this in the Rebound example to update the scale - this -might be helpful if the component that we are updating is deeply nested -and hasn't been optimized with `shouldComponentUpdate`. - -If you find your animations with dropping frames (performing below 60 frames -per second), look into using `setNativeProps` or `shouldComponentUpdate` to -optimize them. Or you could run the animations on the UI thread rather than -the JavaScript thread [with the useNativeDriver -option](http://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html). -You may also want to defer any computationally intensive work until after -animations are complete, using the -[InteractionManager](docs/interactionmanager.html). You can monitor the -frame rate by using the In-App Developer Menu "FPS Monitor" tool. diff --git a/docs/Colors.md b/docs/Colors.md deleted file mode 100644 index 001791e6367..00000000000 --- a/docs/Colors.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -id: colors -title: Color Reference ---- - -Components in React Native are [styled using JavaScript](docs/style.html). Color properties usually match how [CSS works on the web](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). - -### Red-green-blue - -React Native supports `rgb()` and `rgba()` in both hexadecimal and functional notation: - -- `'#f0f'` (#rgb) -- `'#ff00ff'` (#rrggbb) - -- `'rgb(255, 0, 255)'` -- `'rgba(255, 255, 255, 1.0)'` - -- `'#f0ff'` (#rgba) -- `'#ff00ff00'` (#rrggbbaa) - -### Hue-saturation-lightness - -`hsl()` and `hsla()` is supported in functional notation: - -- `'hsl(360, 100%, 100%)'` -- `'hsla(360, 100%, 100%, 1.0)'` - -### `transparent` - -This is a shortcut for `rgba(0,0,0,0)`: - -- `'transparent'` - -### Named colors - -You can also use color names as values. React Native follows the [CSS3 specification](http://www.w3.org/TR/css3-color/#svg-color): - -- aliceblue (#f0f8ff) -- antiquewhite (#faebd7) -- aqua (#00ffff) -- aquamarine (#7fffd4) -- azure (#f0ffff) -- beige (#f5f5dc) -- bisque (#ffe4c4) -- black (#000000) -- blanchedalmond (#ffebcd) -- blue (#0000ff) -- blueviolet (#8a2be2) -- brown (#a52a2a) -- burlywood (#deb887) -- cadetblue (#5f9ea0) -- chartreuse (#7fff00) -- chocolate (#d2691e) -- coral (#ff7f50) -- cornflowerblue (#6495ed) -- cornsilk (#fff8dc) -- crimson (#dc143c) -- cyan (#00ffff) -- darkblue (#00008b) -- darkcyan (#008b8b) -- darkgoldenrod (#b8860b) -- darkgray (#a9a9a9) -- darkgreen (#006400) -- darkgrey (#a9a9a9) -- darkkhaki (#bdb76b) -- darkmagenta (#8b008b) -- darkolivegreen (#556b2f) -- darkorange (#ff8c00) -- darkorchid (#9932cc) -- darkred (#8b0000) -- darksalmon (#e9967a) -- darkseagreen (#8fbc8f) -- darkslateblue (#483d8b) -- darkslategrey (#2f4f4f) -- darkturquoise (#00ced1) -- darkviolet (#9400d3) -- deeppink (#ff1493) -- deepskyblue (#00bfff) -- dimgray (#696969) -- dimgrey (#696969) -- dodgerblue (#1e90ff) -- firebrick (#b22222) -- floralwhite (#fffaf0) -- forestgreen (#228b22) -- fuchsia (#ff00ff) -- gainsboro (#dcdcdc) -- ghostwhite (#f8f8ff) -- gold (#ffd700) -- goldenrod (#daa520) -- gray (#808080) -- green (#008000) -- greenyellow (#adff2f) -- grey (#808080) -- honeydew (#f0fff0) -- hotpink (#ff69b4) -- indianred (#cd5c5c) -- indigo (#4b0082) -- ivory (#fffff0) -- khaki (#f0e68c) -- lavender (#e6e6fa) -- lavenderblush (#fff0f5) -- lawngreen (#7cfc00) -- lemonchiffon (#fffacd) -- lightblue (#add8e6) -- lightcoral (#f08080) -- lightcyan (#e0ffff) -- lightgoldenrodyellow (#fafad2) -- lightgray (#d3d3d3) -- lightgreen (#90ee90) -- lightgrey (#d3d3d3) -- lightpink (#ffb6c1) -- lightsalmon (#ffa07a) -- lightseagreen (#20b2aa) -- lightskyblue (#87cefa) -- lightslategrey (#778899) -- lightsteelblue (#b0c4de) -- lightyellow (#ffffe0) -- lime (#00ff00) -- limegreen (#32cd32) -- linen (#faf0e6) -- magenta (#ff00ff) -- maroon (#800000) -- mediumaquamarine (#66cdaa) -- mediumblue (#0000cd) -- mediumorchid (#ba55d3) -- mediumpurple (#9370db) -- mediumseagreen (#3cb371) -- mediumslateblue (#7b68ee) -- mediumspringgreen (#00fa9a) -- mediumturquoise (#48d1cc) -- mediumvioletred (#c71585) -- midnightblue (#191970) -- mintcream (#f5fffa) -- mistyrose (#ffe4e1) -- moccasin (#ffe4b5) -- navajowhite (#ffdead) -- navy (#000080) -- oldlace (#fdf5e6) -- olive (#808000) -- olivedrab (#6b8e23) -- orange (#ffa500) -- orangered (#ff4500) -- orchid (#da70d6) -- palegoldenrod (#eee8aa) -- palegreen (#98fb98) -- paleturquoise (#afeeee) -- palevioletred (#db7093) -- papayawhip (#ffefd5) -- peachpuff (#ffdab9) -- peru (#cd853f) -- pink (#ffc0cb) -- plum (#dda0dd) -- powderblue (#b0e0e6) -- purple (#800080) -- rebeccapurple (#663399) -- red (#ff0000) -- rosybrown (#bc8f8f) -- royalblue (#4169e1) -- saddlebrown (#8b4513) -- salmon (#fa8072) -- sandybrown (#f4a460) -- seagreen (#2e8b57) -- seashell (#fff5ee) -- sienna (#a0522d) -- silver (#c0c0c0) -- skyblue (#87ceeb) -- slateblue (#6a5acd) -- slategray (#708090) -- snow (#fffafa) -- springgreen (#00ff7f) -- steelblue (#4682b4) -- tan (#d2b48c) -- teal (#008080) -- thistle (#d8bfd8) -- tomato (#ff6347) -- turquoise (#40e0d0) -- violet (#ee82ee) -- wheat (#f5deb3) -- white (#ffffff) -- whitesmoke (#f5f5f5) -- yellow (#ffff00) -- yellowgreen (#9acd32) diff --git a/docs/Debugging.md b/docs/Debugging.md deleted file mode 100644 index 61cff179fc1..00000000000 --- a/docs/Debugging.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -id: debugging -title: Debugging ---- - -## Enabling Keyboard Shortcuts - -React Native supports a few keyboard shortcuts in the iOS Simulator. They are described below. To enable them, open the Hardware menu, select Keyboard, and make sure that "Connect Hardware Keyboard" is checked. - -## Accessing the In-App Developer Menu - -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 `⌘D` keyboard shortcut when your app is running in the iOS Simulator, or `⌘M` when running in an Android emulator. - -![](img/DeveloperMenu.png) - -> The Developer Menu is disabled in release (production) builds. - -## Reloading JavaScript - -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 `⌘R` in the iOS Simulator, or tap `R` twice on Android emulators. - -### Automatic reloading - -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. - -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. - -> 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. - -You will need to rebuild your app for changes to take effect in certain situations: - -* 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 - -Errors and warnings are displayed inside your app in development builds. - -### Errors - -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. - -### Warnings - -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. - -As with a RedBox, you can use `console.warn()` to trigger a YellowBox. - -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: ...'];`. - -In CI/Xcode, YellowBoxes can also be disabled by setting the `IS_TESTING` environment variable. - -> RedBoxes and YellowBoxes are automatically disabled in release (production) builds. - -## 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). - -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 (`⌘⌥I` on macOS, `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. - -> Note: the React Developer Tools Chrome extension does not work with React Native, but you can use its standalone version instead. Read [this section](docs/debugging.html#react-developer-tools) to learn how. - -### 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. - -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. - -## React Developer Tools - -You can use [the standalone version of React Developer Tools](https://github.com/facebook/react-devtools/tree/master/packages/react-devtools) to debug the React component hierarchy. To use it, install the `react-devtools` package globally: - -``` -npm install -g react-devtools -``` - -Now run `react-devtools` from the terminal to launch the standalone DevTools app: - -``` -react-devtools -``` - -![React DevTools](img/ReactDevTools.png) - -It should connect to your simulator within a few seconds. - -> Note: if you prefer to avoid global installations, you can add `react-devtools` as a project dependency. Add the `react-devtools` package to your project using `npm install --save-dev react-devtools`, then add `"react-devtools": "react-devtools"` to the `scripts` section in your `package.json`, and then run `npm run react-devtools` from your project folder to open the DevTools. - -### Integration with React Native Inspector - -Open the in-app developer menu and choose "Show Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it: - -![React Native Inspector](img/Inspector.gif) - -However, when `react-devtools` is running, Inspector will enter a special collapsed mode, and instead use the DevTools as primary UI. In this mode, clicking on something in the simulator will bring up the relevant components in the DevTools: - -![React DevTools Inspector Integration](img/ReactDevToolsInspector.gif) - -You can choose "Hide Inspector" in the same menu to exit this mode. - -### Inspecting Component Instances - -When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console. - -First, follow the instructions for debugging in Chrome to open the Chrome console. - -Make sure that the dropdown in the top left corner of the Chrome console says `debuggerWorker.js`. **This step is essential.** - -Then select a React component in React DevTools. There is a search box at the top that helps you find one by name. As soon as you select it, it will be available as `$r` in the Chrome console, letting you inspect its props, state, and instance properties. - -![React DevTools Chrome Console Integration](img/ReactDevToolsDollarR.gif) - -## Performance Monitor - -You can enable a performance overlay to help you debug performance problems by selecting "Perf Monitor" in the Developer Menu. - -
- -# Debugging in Ejected Apps - - - -## 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: - -``` -$ react-native log-ios -$ react-native log-android -``` - -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. - -> If you're using Create React Native App, console logs already appear in the same terminal output as the packager. - -## Debugging on a device with Chrome Developer Tools - -> If you're using Create React Native App, this is configured for you already. - -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. - -> 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 with [Stetho](http://facebook.github.io/stetho/) on Android - -Follow this guide to enable Stetho for Debug mode: - -1. In `android/app/build.gradle`, add these lines in the `dependencies` section: - - ```gradle - debugCompile 'com.facebook.stetho:stetho:1.5.0' - debugCompile 'com.facebook.stetho:stetho-okhttp3:1.5.0' - ``` - -> The above will configure Stetho v1.5.0. You can check at http://facebook.github.io/stetho/ if a newer version is available. - -2. Create the following Java classes to wrap the Stetho call, one for release and one for debug: - - ```java - // android/app/src/release/java/com/{yourAppName}/StethoWrapper.java - - public class StethoWrapper { - - public static void initialize(Context context) { - // NO_OP - } - - public static void addInterceptor() { - // NO_OP - } - } - ``` - - ```java - // android/app/src/debug/java/com/{yourAppName}/StethoWrapper.java - - public class StethoWrapper { - public static void initialize(Context context) { - Stetho.initializeWithDefaults(context); - } - - public static void addInterceptor() { - OkHttpClient client = OkHttpClientProvider.getOkHttpClient() - .newBuilder() - .addNetworkInterceptor(new StethoInterceptor()) - .build(); - - OkHttpClientProvider.replaceOkHttpClient(client); - } - } - ``` - -3. Open `android/app/src/main/java/com/{yourAppName}/MainApplication.java` and replace the original `onCreate` function: - -```java - public void onCreate() { - super.onCreate(); - - if (BuildConfig.DEBUG) { - StethoWrapper.initialize(this); - StethoWrapper.addInterceptor(); - } - - SoLoader.init(this, /* native exopackage */ false); - } -``` - -4. Open the project in Android Studio and resolve any dependency issues. The IDE should guide you through this steps after hovering your pointer over the red lines. - -5. Run `react-native run-android`. - -6. In a new Chrome tab, open: `chrome://inspect`, then click on the 'Inspect device' item next to "Powered by Stetho". - -## Debugging native code - -When working with native code, such as when writing native modules, you can launch the app from Android Studio or Xcode and take advantage of the native debugging features (setting up breakpoints, etc.) as you would in case of building a standard native app. diff --git a/docs/Images.md b/docs/Images.md deleted file mode 100644 index f552c786ed9..00000000000 --- a/docs/Images.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -id: images -title: Images ---- - -## Static Image Resources - -React Native provides a unified way of managing images and other media assets in your iOS and Android apps. To add a static image to your app, place it somewhere in your source code tree and reference it like this: - -```javascript - -``` - -The image name is resolved the same way JS modules are resolved. In the example above, the packager will look for `my-icon.png` in the same folder as the component that requires it. Also, if you have `my-icon.ios.png` and `my-icon.android.png`, the packager will pick the correct file for the platform. - -You can also use the `@2x` and `@3x` suffixes to provide images for different screen densities. If you have the following file structure: - -``` -. -├── button.js -└── img - ├── check@2x.png - └── check@3x.png -``` - -...and `button.js` code contains: - -```javascript - -``` - -...the packager will bundle and serve the image corresponding to device's screen density. For example, `check@2x.png`, will be used on an iPhone 7, while`check@3x.png` will be used on an iPhone 7 Plus or a Nexus 5. If there is no image matching the screen density, the closest best option will be selected. - -On Windows, you might need to restart the packager if you add new images to your project. - -Here are some benefits that you get: - -1. Same system on iOS and Android. -2. Images live in the same folder as your JavaScript code. Components are self-contained. -3. No global namespace, i.e. you don't have to worry about name collisions. -4. Only the images that are actually used will be packaged into your app. -5. Adding and changing images doesn't require app recompilation, just refresh the simulator as you normally do. -6. The packager knows the image dimensions, no need to duplicate it in the code. -7. Images can be distributed via [npm](https://www.npmjs.com/) packages. - -In order for this to work, the image name in `require` has to be known statically. - -```javascript -// GOOD - - -// BAD -var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive'; - - -// GOOD -var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png'); - -``` - -Note that image sources required this way include size (width, height) info for the Image. If you need to scale the image dynamically (i.e. via flex), you may need to manually set `{ width: undefined, height: undefined }` on the style attribute. - -## Static Non-Image Resources - -The `require` syntax described above can be used to statically include audio, video or document files in your project as well. Most common file types are supported including `.mp3`, `.wav`, `.mp4`, `.mov`, `.html` and `.pdf`. See [packager defaults](https://github.com/facebook/metro-bundler/blob/master/packages/metro-bundler/src/defaults.js#L13-L18) for the full list. - -You can add support for other types by creating a packager config file (see the [packager config file](https://github.com/facebook/react-native/blob/master/local-cli/util/Config.js#L34-L39) for the full list of configuration options). - -A caveat is that videos must use absolute positioning instead of `flexGrow`, since size info is not currently passed for non-image assets. This limitation doesn't occur for videos that are linked directly into Xcode or the Assets folder for Android. - -## Images From Hybrid App's Resources - -If you are building a hybrid app (some UIs in React Native, some UIs in platform code) you can still use images that are already bundled into the app. - -For images included via Xcode asset catalogs or in the Android drawable folder, use the image name without the extension: - -```javascript - -``` - -For images in the Android assets folder, use the `asset:/` scheme: - -```javascript - -``` - -These approaches provide no safety checks. It's up to you to guarantee that those images are available in the application. Also you have to specify image dimensions manually. - -## Network Images - -Many of the images you will display in your app will not be available at compile time, or you will want to load some dynamically to keep the binary size down. Unlike with static resources, *you will need to manually specify the dimensions of your image*. It's highly recommended that you use https as well in order to satisfy [App Transport Security](docs/running-on-device.html#app-transport-security) requirements on iOS. - -```javascript -// GOOD - - -// BAD - -``` - -### Network Requests for Images - - If you would like to set such things as the HTTP-Verb, Headers or a Body along with the image request, you may do this by defining these properties on the source object: - - ```javascript - - ``` - -## Uri Data Images - -Sometimes, you might be getting encoded image data from a REST API call. You can use the `'data:'` uri scheme to use these images. Same as for network resources, *you will need to manually specify the dimensions of your image*. - -> This is recommended for very small and dynamic images only, like icons in a list from a DB. - -```javascript -// include at least width and height! - -``` - -### Cache Control (iOS Only) - -In some cases you might only want to display an image if it is already in the local cache, i.e. a low resolution placeholder until a higher resolution is available. In other cases you do not care if the image is outdated and are willing to display an outdated image to save bandwidth. The `cache` source property gives you control over how the network layer interacts with the cache. - -* `default`: Use the native platforms default strategy. -* `reload`: The data for the URL will be loaded from the originating source. -No existing cache data should be used to satisfy a URL load request. -* `force-cache`: The existing cached data will be used to satisfy the request, -regardless of its age or expiration date. If there is no existing data in the cache -corresponding the request, the data is loaded from the originating source. -* `only-if-cached`: The existing cache data will be used to satisfy a request, regardless of -its age or expiration date. If there is no existing data in the cache corresponding -to a URL load request, no attempt is made to load the data from the originating source, -and the load is considered to have failed. - -```javascript - -``` - -## Local Filesystem Images - -See [CameraRoll](docs/cameraroll.html) for an example of -using local resources that are outside of `Images.xcassets`. - -### Best Camera Roll Image - -iOS saves multiple sizes for the same image in your Camera Roll, it is very important to pick the one that's as close as possible for performance reasons. You wouldn't want to use the full quality 3264x2448 image as source when displaying a 200x200 thumbnail. If there's an exact match, React Native will pick it, otherwise it's going to use the first one that's at least 50% bigger in order to avoid blur when resizing from a close size. All of this is done by default so you don't have to worry about writing the tedious (and error prone) code to do it yourself. - -## Why Not Automatically Size Everything? - -*In the browser* if you don't give a size to an image, the browser is going to render a 0x0 element, download the image, and then render the image based with the correct size. The big issue with this behavior is that your UI is going to jump all around as images load, this makes for a very bad user experience. - -*In React Native* this behavior is intentionally not implemented. It is more work for the developer to know the dimensions (or aspect ratio) of the remote image in advance, but we believe that it leads to a better user experience. Static images loaded from the app bundle via the `require('./my-icon.png')` syntax *can be automatically sized* because their dimensions are available immediately at the time of mounting. - -For example, the result of `require('./my-icon.png')` might be: - -```javascript -{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573} -``` - -## Source as an object - -In React Native, one interesting decision is that the `src` attribute is named `source` and doesn't take a string but an object with a `uri` attribute. - -```javascript - -``` - -On the infrastructure side, the reason is that it allows us to attach metadata to this object. For example if you are using `require('./my-icon.png')`, then we add information about its actual location and size (don't rely on this fact, it might change in the future!). This is also future proofing, for example we may want to support sprites at some point, instead of outputting `{uri: ...}`, we can output `{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}` and transparently support spriting on all the existing call sites. - -On the user side, this lets you annotate the object with useful attributes such as the dimension of the image in order to compute the size it's going to be displayed in. Feel free to use it as your data structure to store more information about your image. - -## Background Image via Nesting - -A common feature request from developers familiar with the web is `background-image`. To handle this use case, you can use the `` component, which has the same props as ``, and add whatever children to it you would like to layer on top of it. - -You might not want to use `` in some cases, since the implementation is very simple. Refer to ``'s [source code](https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageBackground.js) for more insight, and create your own custom component when needed. - -```javascript -return ( - - Inside - -); -``` - -## iOS Border Radius Styles - -Please note that the following corner specific, border radius style properties are currently ignored by iOS's image component: - -* `borderTopLeftRadius` -* `borderTopRightRadius` -* `borderBottomLeftRadius` -* `borderBottomRightRadius` - -## Off-thread Decoding - -Image decoding can take more than a frame-worth of time. This is one of the major sources of frame drops on the web because decoding is done in the main thread. In React Native, image decoding is done in a different thread. In practice, you already need to handle the case when the image is not downloaded yet, so displaying the placeholder for a few more frames while it is decoding does not require any code change. diff --git a/docs/Navigation.md b/docs/Navigation.md deleted file mode 100644 index 211498b33b6..00000000000 --- a/docs/Navigation.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: navigation -title: Navigating Between Screens ---- - -Mobile apps are rarely made up of a single screen. Managing the presentation of, and transition between, multiple screens is typically handled by what is known as a navigator. - -This guide covers the various navigation components available in React Native. -If you are just getting started with navigation, you will probably want to use [React Navigation](docs/navigation.html#react-navigation). React Navigation provides an easy to use navigation solution, with the ability to present common stack navigation and tabbed navigation patterns on both iOS and Android. As this is a JavaScript implementation, it provides the greatest amount of configurability as well as flexibility when integrating with state management libraries such as [redux](https://reactnavigation.org/docs/guides/redux). - -If you're only targeting iOS, you may want to also check out [NavigatorIOS](docs/navigation.html#navigatorios) as a way of providing a native look and feel with minimal configuration, as it provides a wrapper around the native `UINavigationController` class. This component will not work on Android, however. - -If you'd like to achieve a native look and feel on both iOS and Android, or you're integrating React Native into an app that already manages navigation natively, the following libraries provide native navigation on both platforms: [native-navigation](http://airbnb.io/native-navigation/), [react-native-navigation](https://github.com/wix/react-native-navigation). - -## React Navigation - -The community solution to navigation is a standalone library that allows developers to set up the screens of an app with just a few lines of code. - -The first step is to install in your project: - -``` -npm install --save react-navigation -``` - -Then you can quickly create an app with a home screen and a profile screen: - -``` -import { - StackNavigator, -} from 'react-navigation'; - -const App = StackNavigator({ - Home: { screen: HomeScreen }, - Profile: { screen: ProfileScreen }, -}); -``` - -Each screen component can set navigation options such as the header title. It can use action creators on the `navigation` prop to link to other screens: - -``` -class HomeScreen extends React.Component { - static navigationOptions = { - title: 'Welcome', - }; - render() { - const { navigate } = this.props.navigation; - return ( -