Compare commits

...
Author SHA1 Message Date
Mike Grabowski 0adb1b35e8 [0.43.0-rc.1] Bump version numbers 2017-03-06 12:28:17 +01:00
Eric Vicenti 0756c663bc Remove NavigationExperimental examples
Summary: NavigationExperimental is deprecated, so we should avoid documenting it with examples

Reviewed By: lacker, hramos

Differential Revision: D4634484

fbshipit-source-id: 6c8b114d2a7b49c75ec548025384fa6ed75cb2d2
2017-03-06 12:28:01 +01:00
Eric Vicenti 9d6087ffc3 Add deprecation warning for NavigationExperimental
Summary: Starting in RN 0.43, lets start recommending people to move off of NavExperimental, now that a better navigation option is available, and hybrid options on the horizon.

Reviewed By: hramos

Differential Revision: D4634268

fbshipit-source-id: 2f37cc62f9729ae123d85f609a88f84516a5ae92
2017-03-06 12:27:41 +01:00
Spencer Ahrens 8b4d2376f5 Improve docs
Reviewed By: hramos

Differential Revision: D4649351

fbshipit-source-id: 06cbd735bdb51b6d9d4997a348cbc191193485aa
2017-03-06 12:27:09 +01:00
Spencer Ahrens 3cdb567908 Add to docs
Reviewed By: hramos

Differential Revision: D4638645

fbshipit-source-id: 6a37a5fd4e0d8c7769f6c241142b949dba665c34
2017-03-06 12:21:56 +01:00
Eric Vicenti 39eddc1a56 Add deprecation warning for NavigationExperimental
Summary: Starting in RN 0.43, lets start recommending people to move off of NavExperimental, now that a better navigation option is available, and hybrid options on the horizon.

Reviewed By: hramos

Differential Revision: D4634268

