Move ViewPagerAndroid JS code to FB Internal

Summary:
This module is being removed from React Native via Lean Core. This diff moves all the related JS files to FB internal.

Note: I removed two references to previously removed modules from some files in this diff. I hope you don't mind.

Reviewed By: TheSavior

Differential Revision: D15714919

fbshipit-source-id: 88ea406396b31f5c255e06d9c92b67127c81db4a
This commit is contained in:
Christoph Nakazawa 2019-06-11 00:22:11 -07:00 коммит произвёл Facebook Github Bot
Родитель 1f8e08a4fa
Коммит f8a400a53f
6 изменённых файлов: 13 добавлений и 716 удалений

Просмотреть файл

@ -1,112 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const requireNativeComponent = require('../../ReactNative/requireNativeComponent');
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
import type {NativeComponent} from '../../Renderer/shims/ReactNative';
import type {Node} from 'react';
import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
type PageScrollState = 'idle' | 'dragging' | 'settling';
type PageScrollEvent = SyntheticEvent<
$ReadOnly<{|
position: number,
offset: number,
|}>,
>;
type PageScrollStateChangedEvent = SyntheticEvent<
$ReadOnly<{|
pageScrollState: PageScrollState,
|}>,
>;
type PageSelectedEvent = SyntheticEvent<
$ReadOnly<{|
position: number,
|}>,
>;
type NativeProps = $ReadOnly<{|
/**
* Index of initial page that should be selected. Use `setPage` method to
* update the page, and `onPageSelected` to monitor page changes
*/
initialPage?: ?number,
/**
* Executed when transitioning between pages (ether because of animation for
* the requested page change or when user is swiping/dragging between pages)
* The `event.nativeEvent` object for this callback will carry following data:
* - position - index of first page from the left that is currently visible
* - offset - value from range [0,1) describing stage between page transitions.
* Value x means that (1 - x) fraction of the page at "position" index is
* visible, and x fraction of the next page is visible.
*/
onPageScroll?: ?(e: PageScrollEvent) => void,
/**
* Function called when the page scrolling state has changed.
* The page scrolling state can be in 3 states:
* - idle, meaning there is no interaction with the page scroller happening at the time
* - dragging, meaning there is currently an interaction with the page scroller
* - settling, meaning that there was an interaction with the page scroller, and the
* page scroller is now finishing it's closing or opening animation
*/
onPageScrollStateChanged?: ?(e: PageScrollStateChangedEvent) => void,
/**
* This callback will be called once ViewPager finish navigating to selected page
* (when user swipes between pages). The `event.nativeEvent` object passed to this
* callback will have following fields:
* - position - index of page that has been selected
*/
onPageSelected?: ?(e: PageSelectedEvent) => void,
/**
* Blank space to show between pages. This is only visible while scrolling, pages are still
* edge-to-edge.
*/
pageMargin?: ?number,
/**
* Whether enable showing peekFraction or not. If this is true, the preview of
* last and next page will show in current screen. Defaults to false.
*/
peekEnabled?: ?boolean,
/**
* Determines whether the keyboard gets dismissed in response to a drag.
* - 'none' (the default), drags do not dismiss the keyboard.
* - 'on-drag', the keyboard is dismissed when a drag begins.
*/
keyboardDismissMode?: ?('none' | 'on-drag'),
/**
* When false, the content does not scroll.
* The default value is true.
*/
scrollEnabled?: ?boolean,
children?: Node,
style?: ?ViewStyleProp,
|}>;
type ViewPagerNativeType = Class<NativeComponent<NativeProps>>;
module.exports = ((requireNativeComponent(
'AndroidViewPager',
): any): ViewPagerNativeType);

Просмотреть файл

@ -1,277 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
const React = require('react');
const ReactNative = require('../../Renderer/shims/ReactNative');
const UIManager = require('../../ReactNative/UIManager');
const dismissKeyboard = require('../../Utilities/dismissKeyboard');
const NativeAndroidViewPager = require('./AndroidViewPagerNativeComponent');
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
const VIEWPAGER_REF = 'viewPager';
type PageScrollState = 'idle' | 'dragging' | 'settling';
type PageScrollEvent = SyntheticEvent<
$ReadOnly<{|
position: number,
offset: number,
|}>,
>;
type PageScrollStateChangedEvent = SyntheticEvent<
$ReadOnly<{|
pageScrollState: PageScrollState,
|}>,
>;
type PageSelectedEvent = SyntheticEvent<
$ReadOnly<{|
position: number,
|}>,
>;
export type ViewPagerScrollState = $Keys<{
idle: string,
dragging: string,
settling: string,
}>;
type Props = $ReadOnly<{|
/**
* Index of initial page that should be selected. Use `setPage` method to
* update the page, and `onPageSelected` to monitor page changes
*/
initialPage?: ?number,
/**
* Executed when transitioning between pages (ether because of animation for
* the requested page change or when user is swiping/dragging between pages)
* The `event.nativeEvent` object for this callback will carry following data:
* - position - index of first page from the left that is currently visible
* - offset - value from range [0,1) describing stage between page transitions.
* Value x means that (1 - x) fraction of the page at "position" index is
* visible, and x fraction of the next page is visible.
*/
onPageScroll?: ?(e: PageScrollEvent) => void,
/**
* Function called when the page scrolling state has changed.
* The page scrolling state can be in 3 states:
* - idle, meaning there is no interaction with the page scroller happening at the time
* - dragging, meaning there is currently an interaction with the page scroller
* - settling, meaning that there was an interaction with the page scroller, and the
* page scroller is now finishing it's closing or opening animation
*/
onPageScrollStateChanged?: ?(e: PageScrollStateChangedEvent) => void,
/**
* This callback will be called once ViewPager finish navigating to selected page
* (when user swipes between pages). The `event.nativeEvent` object passed to this
* callback will have following fields:
* - position - index of page that has been selected
*/
onPageSelected?: ?(e: PageSelectedEvent) => void,
/**
* Blank space to show between pages. This is only visible while scrolling, pages are still
* edge-to-edge.
*/
pageMargin?: ?number,
/**
* Whether enable showing peekFraction or not. If this is true, the preview of
* last and next page will show in current screen. Defaults to false.
*/
peekEnabled?: ?boolean,
/**
* Determines whether the keyboard gets dismissed in response to a drag.
* - 'none' (the default), drags do not dismiss the keyboard.
* - 'on-drag', the keyboard is dismissed when a drag begins.
*/
keyboardDismissMode?: ?('none' | 'on-drag'),
/**
* When false, the content does not scroll.
* The default value is true.
*/
scrollEnabled?: ?boolean,
children?: React.Node,
style?: ?ViewStyleProp,
|}>;
/**
* Container that allows to flip left and right between child views. Each
* child view of the `ViewPagerAndroid` will be treated as a separate page
* and will be stretched to fill the `ViewPagerAndroid`.
*
* It is important all children are `<View>`s and not composite components.
* You can set style properties like `padding` or `backgroundColor` for each
* child. It is also important that each child have a `key` prop.
*
* Example:
*
* ```
* render: function() {
* return (
* <ViewPagerAndroid
* style={styles.viewPager}
* initialPage={0}>
* <View style={styles.pageStyle} key="1">
* <Text>First page</Text>
* </View>
* <View style={styles.pageStyle} key="2">
* <Text>Second page</Text>
* </View>
* </ViewPagerAndroid>
* );
* }
*
* ...
*
* var styles = {
* ...
* viewPager: {
* flex: 1
* },
* pageStyle: {
* alignItems: 'center',
* padding: 20,
* }
* }
* ```
*/
class ViewPagerAndroid extends React.Component<Props> {
componentDidMount() {
if (this.props.initialPage != null) {
this.setPageWithoutAnimation(this.props.initialPage);
}
}
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
* when making Flow check .android.js files. */
getInnerViewNode = (): ReactComponent => {
return this.refs[VIEWPAGER_REF].getInnerViewNode();
};
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
* when making Flow check .android.js files. */
_childrenWithOverridenStyle = (): Array => {
// Override styles so that each page will fill the parent. Native component
// will handle positioning of elements, so it's not important to offset
// them correctly.
return React.Children.map(this.props.children, function(child) {
if (!child) {
return null;
}
const newProps = {
...child.props,
style: [
child.props.style,
{
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
width: undefined,
height: undefined,
},
],
collapsable: false,
};
if (
child.type &&
child.type.displayName &&
child.type.displayName !== 'RCTView' &&
child.type.displayName !== 'View'
) {
console.warn(
'Each ViewPager child must be a <View>. Was ' +
child.type.displayName,
);
}
return React.createElement(child.type, newProps);
});
};
_onPageScroll = (e: PageScrollEvent) => {
if (this.props.onPageScroll) {
this.props.onPageScroll(e);
}
if (this.props.keyboardDismissMode === 'on-drag') {
dismissKeyboard();
}
};
_onPageScrollStateChanged = (e: PageScrollStateChangedEvent) => {
if (this.props.onPageScrollStateChanged) {
this.props.onPageScrollStateChanged(e);
}
};
_onPageSelected = (e: PageSelectedEvent) => {
if (this.props.onPageSelected) {
this.props.onPageSelected(e);
}
};
/**
* A helper function to scroll to a specific page in the ViewPager.
* The transition between pages will be animated.
*/
setPage = (selectedPage: number) => {
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(this),
UIManager.getViewManagerConfig('AndroidViewPager').Commands.setPage,
[selectedPage],
);
};
/**
* A helper function to scroll to a specific page in the ViewPager.
* The transition between pages will *not* be animated.
*/
setPageWithoutAnimation = (selectedPage: number) => {
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(this),
UIManager.getViewManagerConfig('AndroidViewPager').Commands
.setPageWithoutAnimation,
[selectedPage],
);
};
render() {
return (
<NativeAndroidViewPager
{...this.props}
ref={VIEWPAGER_REF}
style={this.props.style}
onPageScroll={this._onPageScroll}
onPageScrollStateChanged={this._onPageScrollStateChanged}
onPageSelected={this._onPageSelected}
children={this._childrenWithOverridenStyle()}
/>
);
}
}
module.exports = ViewPagerAndroid;