fbshipit-source-id: 2f37cc62f9729ae123d85f609a88f84516a5ae92
2017-03-06 12:20:42 +01:00
Mike Grabowski c72a44874b [0.43.0-rc.0] Bump version numbers 2017-03-02 15:44:53 +01:00
16 changed files with 123 additions and 1687 deletions
+25 -9
View File
@@ -77,7 +77,9 @@ class FlatListExample extends React.PureComponent {
}
render() {
const filterRegex = new RegExp(String(this.state.filterText), 'i');
const filter = (item) => (filterRegex.test(item.text) || filterRegex.test(item.title));
const filter = (item) => (
filterRegex.test(item.text) || filterRegex.test(item.title)
);
const filteredData = this.state.data.filter(filter);
return (
<UIExplorerPage
@@ -112,9 +114,14 @@ class FlatListExample extends React.PureComponent {
data={filteredData}
debug={this.state.debug}
disableVirtualization={!this.state.virtualized}
getItemLayout={this.state.fixedHeight ? this._getItemLayout : undefined}
getItemLayout={this.state.fixedHeight ?
this._getItemLayout :
undefined
}
horizontal={this.state.horizontal}
key={(this.state.horizontal ? 'h' : 'v') + (this.state.fixedHeight ? 'f' : 'd')}
key={(this.state.horizontal ? 'h' : 'v') +
(this.state.fixedHeight ? 'f' : 'd')
}
legacyImplementation={false}
numColumns={1}
onRefresh={this._onRefresh}
@@ -145,22 +152,31 @@ class FlatListExample extends React.PureComponent {
};
_shouldItemUpdate(prev, next) {
/**
* Note that this does not check state.horizontal or state.fixedheight because we blow away the
* whole list by changing the key in those cases. Make sure that you do the same in your code,
* or incorporate all relevant data into the item data, or skip this optimization entirely.
* Note that this does not check state.horizontal or state.fixedheight
* because we blow away the whole list by changing the key in those cases.
* Make sure that you do the same in your code, or incorporate all relevant
* data into the item data, or skip this optimization entirely.
*/
return prev.item !== next.item;
}
// This is called when items change viewability by scrolling into or out of the viewable area.
// This is called when items change viewability by scrolling into or out of
// the viewable area.
_onViewableItemsChanged = (info: {
changed: Array<{
key: string, isViewable: boolean, item: any, index: ?number, section?: any
key: string,
isViewable: boolean,
item: any,
index: ?number,
section?: any,
}>
}
) => {
// Impressions can be logged here
if (this.state.logViewable) {
infoLog('onViewableItemsChanged: ', info.changed.map((v) => ({...v, item: '...'})));
infoLog(
'onViewableItemsChanged: ',
info.changed.map((v) => ({...v, item: '...'})),
);
}
};
_pressItem = (key: number) => {
@@ -1,486 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';
const NavigationExampleRow = require('./NavigationExampleRow');
const React = require('react');
const ReactNative = require('react-native');
/**
* Basic example that shows how to use <NavigationCardStack /> to build
* an app with composite navigation system.
* @providesModule NavigationCardStack-NavigationHeader-Tabs-example
*/
const {
Component,
PropTypes,
} = React;
const {
NavigationExperimental,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} = ReactNative;
const {
CardStack: NavigationCardStack,
Header: NavigationHeader,
PropTypes: NavigationPropTypes,
StateUtils: NavigationStateUtils,
} = NavigationExperimental;
// First Step.
// Define what app navigation state will look like.
function createAppNavigationState(): Object {
return {
// Three tabs.
tabs: {
index: 0,
routes: [
{key: 'apple'},
{key: 'banana'},
{key: 'orange'},
],
},
// Scenes for the `apple` tab.
apple: {
index: 0,
routes: [{key: 'Apple Home'}],
},
// Scenes for the `banana` tab.
banana: {
index: 0,
routes: [{key: 'Banana Home'}],
},
// Scenes for the `orange` tab.
orange: {
index: 0,
routes: [{key: 'Orange Home'}],
},
};
}
// Next step.
// Define what app navigation state shall be updated.
function updateAppNavigationState(
state: Object,
action: Object,
): Object {
let {type} = action;
if (type === 'BackAction') {
type = 'pop';
}
switch (type) {
case 'push': {
// Push a route into the scenes stack.
const route: Object = action.route;
const {tabs} = state;
const tabKey = tabs.routes[tabs.index].key;
const scenes = state[tabKey];
const nextScenes = NavigationStateUtils.push(scenes, route);
if (scenes !== nextScenes) {
return {
...state,
[tabKey]: nextScenes,
};
}
break;
}
case 'pop': {
// Pops a route from the scenes stack.
const {tabs} = state;
const tabKey = tabs.routes[tabs.index].key;
const scenes = state[tabKey];
const nextScenes = NavigationStateUtils.pop(scenes);
if (scenes !== nextScenes) {
return {
...state,
[tabKey]: nextScenes,
};
}
break;
}
case 'selectTab': {
// Switches the tab.
const tabKey: string = action.tabKey;
const tabs = NavigationStateUtils.jumpTo(state.tabs, tabKey);
if (tabs !== state.tabs) {
return {
...state,
tabs,
};
}
}
}
return state;
}
// Next step.
// Defines a helper function that creates a HOC (higher-order-component)
// which provides a function `navigate` through component props. The
// `navigate` function will be used to invoke navigation changes.
// This serves a convenient way for a component to navigate.
function createAppNavigationContainer(ComponentClass) {
const key = '_yourAppNavigationContainerNavigateCall';
class Container extends Component {
static contextTypes = {
[key]: PropTypes.func,
};
static childContextTypes = {
[key]: PropTypes.func.isRequired,
};
static propTypes = {
navigate: PropTypes.func,
};
getChildContext(): Object {
return {
[key]: this.context[key] || this.props.navigate,
};
}
render(): React.Element {
const navigate = this.context[key] || this.props.navigate;
return <ComponentClass {...this.props} navigate={navigate} />;
}
}
return Container;
}
// Next step.
// Define a component for your application that owns the navigation state.
class YourApplication extends Component {
static propTypes = {
onExampleExit: PropTypes.func,
};
// This sets up the initial navigation state.
constructor(props, context) {
super(props, context);
// This sets up the initial navigation state.
this.state = createAppNavigationState();
this._navigate = this._navigate.bind(this);
}
render(): React.Element {
// User your own navigator (see next step).
return (
<YourNavigator
appNavigationState={this.state}
navigate={this._navigate}
/>
);
}
// This public method is optional. If exists, the UI explorer will call it
// the "back button" is pressed. Normally this is the cases for Android only.
handleBackAction(): boolean {
return this._navigate({type: 'pop'});
}
// This handles the navigation state changes. You're free and responsible
// to define the API that changes that navigation state. In this exmaple,
// we'd simply use a `updateAppNavigationState` to update the navigation
// state.
_navigate(action: Object): void {
if (action.type === 'exit') {
// Exits the example. `this.props.onExampleExit` is provided
// by the UI Explorer.
this.props.onExampleExit && this.props.onExampleExit();
return;
}
const state = updateAppNavigationState(
this.state,
action,
);
// `updateAppNavigationState` (which uses NavigationStateUtils) gives you
// back the same `state` if nothing has changed. You could use
// that to avoid redundant re-rendering.
if (this.state !== state) {
this.setState(state);
}
}
}
// Next step.
// Define your own controlled navigator.
const YourNavigator = createAppNavigationContainer(class extends Component {
static propTypes = {
appNavigationState: PropTypes.shape({
apple: NavigationPropTypes.navigationState.isRequired,
banana: NavigationPropTypes.navigationState.isRequired,
orange: NavigationPropTypes.navigationState.isRequired,
tabs: NavigationPropTypes.navigationState.isRequired,
}),
navigate: PropTypes.func.isRequired,
};
// This sets up the methods (e.g. Pop, Push) for navigation.
constructor(props: any, context: any) {
super(props, context);
this._back = this._back.bind(this);
this._renderHeader = this._renderHeader.bind(this);
this._renderScene = this._renderScene.bind(this);
}
// Now use the `NavigationCardStack` to render the scenes.
render(): React.Element {
const {appNavigationState} = this.props;
const {tabs} = appNavigationState;
const tabKey = tabs.routes[tabs.index].key;
const scenes = appNavigationState[tabKey];
return (
<View style={styles.navigator}>
<NavigationCardStack
key={'stack_' + tabKey}
onNavigateBack={this._back}
navigationState={scenes}
renderHeader={this._renderHeader}
renderScene={this._renderScene}
style={styles.navigatorCardStack}
/>
<YourTabs
navigationState={tabs}
/>
</View>
);
}
// Render the header.
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
// as type `NavigationSceneRendererProps`.
_renderHeader(sceneProps: Object): React.Element {
return (
<YourHeader
{...sceneProps}
/>
);
}
// Render a scene for route.
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
// as type `NavigationSceneRendererProps`.
_renderScene(sceneProps: Object): React.Element {
return (
<YourScene
{...sceneProps}
/>
);
}
_back() {
this.props.navigate({type: 'pop'});
}
});
// Next step.
// Define your own header.
const YourHeader = createAppNavigationContainer(class extends Component {
static propTypes = {
...NavigationPropTypes.SceneRendererProps,
navigate: PropTypes.func.isRequired,
};
constructor(props: Object, context: any) {
super(props, context);
this._back = this._back.bind(this);
this._renderTitleComponent = this._renderTitleComponent.bind(this);
}
render(): React.Element {
return (
<NavigationHeader
{...this.props}
renderTitleComponent={this._renderTitleComponent}
onNavigateBack={this._back}
/>
);
}
_back(): void {
this.props.navigate({type: 'pop'});
}
_renderTitleComponent(props: Object): React.Element {
return (
<NavigationHeader.Title>
{props.scene.route.key}
</NavigationHeader.Title>
);
}
});
// Next step.
// Define your own scene.
const YourScene = createAppNavigationContainer(class extends Component {
static propTypes = {
...NavigationPropTypes.SceneRendererProps,
navigate: PropTypes.func.isRequired,
};
constructor(props: Object, context: any) {
super(props, context);
this._exit = this._exit.bind(this);
this._popRoute = this._popRoute.bind(this);
this._pushRoute = this._pushRoute.bind(this);
}
render(): React.Element {
return (
<ScrollView>
<NavigationExampleRow
text="Push Route"
onPress={this._pushRoute}
/>
<NavigationExampleRow
text="Pop Route"
onPress={this._popRoute}
/>
<NavigationExampleRow
text="Exit Header + Scenes + Tabs Example"
onPress={this._exit}
/>
</ScrollView>
);
}
_pushRoute(): void {
// Just push a route with a new unique key.
const route = {key: '[' + this.props.scenes.length + ']-' + Date.now()};
this.props.navigate({type: 'push', route});
}
_popRoute(): void {
this.props.navigate({type: 'pop'});
}
_exit(): void {
this.props.navigate({type: 'exit'});
}
});
// Next step.
// Define your own tabs.
const YourTabs = createAppNavigationContainer(class extends Component {
static propTypes = {
navigationState: NavigationPropTypes.navigationState.isRequired,
navigate: PropTypes.func.isRequired,
};
constructor(props: Object, context: any) {
super(props, context);
}
render(): React.Element {
return (
<View style={styles.tabs}>
{this.props.navigationState.routes.map(this._renderTab, this)}
</View>
);
}
_renderTab(route: Object, index: number): React.Element {
return (
<YourTab
key={route.key}
route={route}
selected={this.props.navigationState.index === index}
/>
);
}
});
// Next step.
// Define your own Tab
const YourTab = createAppNavigationContainer(class extends Component {
static propTypes = {
navigate: PropTypes.func.isRequired,
route: NavigationPropTypes.navigationRoute.isRequired,
selected: PropTypes.bool.isRequired,
};
constructor(props: Object, context: any) {
super(props, context);
this._onPress = this._onPress.bind(this);
}
render(): React.Element {
const style = [styles.tabText];
if (this.props.selected) {
style.push(styles.tabSelected);
}
return (
<TouchableOpacity style={styles.tab} onPress={this._onPress}>
<Text style={style}>
{this.props.route.key}
</Text>
</TouchableOpacity>
);
}
_onPress() {
this.props.navigate({type: 'selectTab', tabKey: this.props.route.key});
}
});
const styles = StyleSheet.create({
navigator: {
flex: 1,
},
navigatorCardStack: {
flex: 20,
},
tabs: {
flex: 1,
flexDirection: 'row',
},
tab: {
alignItems: 'center',
backgroundColor: '#fff',
flex: 1,
justifyContent: 'center',
},
tabText: {
color: '#222',
fontWeight: '500',
},
tabSelected: {
color: 'blue',
},
});
module.exports = YourApplication;
@@ -1,198 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @providesModule NavigationCardStack-NoGesture-example
*/
'use strict';
const NavigationExampleRow = require('./NavigationExampleRow');
const React = require('react');
const ReactNative = require('react-native');
/**
* Basic example that shows how to use <NavigationCardStack /> to build
* an app with controlled navigation system but without gestures.
*/
const {
NavigationExperimental,
ScrollView,
StyleSheet,
} = ReactNative;
const {
CardStack: NavigationCardStack,
StateUtils: NavigationStateUtils,
} = NavigationExperimental;
// Step 1:
// Define a component for your application.
class YourApplication extends React.Component {
// This sets up the initial navigation state.
constructor(props, context) {
super(props, context);
this.state = {
// This defines the initial navigation state.
navigationState: {
index: 0, // starts with first route focused.
routes: [{key: 'Welcome'}], // starts with only one route.
},
};
this._exit = this._exit.bind(this);
this._onNavigationChange = this._onNavigationChange.bind(this);
}
// User your own navigator (see Step 2).
render(): React.Element {
return (
<YourNavigator
navigationState={this.state.navigationState}
onNavigationChange={this._onNavigationChange}
onExit={this._exit}
/>
);
}
// This handles the navigation state changes. You're free and responsible
// to define the API that changes that navigation state. In this exmaple,
// we'd simply use a `function(type: string)` to update the navigation state.
_onNavigationChange(type: string): void {
let {navigationState} = this.state;
switch (type) {
case 'push':
// push a new route.
const route = {key: 'route-' + Date.now()};
navigationState = NavigationStateUtils.push(navigationState, route);
break;
case 'pop':
navigationState = NavigationStateUtils.pop(navigationState);
break;
}
// NavigationStateUtils gives you back the same `navigationState` if nothing
// has changed. You could use that to avoid redundant re-rendering.
if (this.state.navigationState !== navigationState) {
this.setState({navigationState});
}
}
// Exits the example. `this.props.onExampleExit` is provided
// by the UI Explorer.
_exit(): void {
this.props.onExampleExit && this.props.onExampleExit();
}
// This public method is optional. If exists, the UI explorer will call it
// the "back button" is pressed. Normally this is the cases for Android only.
handleBackAction(): boolean {
return this._onNavigationChange('pop');
}
}
// Step 2:
// Define your own controlled navigator.
//
// +------------+
// +-+ |
// +-+ | |
// | | | |
// | | | Active |
// | | | Scene |
// | | | |
// +-+ | |
// +-+ |
// +------------+
//
class YourNavigator extends React.Component {
// This sets up the methods (e.g. Pop, Push) for navigation.
constructor(props: any, context: any) {
super(props, context);
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
this._renderScene = this._renderScene.bind(this);
}
// Now use the `NavigationCardStack` to render the scenes.
render(): React.Element {
return (
<NavigationCardStack
onNavigateBack={this._onPopRoute}
navigationState={this.props.navigationState}
renderScene={this._renderScene}
style={styles.navigator}
enableGestures={false}
/>
);
}
// Render a scene for route.
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
// as type `NavigationSceneRendererProps`.
_renderScene(sceneProps: Object): React.Element {
return (
<YourScene
route={sceneProps.scene.route}
onPushRoute={this._onPushRoute}
onPopRoute={this._onPopRoute}
onExit={this.props.onExit}
/>
);
}
}
// Step 3:
// Define your own scene.
class YourScene extends React.Component {
render() {
return (
<ScrollView>
<NavigationExampleRow
text={'route = ' + this.props.route.key}
/>
<NavigationExampleRow
text="Push Route"
onPress={this.props.onPushRoute}
/>
<NavigationExampleRow
text="Pop Route"
onPress={this.props.onPopRoute}
/>
<NavigationExampleRow
text="Exit Card Stack Example"
onPress={this.props.onExit}
/>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
navigator: {
flex: 1,
},
});
module.exports = YourApplication;
@@ -1,196 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* @providesModule NavigationCardStack-example
*/
'use strict';
const NavigationExampleRow = require('./NavigationExampleRow');
const React = require('react');
const ReactNative = require('react-native');
/**
* Basic example that shows how to use <NavigationCardStack /> to build
* an app with controlled navigation system.
*/
const {
NavigationExperimental,
ScrollView,
StyleSheet,
} = ReactNative;
const {
CardStack: NavigationCardStack,
StateUtils: NavigationStateUtils,
} = NavigationExperimental;
// Step 1:
// Define a component for your application.
class YourApplication extends React.Component {
// This sets up the initial navigation state.
constructor(props, context) {
super(props, context);
this.state = {
// This defines the initial navigation state.
navigationState: {
index: 0, // starts with first route focused.
routes: [{key: 'Welcome'}], // starts with only one route.
},
};
this._exit = this._exit.bind(this);
this._onNavigationChange = this._onNavigationChange.bind(this);
}
// User your own navigator (see Step 2).
render(): React.Element {
return (
<YourNavigator
navigationState={this.state.navigationState}
onNavigationChange={this._onNavigationChange}
onExit={this._exit}
/>
);
}
// This handles the navigation state changes. You're free and responsible
// to define the API that changes that navigation state. In this exmaple,
// we'd simply use a `function(type: string)` to update the navigation state.
_onNavigationChange(type: string): void {
let {navigationState} = this.state;
switch (type) {
case 'push':
// push a new route.
const route = {key: 'route-' + Date.now()};
navigationState = NavigationStateUtils.push(navigationState, route);
break;
case 'pop':
navigationState = NavigationStateUtils.pop(navigationState);
break;
}
// NavigationStateUtils gives you back the same `navigationState` if nothing
// has changed. You could use that to avoid redundant re-rendering.
if (this.state.navigationState !== navigationState) {
this.setState({navigationState});
}
}
// Exits the example. `this.props.onExampleExit` is provided
// by the UI Explorer.
_exit(): void {
this.props.onExampleExit && this.props.onExampleExit();
}
// This public method is optional. If exists, the UI explorer will call it
// the "back button" is pressed. Normally this is the cases for Android only.
handleBackAction(): boolean {
return this._onNavigationChange('pop');
}
}
// Step 2:
// Define your own controlled navigator.
//
// +------------+
// +-+ |
// +-+ | |
// | | | |
// | | | Active |
// | | | Scene |
// | | | |
// +-+ | |
// +-+ |
// +------------+
//
class YourNavigator extends React.Component {
// This sets up the methods (e.g. Pop, Push) for navigation.
constructor(props: any, context: any) {
super(props, context);
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
this._renderScene = this._renderScene.bind(this);
}
// Now use the `NavigationCardStack` to render the scenes.
render(): React.Element {
return (
<NavigationCardStack
onNavigateBack={this._onPopRoute}
navigationState={this.props.navigationState}
renderScene={this._renderScene}
style={styles.navigator}
/>
);
}
// Render a scene for route.
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
// as type `NavigationSceneRendererProps`.
_renderScene(sceneProps: Object): React.Element {
return (
<YourScene
route={sceneProps.scene.route}
onPushRoute={this._onPushRoute}
onPopRoute={this._onPopRoute}
onExit={this.props.onExit}
/>
);
}
}
// Step 3:
// Define your own scene.
class YourScene extends React.Component {
render() {
return (
<ScrollView>
<NavigationExampleRow
text={'route = ' + this.props.route.key}
/>
<NavigationExampleRow
text="Push Route"
onPress={this.props.onPushRoute}
/>
<NavigationExampleRow
text="Pop Route"
onPress={this.props.onPopRoute}
/>
<NavigationExampleRow
text="Exit Card Stack Example"
onPress={this.props.onExit}
/>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
navigator: {
flex: 1,
},
});
module.exports = YourApplication;
@@ -1,74 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* @providesModule NavigationExampleRow
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var {
Text,
PixelRatio,
StyleSheet,
View,
TouchableHighlight,
} = ReactNative;
class NavigationExampleRow extends React.Component {
render() {
if (this.props.onPress) {
return (
<TouchableHighlight
style={styles.row}
underlayColor="#D0D0D0"
onPress={this.props.onPress}>
<Text style={styles.buttonText}>
{this.props.text}
</Text>
</TouchableHighlight>
);
}
return (
<View style={styles.row}>
<Text style={styles.rowText}>
{this.props.text}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
row: {
padding: 15,
backgroundColor: 'white',
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
rowText: {
fontSize: 17,
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
});
module.exports = NavigationExampleRow;
@@ -1,153 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* @providesModule NavigationExperimentalExample
*/
'use strict';
const AsyncStorage = require('AsyncStorage');
const NavigationExampleRow = require('./NavigationExampleRow');
const React = require('react');
const ScrollView = require('ScrollView');
const StyleSheet = require('StyleSheet');
const View = require('View');
/*
* Heads up! This file is not the real navigation example- only a utility to switch between them.
*
* To learn how to use the Navigation API, take a look at the following example files:
*/
const EXAMPLES = {
'CardStack + Header + Tabs Example': require('./NavigationCardStack-NavigationHeader-Tabs-example'),
'CardStack Example': require('./NavigationCardStack-example'),
'CardStack Without Gestures Example': require('./NavigationCardStack-NoGesture-example'),
'Transitioner + Animated View Example': require('./NavigationTransitioner-AnimatedView-example'),
'Transitioner + Animated View Pager Example': require('./NavigationTransitioner-AnimatedView-pager-example'),
};
const EXAMPLE_STORAGE_KEY = 'NavigationExperimentalExample';
class NavigationExperimentalExample extends React.Component {
static title = 'Navigation (Experimental)';
static description = 'Upcoming navigation APIs and animated navigation views';
static external = true;
state = {
example: null,
};
componentDidMount() {
AsyncStorage.getItem(EXAMPLE_STORAGE_KEY, (err, example) => {
if (err || !example || !EXAMPLES[example]) {
this.setState({
example: 'menu',
});
return;
}
this.setState({
example,
});
});
}
setExample = (example) => {
this.setState({
example,
});
AsyncStorage.setItem(EXAMPLE_STORAGE_KEY, example);
};
_renderMenu = () => {
let exitRow = null;
if (this.props.onExampleExit) {
exitRow = (
<NavigationExampleRow
text="Exit Navigation Examples"
onPress={this.props.onExampleExit}
/>
);
}
return (
<View style={styles.menu}>
<ScrollView>
{this._renderExampleList()}
{exitRow}
</ScrollView>
</View>
);
};
_renderExampleList = () => {
return Object.keys(EXAMPLES).map(exampleName => (
<NavigationExampleRow
key={exampleName}
text={exampleName}
onPress={() => {
this.setExample(exampleName);
}}
/>
));
};
_exitInnerExample = () => {
this.setExample('menu');
};
handleBackAction = () => {
const wasHandledByExample = (
this.exampleRef &&
this.exampleRef.handleBackAction &&
this.exampleRef.handleBackAction()
);
if (wasHandledByExample) {
return true;
}
if (this.state.example && this.state.example !== 'menu') {
this._exitInnerExample();
return true;
}
return false;
};
render() {
if (this.state.example === 'menu') {
return this._renderMenu();
}
if (EXAMPLES[this.state.example]) {
const Component = EXAMPLES[this.state.example];
return (
<Component
onExampleExit={this._exitInnerExample}
ref={exampleRef => { this.exampleRef = exampleRef; }}
/>
);
}
return null;
}
}
const styles = StyleSheet.create({
menu: {
backgroundColor: '#E9E9EF',
flex: 1,
marginTop: 20,
},
});
module.exports = NavigationExperimentalExample;
@@ -1,256 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @flow
* @providesModule NavigationTransitioner-AnimatedView-example
*/
'use strict';
const NavigationExampleRow = require('./NavigationExampleRow');
const React = require('react');
const ReactNative = require('react-native');
/**
* Basic example that shows how to use <NavigationTransitioner /> and
* <Animated.View /> to build a stack of animated scenes that render the
* navigation state.
*/
import type {
NavigationSceneRendererProps,
NavigationState,
NavigationTransitionProps,
NavigationTransitionSpec,
} from 'NavigationTypeDefinition';
const {
Component,
PropTypes,
} = React;
const {
Animated,
Easing,
NavigationExperimental,
ScrollView,
StyleSheet,
} = ReactNative;
const {
PropTypes: NavigationPropTypes,
StateUtils: NavigationStateUtils,
Transitioner: NavigationTransitioner,
} = NavigationExperimental;
function reducer(state: ?NavigationState, action: any): NavigationState {
if (!state) {
return {
index: 0,
routes: [{key: 'route-1'}],
};
}
switch (action) {
case 'push':
const route = {key: 'route-' + (state.routes.length + 1)};
return NavigationStateUtils.push(state, route);
case 'pop':
return NavigationStateUtils.pop(state);
}
return state;
}
class Example extends Component {
state: NavigationState;
constructor(props: any, context: any) {
super(props, context);
this.state = reducer();
}
render(): React.Element<any> {
return (
<ExampleNavigator
navigationState={this.state}
navigate={action => this._navigate(action)}
/>
);
}
_navigate(action: any): boolean {
if (action === 'exit') {
// Exits the example. `this.props.onExampleExit` is provided
// by the UI Explorer.
this.props.onExampleExit && this.props.onExampleExit();
return false;
}
const state = reducer(this.state, action);
if (state === this.state) {
return false;
}
this.setState(state);
return true;
}
// This public method is optional. If exists, the UI explorer will call it
// the "back button" is pressed. Normally this is the cases for Android only.
handleBackAction(): boolean {
return this._navigate('pop');
}
}
class ExampleNavigator extends Component {
props: {
navigate: Function,
navigationState: NavigationState,
};
static propTypes: {
navigationState: NavigationPropTypes.navigationState.isRequired,
navigate: PropTypes.func.isRequired,
};
render(): React.Element<any> {
return (
<NavigationTransitioner
navigationState={this.props.navigationState}
render={(transitionProps) => this._render(transitionProps)}
configureTransition={this._configureTransition}
/>
);
}
_render(
transitionProps: NavigationTransitionProps,
): Array<React.Element<any>> {
return transitionProps.scenes.map((scene) => {
const sceneProps = {
...transitionProps,
scene,
};
return this._renderScene(sceneProps);
});
}
_renderScene(
sceneProps: NavigationSceneRendererProps,
): React.Element<any> {
return (
<ExampleScene
{...sceneProps}
key={sceneProps.scene.key}
navigate={this.props.navigate}
/>
);
}
_configureTransition(): NavigationTransitionSpec {
const easing: any = Easing.inOut(Easing.ease);
return {
duration: 500,
easing,
};
}
}
class ExampleScene extends Component {
props: NavigationSceneRendererProps & {
navigate: Function,
};
static propTypes = {
...NavigationPropTypes.SceneRendererProps,
navigate: PropTypes.func.isRequired,
};
render(): React.Element<any> {
const {scene, navigate} = this.props;
return (
<Animated.View
style={[styles.scene, this._getAnimatedStyle()]}>
<ScrollView style={styles.scrollView}>
<NavigationExampleRow
text={scene.route.key}
/>
<NavigationExampleRow
text="Push Route"
onPress={() => navigate('push')}
/>
<NavigationExampleRow
text="Pop Route"
onPress={() => navigate('pop')}
/>
<NavigationExampleRow
text="Exit NavigationTransitioner Example"
onPress={() => navigate('exit')}
/>
</ScrollView>
</Animated.View>
);
}
_getAnimatedStyle(): Object {
const {
layout,
position,
scene,
} = this.props;
const {
index,
} = scene;
const inputRange = [index - 1, index, index + 1];
const width = layout.initWidth;
const translateX = position.interpolate({
inputRange,
outputRange: ([width, 0, -10]: Array<number>),
});
return {
transform: [
{ translateX },
],
};
}
}
const styles = StyleSheet.create({
scene: {
backgroundColor: '#E9E9EF',
bottom: 0,
flex: 1,
left: 0,
position: 'absolute',
right: 0,
shadowColor: 'black',
shadowOffset: {width: 0, height: 0},
shadowOpacity: 0.4,
shadowRadius: 10,
top: 0,
},
scrollView: {
flex: 1,
},
});
module.exports = Example;
@@ -1,265 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @flow
* @providesModule NavigationTransitioner-AnimatedView-pager-example
*/
'use strict';
const NavigationExampleRow = require('./NavigationExampleRow');
const React = require('react');
const ReactNative = require('react-native');
/**
* Basic example that shows how to use <NavigationTransitioner /> and
* <Animated.View /> to build a list of animated scenes that render the
* navigation state.
*/
import type {
NavigationSceneRendererProps,
NavigationState,
NavigationTransitionProps,
} from 'NavigationTypeDefinition';
const {
Component,
PropTypes,
} = React;
const {
Animated,
NavigationExperimental,
StyleSheet,
Text,
View,
} = ReactNative;
const {
PropTypes: NavigationPropTypes,
StateUtils: NavigationStateUtils,
Transitioner: NavigationTransitioner,
Card: NavigationCard,
} = NavigationExperimental;
const {
PagerPanResponder: NavigationPagerPanResponder,
PagerStyleInterpolator: NavigationPagerStyleInterpolator,
} = NavigationCard;
function reducer(state: ?NavigationState, action: any): NavigationState {
if (!state) {
return {
index: 0,
routes: [
{key: 'Step 1', color: '#ff0000'},
{key: 'Step 2', color: '#ff7f00'},
{key: 'Step 3', color: '#ffff00'},
{key: 'Step 4', color: '#00ff00'},
{key: 'Step 5', color: '#0000ff'},
{key: 'Step 6', color: '#4b0082'},
{key: 'Step 7', color: '#8f00ff'},
],
};
}
switch (action) {
case 'back':
return NavigationStateUtils.back(state);
case 'forward':
return NavigationStateUtils.forward(state);
}
return state;
}
class Example extends Component {
state: NavigationState;
constructor(props: any, context: any) {
super(props, context);
this.state = reducer();
}
render(): React.Element<any> {
return (
<View style={styles.example}>
<ExampleNavigator
navigationState={this.state}
navigate={action => this._navigate(action)}
/>
<NavigationExampleRow
text="Exit"
onPress={() => this._navigate('exit')}
/>
</View>
);
}
_navigate(action: string): boolean {
if (action === 'exit') {
// Exits the example. `this.props.onExampleExit` is provided
// by the UI Explorer.
this.props.onExampleExit && this.props.onExampleExit();
return false;
}
const state = reducer(this.state, action);
if (state === this.state) {
return false;
}
this.setState(state);
return true;
}
// This public method is optional. If exists, the UI explorer will call it
// the "back button" is pressed. Normally this is the cases for Android only.
handleBackAction(): boolean {
return this._navigate('back');
}
}
class ExampleNavigator extends Component {
_render: Function;
_renderScene: Function;
props: {
navigate: Function,
navigationState: NavigationState,
};
static propTypes: {
navigationState: NavigationPropTypes.navigationState.isRequired,
navigate: PropTypes.func.isRequired,
};
constructor(props, context) {
super(props, context);
this._render = this._render.bind(this);
this._renderScene = this._renderScene.bind(this);
}
render(): React.Element<any> {
return (
<NavigationTransitioner
navigationState={this.props.navigationState}
render={this._render}
/>
);
}
_render(
transitionProps: NavigationTransitionProps,
): React.Element<any> {
const scenes = transitionProps.scenes.map((scene) => {
const sceneProps = {
...transitionProps,
scene,
};
return this._renderScene(sceneProps);
});
return (
<View style={styles.navigator}>
{scenes}
</View>
);
}
_renderScene(
sceneProps: NavigationSceneRendererProps,
): React.Element<any> {
return (
<ExampleScene
{...sceneProps}
key={sceneProps.scene.key + 'scene'}
navigate={this.props.navigate}
/>
);
}
}
class ExampleScene extends Component {
props: NavigationSceneRendererProps & {
navigate: Function,
};
static propTypes = {
...NavigationPropTypes.SceneRendererProps,
navigate: PropTypes.func.isRequired,
};
render(): React.Element<any> {
const {scene, navigate} = this.props;
const panHandlers = NavigationPagerPanResponder.forHorizontal({
...this.props,
onNavigateBack: () => navigate('back'),
onNavigateForward: () => navigate('forward'),
});
const route: any = scene.route;
const style = [
styles.scene,
{backgroundColor: route.color},
NavigationPagerStyleInterpolator.forHorizontal(this.props),
];
return (
<Animated.View
{...panHandlers}
style={style}>
<View style={styles.heading}>
<Text style={styles.headingText}>
{scene.route.key}
</Text>
</View>
</Animated.View>
);
}
}
const styles = StyleSheet.create({
example: {
flex: 1,
},
navigator: {
flex: 1,
},
scene: {
backgroundColor: '#000',
bottom: 0,
flex: 1,
left: 0,
position: 'absolute',
right: 0,
top: 0,
},
heading: {
alignItems : 'center',
flex: 1,
justifyContent: 'center',
},
headingText: {
color: '#222',
fontSize: 24,
fontWeight: 'bold',
},
});
module.exports = Example;
+21 -8
View File
@@ -81,7 +81,9 @@ class SectionListExample extends React.PureComponent {
};
render() {
const filterRegex = new RegExp(String(this.state.filterText), 'i');
const filter = (item) => (filterRegex.test(item.text) || filterRegex.test(item.title));
const filter = (item) => (
filterRegex.test(item.text) || filterRegex.test(item.title)
);
const filteredData = this.state.data.filter(filter);
return (
<UIExplorerPage
@@ -104,8 +106,12 @@ class SectionListExample extends React.PureComponent {
<SectionList
ListHeaderComponent={HeaderComponent}
ListFooterComponent={FooterComponent}
SectionSeparatorComponent={() => <CustomSeparatorComponent text="SECTION SEPARATOR" />}
ItemSeparatorComponent={() => <CustomSeparatorComponent text="ITEM SEPARATOR" />}
SectionSeparatorComponent={() =>
<CustomSeparatorComponent text="SECTION SEPARATOR" />
}
ItemSeparatorComponent={() =>
<CustomSeparatorComponent text="ITEM SEPARATOR" />
}
enableVirtualization={this.state.virtualized}
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
onViewableItemsChanged={this._onViewableItemsChanged}
@@ -117,8 +123,8 @@ class SectionListExample extends React.PureComponent {
{title: 'Item In Header Section', text: 'Section s1', key: '0'},
]},
{key: 's2', data: [
{noImage: true, title: 'First item', text: 'Section s2', key: '0'},
{noImage: true, title: 'Second item', text: 'Section s2', key: '1'},
{noImage: true, title: '1st item', text: 'Section s2', key: '0'},
{noImage: true, title: '2nd item', text: 'Section s2', key: '1'},
]},
{key: 'Filtered Items', data: filteredData},
]}
@@ -127,11 +133,18 @@ class SectionListExample extends React.PureComponent {
</UIExplorerPage>
);
}
_renderItemComponent = ({item}) => <ItemComponent item={item} onPress={this._pressItem} />;
// This is called when items change viewability by scrolling into our out of the viewable area.
_renderItemComponent = ({item}) => (
<ItemComponent item={item} onPress={this._pressItem} />
);
// This is called when items change viewability by scrolling into our out of
// the viewable area.
_onViewableItemsChanged = (info: {
changed: Array<{
key: string, isViewable: boolean, item: {columns: Array<*>}, index: ?number, section?: any
key: string,
isViewable: boolean,
item: {columns: Array<*>},
index: ?number,
section?: any
}>},
) => {
// Impressions can be logged here
@@ -192,10 +192,6 @@ const APIExamples: Array<UIExplorerExample> = [
key: 'NativeAnimationsExample',
module: require('./NativeAnimationsExample'),
},
{
key: 'NavigationExperimentalExample',
module: require('./NavigationExperimental/NavigationExperimentalExample'),
},
{
key: 'NetInfoExample',
module: require('./NetInfoExample'),
@@ -298,11 +298,6 @@ const APIExamples: Array<UIExplorerExample> = [
module: require('./NativeAnimationsExample'),
supportsTVOS: true,
},
{
key: 'NavigationExperimentalExample',
module: require('./NavigationExperimental/NavigationExperimentalExample'),
supportsTVOS: true,
},
{
key: 'NetInfoExample',
module: require('./NetInfoExample'),
+17 -12
View File
@@ -46,19 +46,24 @@ const requireNativeComponent = require('requireNativeComponent');
* view from becoming the responder.
*
*
* `<ScrollView>` vs `<ListView>` - which one to use?
* ScrollView simply renders all its react child components at once. That
* makes it very easy to understand and use.
* On the other hand, this has a performance downside. Imagine you have a very
* long list of items you want to display, worth of couple of your ScrollViews
* heights. Creating JS components and native views upfront for all its items,
* which may not even be shown, will contribute to slow rendering of your
* screen and increased memory usage.
* `<ScrollView>` vs [`<FlatList>`](/react-native/docs/flatlist.html) - which one to use?
*
* This is where ListView comes into play. ListView renders items lazily,
* just when they are about to appear. This laziness comes at cost of a more
* complicated API, which is worth it unless you are rendering a small fixed
* set of items.
* `ScrollView` simply renders all its react child components at once. That
* makes it very easy to understand and use.
*
* On the other hand, this has a performance downside. Imagine you have a very
* long list of items you want to display, maybe several screens worth of
* content. Creating JS components and native views for everythign all at once,
* much of which may not even be shown, will contribute to slow rendering and
* increased memory usage.
*
* This is where `FlatList` comes into play. `FlatList` renders items lazily,
* just when they are about to appear, and removes items that scroll way off
* screen to save memory and processing time.
*
* `FlatList` is also handy if you want to render separators between your items,
* multiple columns, infinite scroll loading, or any number of other features it
* supports out of the box.
*/
const ScrollView = React.createClass({
propTypes: {
@@ -49,19 +49,6 @@ import type {ViewabilityConfig, ViewToken} from 'ViewabilityHelper';
type Item = any;
type renderItemType = (info: {item: Item, index: number}) => ?React.Element<any>;
/**
* Renders a virtual list of items given a data blob and accessor functions. Items that are outside
* the render window (except for the initial items at the top) are 'virtualized' e.g. unmounted or
* never rendered in the first place. This improves performance and saves memory for large data
* sets, but will reset state on items that scroll too far out of the render window.
*
* TODO: Note that LayoutAnimation and sticky section headers both have bugs when used with this and
* are therefor not supported, but new Animated impl might work?
* https://github.com/facebook/react-native/pull/11315
*
* TODO: removeClippedSubviews might not be necessary and may cause bugs?
*
*/
type RequiredProps = {
renderItem: renderItemType,
/**
@@ -76,7 +63,7 @@ type OptionalProps = {
SeparatorComponent?: ?ReactClass<any>,
/**
* `debug` will turn on extra logging and visual overlays to aid with debugging both usage and
* implementation.
* implementation, but with a significant perf hit.
*/
debug?: ?boolean,
/**
@@ -85,13 +72,28 @@ type OptionalProps = {
* this for debugging purposes.
*/
disableVirtualization: boolean,
getItem: (items: any, index: number) => ?Item,
getItemCount: (items: any) => number,
getItemLayout?: (items: any, index: number) =>
/**
* A generic accessor for extracting an item from any sort of data blob.
*/
getItem: (data: any, index: number) => ?Item,
/**
* Determines how many items are in the data blob.
*/
getItemCount: (data: any) => number,
getItemLayout?: (data: any, index: number) =>
{length: number, offset: number, index: number}, // e.g. height, y
horizontal?: ?boolean,
/**
* How many items to render in the initial batch. This should be enough to fill the screen but not
* much more.
*/
initialNumToRender: number,
keyExtractor: (item: Item, index: number) => string,
/**
* The maximum number of items to render in each incremental render batch. The more rendered at
* once, the better the fill rate, but responsiveness my suffer because rendering content may
* interfere with responding to button taps or other interactions.
*/
maxToRenderPerBatch: number,
onEndReached?: ?(info: {distanceFromEnd: number}) => void,
onEndReachedThreshold?: ?number, // units of visible length
@@ -110,15 +112,34 @@ type OptionalProps = {
* Set this true while waiting for new data from a refresh.
*/
refreshing?: ?boolean,
/**
* A native optimization that removes clipped subviews (those outside the parent) from the view
* hierarchy to offload work from the native rendering system. They are still kept around so no
* memory is saved and state is preserved.
*/
removeClippedSubviews?: boolean,
/**
* Render a custom scroll component, e.g. with a differently styled `RefreshControl`.
*/
renderScrollComponent: (props: Object) => React.Element<any>,
shouldItemUpdate: (
props: {item: Item, index: number},
nextProps: {item: Item, index: number}
) => boolean,
/**
* Amount of time between low-pri item render batches, e.g. for rendering items quite a ways off
* screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`.
*/
updateCellsBatchingPeriod: number,
viewabilityConfig?: ViewabilityConfig,
windowSize: number, // units of visible length
/**
* Determines the maximum number of items rendered outside of the visible area, in units of
* visible lengths. So if your list fills the screen, then `windowSize={21}` (the default) will
* render the visible screen area plus up to 10 screens above and 10 below the viewport. Reducing
* this number will reduce memory consumption and may improve performance, but will increase the
* chance that fast scrolling may reveal momentary blank areas of unrendered content.
*/
windowSize: number,
};
export type Props = RequiredProps & OptionalProps;
@@ -148,6 +169,12 @@ type State = {first: number, last: number};
* and we are working on improving it behind the scenes.
* - By default, the list looks for a `key` prop on each item and uses that for the React key.
* Alternatively, you can provide a custom keyExtractor prop.
*
* NOTE: `LayoutAnimation` and sticky section headers both have bugs when used with this and are
* therefore not officially supported yet.
*
* NOTE: `removeClippedSubviews` might not be necessary and may cause bugs. If you see issues with
* content not rendering, try disabling it, and we may change the default there.
*/
class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
props: Props;
@@ -18,6 +18,18 @@ const NavigationPropTypes = require('NavigationPropTypes');
const NavigationStateUtils = require('NavigationStateUtils');
const NavigationTransitioner = require('NavigationTransitioner');
const warning = require('fbjs/lib/warning');
// This warning will only be reached if the user has required the module
warning(
false,
'NavigationExperimental is deprecated and will be removed in a future ' +
'version of React Native. The NavigationExperimental views live on in ' +
'the React-Navigation project, which also makes it easy to declare ' +
'navigation logic for your app. Learn more at https://reactnavigation.org/'
);
const NavigationExperimental = {
// Core
StateUtils: NavigationStateUtils,
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0-master
VERSION_NAME=0.43.0-rc.1
GROUP=com.facebook.react
POM_NAME=ReactNative
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "1000.0.0",
"version": "0.43.0-rc.1",
"description": "A framework for building native apps using React",
"license": "BSD-3-Clause",
"repository": {
@@ -228,4 +228,4 @@
"shelljs": "0.6.0",
"sinon": "^2.0.0-pre.2"
}
}
}