Просмотреть файл

@ -1,12 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
'use strict';
module.exports = require('../UnimplementedViews/UnimplementedView');

Просмотреть файл

@ -136,15 +136,6 @@ module.exports = {
get View() {
return require('../Components/View/View');
},
get ViewPagerAndroid() {
warnOnce(
'viewpager-moved',
'ViewPagerAndroid has been extracted from react-native core and will be removed in a future release. ' +
"It can now be installed and imported from '@react-native-community/viewpager' instead of 'react-native'. " +
'See https://github.com/react-native-community/react-native-viewpager',
);
return require('../Components/ViewPager/ViewPagerAndroid');
},
get VirtualizedList() {
return require('../Lists/VirtualizedList');
},
@ -417,4 +408,17 @@ if (__DEV__) {
);
},
});
// $FlowFixMe This is intentional: Flow will error when attempting to access ViewPagerAndroid.
Object.defineProperty(module.exports, 'ViewPagerAndroid', {
configurable: true,
get() {
invariant(
false,
'ViewPagerAndroid has been removed from React Native. ' +
"It can now be installed and imported from 'react-native-viewpager' instead of 'react-native'. " +
'See https://github.com/react-native-community/react-native-viewpager',
);
},
});
}

Просмотреть файл

@ -1,302 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
'use strict';
const React = require('react');
const {
Image,
StyleSheet,
Text,
TouchableWithoutFeedback,
TouchableOpacity,
View,
ViewPagerAndroid,
} = require('react-native');
import type {ViewPagerScrollState} from '../../../../Libraries/Components/ViewPager/ViewPagerAndroid';
const PAGES = 5;
const BGCOLOR = ['#fdc08e', '#fff6b9', '#99d1b7', '#dde5fe', '#f79273'];
const IMAGE_URIS = [
'https://apod.nasa.gov/apod/image/1410/20141008tleBaldridge001h990.jpg',
'https://apod.nasa.gov/apod/image/1409/volcanicpillar_vetter_960.jpg',
'https://apod.nasa.gov/apod/image/1409/m27_snyder_960.jpg',
'https://apod.nasa.gov/apod/image/1409/PupAmulti_rot0.jpg',
'https://apod.nasa.gov/apod/image/1510/lunareclipse_27Sep_beletskycrop4.jpg',
];
type Props = $ReadOnly<{||}>;
type State = {|likes: number|};
class LikeCount extends React.Component<Props, State> {
state = {
likes: 7,
};
onClick = () => {
this.setState({likes: this.state.likes + 1});
};
render() {
const thumbsUp = '\uD83D\uDC4D';
return (
<View style={styles.likeContainer}>
<TouchableOpacity onPress={this.onClick} style={styles.likeButton}>
<Text style={styles.likesText}>{thumbsUp + ' Like'}</Text>
</TouchableOpacity>
<Text style={styles.likesText}>{this.state.likes + ' likes'}</Text>
</View>
);
}
}
class Button extends React.Component {
_handlePress = () => {
if (this.props.enabled && this.props.onPress) {
this.props.onPress();
}
};
render() {
return (
<TouchableWithoutFeedback onPress={this._handlePress}>
<View
style={[
styles.button,
this.props.enabled ? {} : styles.buttonDisabled,
]}>
<Text style={styles.buttonText}>{this.props.text}</Text>
</View>
</TouchableWithoutFeedback>
);
}
}
class ProgressBar extends React.Component {
render() {
const fractionalPosition =
this.props.progress.position + this.props.progress.offset;
const progressBarSize =
(fractionalPosition / (PAGES - 1)) * this.props.size;
return (
<View style={[styles.progressBarContainer, {width: this.props.size}]}>
<View style={[styles.progressBar, {width: progressBarSize}]} />
</View>
);
}
}
class ViewPagerAndroidExample extends React.Component {
state = {
page: 0,
animationsAreEnabled: true,
scrollEnabled: true,
progress: {
position: 0,
offset: 0,
},
};
onPageSelected = e => {
this.setState({page: e.nativeEvent.position});
};
onPageScroll = e => {
this.setState({progress: e.nativeEvent});
};
onPageScrollStateChanged = (state: ViewPagerScrollState) => {
this.setState({scrollState: state});
};
move = delta => {
const page = this.state.page + delta;
this.go(page);
};
go = page => {
if (this.state.animationsAreEnabled) {
this.viewPager.setPage(page);
} else {
this.viewPager.setPageWithoutAnimation(page);
}
this.setState({page});
};
render() {
const pages = [];
for (let i = 0; i < PAGES; i++) {
const pageStyle = {
backgroundColor: BGCOLOR[i % BGCOLOR.length],
alignItems: 'center',
padding: 20,
};
pages.push(
<View key={i} style={pageStyle} collapsable={false}>
<Image
style={styles.image}
source={{uri: IMAGE_URIS[i % BGCOLOR.length]}}
/>
<LikeCount />
</View>,
);
}
const {page, animationsAreEnabled} = this.state;
return (
<View style={styles.container}>
<ViewPagerAndroid
style={styles.viewPager}
initialPage={0}
scrollEnabled={this.state.scrollEnabled}
onPageScroll={this.onPageScroll}
onPageSelected={this.onPageSelected}
onPageScrollStateChanged={this.onPageScrollStateChanged}
pageMargin={10}
ref={viewPager => {
this.viewPager = viewPager;
}}>
{pages}
</ViewPagerAndroid>
<View style={styles.buttons}>
<Button
enabled={true}
text={
this.state.scrollEnabled ? 'Scroll Enabled' : 'Scroll Disabled'
}
onPress={() =>
this.setState({scrollEnabled: !this.state.scrollEnabled})
}
/>
</View>
<View style={styles.buttons}>
{animationsAreEnabled ? (
<Button
text="Turn off animations"
enabled={true}
onPress={() => this.setState({animationsAreEnabled: false})}
/>
) : (
<Button
text="Turn animations back on"
enabled={true}
onPress={() => this.setState({animationsAreEnabled: true})}
/>
)}
<Text style={styles.scrollStateText}>
ScrollState[ {this.state.scrollState} ]
</Text>
</View>
<View style={styles.buttons}>
<Button text="Start" enabled={page > 0} onPress={() => this.go(0)} />
<Button
text="Prev"
enabled={page > 0}
onPress={() => this.move(-1)}
/>
<Text style={styles.buttonText}>
Page {page + 1} / {PAGES}
</Text>
<ProgressBar size={100} progress={this.state.progress} />
<Button
text="Next"
enabled={page < PAGES - 1}
onPress={() => this.move(1)}
/>
<Button
text="Last"
enabled={page < PAGES - 1}
onPress={() => this.go(PAGES - 1)}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
buttons: {
flexDirection: 'row',
height: 30,
backgroundColor: 'black',
alignItems: 'center',
justifyContent: 'space-between',
},
button: {
flex: 1,
width: 0,
margin: 5,
borderColor: 'gray',
borderWidth: 1,
backgroundColor: 'gray',
},
buttonDisabled: {
backgroundColor: 'black',
opacity: 0.5,
},
buttonText: {
color: 'white',
},
scrollStateText: {
color: '#99d1b7',
},
container: {
flex: 1,
backgroundColor: 'white',
},
image: {
width: 300,
height: 200,
padding: 20,
},
likeButton: {
backgroundColor: 'rgba(0, 0, 0, 0.1)',
borderColor: '#333333',
borderWidth: 1,
borderRadius: 5,
flex: 1,
margin: 8,
padding: 8,
},
likeContainer: {
flexDirection: 'row',
},
likesText: {
flex: 1,
fontSize: 18,
alignSelf: 'center',
},
progressBarContainer: {
height: 10,
margin: 10,
borderColor: '#eeeeee',
borderWidth: 2,
},
progressBar: {
alignSelf: 'flex-start',
flex: 1,
backgroundColor: '#eeeeee',
},
viewPager: {
flex: 1,
},
});
exports.title = '<ViewPagerAndroid>';
exports.description =
'Container that allows to flip left and right between child views.';
exports.examples = [
{
title: 'Basic pager',
render(): React.Element<typeof ViewPagerAndroidExample> {
return <ViewPagerAndroidExample />;
},
},
];

Просмотреть файл

@ -101,10 +101,6 @@ const ComponentExamples: Array<RNTesterExample> = [
key: 'ViewExample',
module: require('../examples/View/ViewExample'),
},
{
key: 'ViewPagerAndroidExample',
module: require('../examples/ViewPagerAndroid/ViewPagerAndroidExample'),
},
];
const APIExamples: Array<RNTesterExample> = [