From 9ca7989f60cc8137705effeaad0f128fa73ed2e4 Mon Sep 17 00:00:00 2001 From: Christoph Nakazawa Date: Wed, 27 Mar 2019 16:19:59 -0700 Subject: [PATCH] Remove SwipeableFlatList from RN Summary: According to TheSavior this was an experimental module that "accidentally" got added to RN open source. In fact, we only use it in two places internally. This diff moves these files to FB internal and removes them from RN completely. I skipped the deprecation message because it was always an experimental feature and I don't expect anyone out there using it. Reviewed By: TheSavior Differential Revision: D14631749 fbshipit-source-id: 87878fcbb901e1e7fa4a3ff3205e09886ff3ed43 --- .../SwipeableRow/SwipeableFlatList.js | 172 -------- .../SwipeableQuickActionButton.js | 79 ---- .../SwipeableRow/SwipeableQuickActions.js | 69 ---- .../Experimental/SwipeableRow/SwipeableRow.js | 384 ------------------ .../react-native-implementation.js | 3 - RNTester/js/RNTesterList.android.js | 4 - RNTester/js/RNTesterList.ios.js | 5 - RNTester/js/SwipeableFlatListExample.js | 150 ------- 8 files changed, 866 deletions(-) delete mode 100644 Libraries/Experimental/SwipeableRow/SwipeableFlatList.js delete mode 100644 Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js delete mode 100644 Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js delete mode 100644 Libraries/Experimental/SwipeableRow/SwipeableRow.js delete mode 100644 RNTester/js/SwipeableFlatListExample.js diff --git a/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js b/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js deleted file mode 100644 index 5bbe37f0a0b..00000000000 --- a/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js +++ /dev/null @@ -1,172 +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. - * - * @flow - * @format - */ -'use strict'; - -import type {Props as FlatListProps} from 'FlatList'; -import type {renderItemType} from 'VirtualizedList'; - -const React = require('React'); -const SwipeableRow = require('SwipeableRow'); -const FlatList = require('FlatList'); - -// TODO: Make this $ReadOnly and Exact. Will require doing the same to the props in -// Libraries/Lists/* -type SwipableListProps = { - /** - * To alert the user that swiping is possible, the first row can bounce - * on component mount. - */ - bounceFirstRowOnMount: boolean, - - /** - * Maximum distance to open to after a swipe - */ - maxSwipeDistance: number | (Object => number), - - /** - * Callback method to render the view that will be unveiled on swipe - */ - renderQuickActions: renderItemType, -}; - -type Props = SwipableListProps & FlatListProps; - -type State = {| - openRowKey: ?string, -|}; - -/** - * A container component that renders multiple SwipeableRow's in a FlatList - * implementation. This is designed to be a drop-in replacement for the - * standard React Native `FlatList`, so use it as if it were a FlatList, but - * with extra props. - * - * SwipeableRow can be used independently of this component, but the main - * benefits of using this component are: - * - * - It ensures that at most 1 row is swiped open (auto closes others) - * - It can bounce the 1st row of the list so users know it's swipeable - * - Increase performance on iOS by locking list swiping when row swiping is occurring - * - More to come - */ - -class SwipeableFlatList extends React.Component, State> { - _flatListRef: ?FlatList = null; - _shouldBounceFirstRowOnMount: boolean = false; - - static defaultProps = { - ...FlatList.defaultProps, - bounceFirstRowOnMount: true, - renderQuickActions: () => null, - }; - - constructor(props: Props, context: any): void { - super(props, context); - this.state = { - openRowKey: null, - }; - - this._shouldBounceFirstRowOnMount = this.props.bounceFirstRowOnMount; - } - - render(): React.Node { - return ( - { - this._flatListRef = ref; - }} - onScroll={this._onScroll} - renderItem={this._renderItem} - extraData={this.state} - /> - ); - } - - _onScroll = (e): void => { - // Close any opens rows on ListView scroll - if (this.state.openRowKey) { - this.setState({ - openRowKey: null, - }); - } - - this.props.onScroll && this.props.onScroll(e); - }; - - _renderItem = (info: Object): ?React.Element => { - const slideoutView = this.props.renderQuickActions(info); - const key = this.props.keyExtractor(info.item, info.index); - - // If renderQuickActions is unspecified or returns falsey, don't allow swipe - if (!slideoutView) { - return this.props.renderItem(info); - } - - let shouldBounceOnMount = false; - if (this._shouldBounceFirstRowOnMount) { - this._shouldBounceFirstRowOnMount = false; - shouldBounceOnMount = true; - } - - return ( - this._onOpen(key)} - onClose={() => this._onClose(key)} - shouldBounceOnMount={shouldBounceOnMount} - onSwipeEnd={this._setListViewScrollable} - onSwipeStart={this._setListViewNotScrollable}> - {this.props.renderItem(info)} - - ); - }; - - // This enables rows having variable width slideoutView. - _getMaxSwipeDistance(info: Object): number { - if (typeof this.props.maxSwipeDistance === 'function') { - return this.props.maxSwipeDistance(info); - } - - return this.props.maxSwipeDistance; - } - - _setListViewScrollableTo(value: boolean) { - if (this._flatListRef) { - this._flatListRef.setNativeProps({ - scrollEnabled: value, - }); - } - } - - _setListViewScrollable = () => { - this._setListViewScrollableTo(true); - }; - - _setListViewNotScrollable = () => { - this._setListViewScrollableTo(false); - }; - - _onOpen(key: any): void { - this.setState({ - openRowKey: key, - }); - } - - _onClose(key: any): void { - this.setState({ - openRowKey: null, - }); - } -} - -module.exports = SwipeableFlatList; diff --git a/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js b/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js deleted file mode 100644 index 0ad96e4d226..00000000000 --- a/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js +++ /dev/null @@ -1,79 +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 DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); -const Image = require('Image'); -const React = require('React'); -const Text = require('Text'); -const TouchableHighlight = require('TouchableHighlight'); -const View = require('View'); - -import type {ImageSource} from 'ImageSource'; - -/** - * Standard set of quick action buttons that can, if the user chooses, be used - * with SwipeableListView. Each button takes an image and text with optional - * formatting. - */ -class SwipeableQuickActionButton extends React.Component<{ - accessibilityLabel?: string, - imageSource?: ?(ImageSource | number), - /* $FlowFixMe(>=0.82.0 site=react_native_fb) This comment suppresses an error - * found when Flow v0.82 was deployed. To see the error delete this comment - * and run Flow. */ - imageStyle?: ?DeprecatedViewPropTypes.style, - mainView?: ?React.Node, - onPress?: Function, - /* $FlowFixMe(>=0.82.0 site=react_native_fb) This comment suppresses an error - * found when Flow v0.82 was deployed. To see the error delete this comment - * and run Flow. */ - style?: ?DeprecatedViewPropTypes.style, - /* $FlowFixMe(>=0.82.0 site=react_native_fb) This comment suppresses an error - * found when Flow v0.82 was deployed. To see the error delete this comment - * and run Flow. */ - containerStyle?: ?DeprecatedViewPropTypes.style, - testID?: string, - text?: ?(string | Object | Array), - /* $FlowFixMe(>=0.82.0 site=react_native_fb) This comment suppresses an error - * found when Flow v0.82 was deployed. To see the error delete this comment - * and run Flow. */ - textStyle?: ?DeprecatedViewPropTypes.style, -}> { - render(): React.Node { - if (!this.props.imageSource && !this.props.text && !this.props.mainView) { - return null; - } - const mainView = this.props.mainView ? ( - this.props.mainView - ) : ( - - - {this.props.text} - - ); - return ( - - {mainView} - - ); - } -} - -module.exports = SwipeableQuickActionButton; diff --git a/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js b/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js deleted file mode 100644 index c97f77648af..00000000000 --- a/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js +++ /dev/null @@ -1,69 +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 StyleSheet = require('StyleSheet'); -const View = require('View'); - -import type {ViewStyleProp} from 'StyleSheet'; - -type Props = $ReadOnly<{| - style?: ?ViewStyleProp, - children: React.Node, -|}>; - -/** - * A thin wrapper around standard quick action buttons that can, if the user - * chooses, be used with SwipeableListView. Sample usage is as follows, in the - * renderQuickActions callback: - * - * - * - * - * - */ -class SwipeableQuickActions extends React.Component { - render(): React.Node { - const children = this.props.children; - let buttons = []; - - // Multiple children - if (children instanceof Array) { - for (let i = 0; i < children.length; i++) { - buttons.push(children[i]); - - if (i < children.length - 1) { - // Not last button - buttons.push(); - } - } - } else { - // 1 child - buttons = children; - } - - return {buttons}; - } -} - -const styles = StyleSheet.create({ - background: { - flex: 1, - flexDirection: 'row', - justifyContent: 'flex-end', - }, - divider: { - width: 4, - }, -}); - -module.exports = SwipeableQuickActions; diff --git a/Libraries/Experimental/SwipeableRow/SwipeableRow.js b/Libraries/Experimental/SwipeableRow/SwipeableRow.js deleted file mode 100644 index de707a3549d..00000000000 --- a/Libraries/Experimental/SwipeableRow/SwipeableRow.js +++ /dev/null @@ -1,384 +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 Animated = require('Animated'); -const I18nManager = require('I18nManager'); -const PanResponder = require('PanResponder'); -const React = require('React'); -const StyleSheet = require('StyleSheet'); -const View = require('View'); - -import type {LayoutEvent, PressEvent} from 'CoreEventTypes'; -import type {GestureState} from 'PanResponder'; - -const IS_RTL = I18nManager.isRTL; - -// NOTE: Eventually convert these consts to an input object of configurations - -// Position of the left of the swipable item when closed -const CLOSED_LEFT_POSITION = 0; -// Minimum swipe distance before we recognize it as such -const HORIZONTAL_SWIPE_DISTANCE_THRESHOLD = 10; -// Minimum swipe speed before we fully animate the user's action (open/close) -const HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD = 0.3; -// Factor to divide by to get slow speed; i.e. 4 means 1/4 of full speed -const SLOW_SPEED_SWIPE_FACTOR = 4; -// Time, in milliseconds, of how long the animated swipe should be -const SWIPE_DURATION = 300; - -/** - * On SwipeableListView mount, the 1st item will bounce to show users it's - * possible to swipe - */ -const ON_MOUNT_BOUNCE_DELAY = 700; -const ON_MOUNT_BOUNCE_DURATION = 400; - -// Distance left of closed position to bounce back when right-swiping from closed -const RIGHT_SWIPE_BOUNCE_BACK_DISTANCE = 30; -const RIGHT_SWIPE_BOUNCE_BACK_DURATION = 300; -/** - * Max distance of right swipe to allow (right swipes do functionally nothing). - * Must be multiplied by SLOW_SPEED_SWIPE_FACTOR because gestureState.dx tracks - * how far the finger swipes, and not the actual animation distance. - */ -const RIGHT_SWIPE_THRESHOLD = 30 * SLOW_SPEED_SWIPE_FACTOR; -const DEFAULT_SWIPE_THRESHOLD = 30; - -const emptyFunction = () => {}; - -type Props = $ReadOnly<{| - children?: ?React.Node, - isOpen?: ?boolean, - maxSwipeDistance?: ?number, - onClose?: ?() => void, - onOpen?: ?() => void, - onSwipeEnd?: ?() => void, - onSwipeStart?: ?() => void, - preventSwipeRight?: ?boolean, - shouldBounceOnMount?: ?boolean, - slideoutView?: ?React.Node, - swipeThreshold?: ?number, -|}>; - -type State = { - currentLeft: Animated.Value, - isSwipeableViewRendered: boolean, - rowHeight: ?number, -}; - -/** - * Creates a swipable row that allows taps on the main item and a custom View - * on the item hidden behind the row. Typically this should be used in - * conjunction with SwipeableListView for additional functionality, but can be - * used in a normal ListView. See the renderRow for SwipeableListView to see how - * to use this component separately. - */ -class SwipeableRow extends React.Component { - _handleMoveShouldSetPanResponderCapture = ( - event: PressEvent, - gestureState: GestureState, - ): boolean => { - // Decides whether a swipe is responded to by this component or its child - return gestureState.dy < 10 && this._isValidSwipe(gestureState); - }; - - _handlePanResponderGrant = ( - event: PressEvent, - gestureState: GestureState, - ): void => {}; - - _handlePanResponderMove = ( - event: PressEvent, - gestureState: GestureState, - ): void => { - if (this._isSwipingExcessivelyRightFromClosedPosition(gestureState)) { - return; - } - - this.props.onSwipeStart && this.props.onSwipeStart(); - - if (this._isSwipingRightFromClosed(gestureState)) { - this._swipeSlowSpeed(gestureState); - } else { - this._swipeFullSpeed(gestureState); - } - }; - - _onPanResponderTerminationRequest = ( - event: PressEvent, - gestureState: GestureState, - ): boolean => { - return false; - }; - - _handlePanResponderEnd = ( - event: PressEvent, - gestureState: GestureState, - ): void => { - const horizontalDistance = IS_RTL ? -gestureState.dx : gestureState.dx; - if (this._isSwipingRightFromClosed(gestureState)) { - this.props.onOpen && this.props.onOpen(); - this._animateBounceBack(RIGHT_SWIPE_BOUNCE_BACK_DURATION); - } else if (this._shouldAnimateRemainder(gestureState)) { - if (horizontalDistance < 0) { - // Swiped left - this.props.onOpen && this.props.onOpen(); - this._animateToOpenPositionWith(gestureState.vx, horizontalDistance); - } else { - // Swiped right - this.props.onClose && this.props.onClose(); - this._animateToClosedPosition(); - } - } else { - if (this._previousLeft === CLOSED_LEFT_POSITION) { - this._animateToClosedPosition(); - } else { - this._animateToOpenPosition(); - } - } - - this.props.onSwipeEnd && this.props.onSwipeEnd(); - }; - - _panResponder = PanResponder.create({ - onMoveShouldSetPanResponderCapture: this - ._handleMoveShouldSetPanResponderCapture, - onPanResponderGrant: this._handlePanResponderGrant, - onPanResponderMove: this._handlePanResponderMove, - onPanResponderRelease: this._handlePanResponderEnd, - onPanResponderTerminationRequest: this._onPanResponderTerminationRequest, - onPanResponderTerminate: this._handlePanResponderEnd, - onShouldBlockNativeResponder: (event, gestureState) => false, - }); - - _previousLeft = CLOSED_LEFT_POSITION; - _timeoutID: ?TimeoutID = null; - - state = { - currentLeft: new Animated.Value(this._previousLeft), - /** - * In order to render component A beneath component B, A must be rendered - * before B. However, this will cause "flickering", aka we see A briefly - * then B. To counter this, _isSwipeableViewRendered flag is used to set - * component A to be transparent until component B is loaded. - */ - isSwipeableViewRendered: false, - rowHeight: null, - }; - - componentDidMount(): void { - if (this.props.shouldBounceOnMount) { - /** - * Do the on mount bounce after a delay because if we animate when other - * components are loading, the animation will be laggy - */ - this._timeoutID = setTimeout(() => { - this._animateBounceBack(ON_MOUNT_BOUNCE_DURATION); - }, ON_MOUNT_BOUNCE_DELAY); - } - } - - UNSAFE_componentWillReceiveProps(nextProps: $Shape): void { - /** - * We do not need an "animateOpen(noCallback)" because this animation is - * handled internally by this component. - */ - const isOpen = this.props.isOpen ?? false; - const nextIsOpen = nextProps.isOpen ?? false; - - if (isOpen && !nextIsOpen) { - this._animateToClosedPosition(); - } - } - - componentWillUnmount() { - if (this._timeoutID != null) { - clearTimeout(this._timeoutID); - } - } - - render(): React.Element { - // The view hidden behind the main view - let slideOutView; - if (this.state.isSwipeableViewRendered && this.state.rowHeight) { - slideOutView = ( - - {this.props.slideoutView} - - ); - } - - // The swipeable item - const swipeableView = ( - - {this.props.children} - - ); - - return ( - - {slideOutView} - {swipeableView} - - ); - } - - close(): void { - this.props.onClose && this.props.onClose(); - this._animateToClosedPosition(); - } - - _onSwipeableViewLayout = (event: LayoutEvent): void => { - this.setState({ - isSwipeableViewRendered: true, - rowHeight: event.nativeEvent.layout.height, - }); - }; - - _isSwipingRightFromClosed(gestureState: GestureState): boolean { - const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx; - return this._previousLeft === CLOSED_LEFT_POSITION && gestureStateDx > 0; - } - - _swipeFullSpeed(gestureState: GestureState): void { - this.state.currentLeft.setValue(this._previousLeft + gestureState.dx); - } - - _swipeSlowSpeed(gestureState: GestureState): void { - this.state.currentLeft.setValue( - this._previousLeft + gestureState.dx / SLOW_SPEED_SWIPE_FACTOR, - ); - } - - _isSwipingExcessivelyRightFromClosedPosition( - gestureState: GestureState, - ): boolean { - /** - * We want to allow a BIT of right swipe, to allow users to know that - * swiping is available, but swiping right does not do anything - * functionally. - */ - const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx; - return ( - this._isSwipingRightFromClosed(gestureState) && - gestureStateDx > RIGHT_SWIPE_THRESHOLD - ); - } - - _animateTo( - toValue: number, - duration: number = SWIPE_DURATION, - callback: Function = emptyFunction, - ): void { - Animated.timing(this.state.currentLeft, { - duration, - toValue, - useNativeDriver: true, - }).start(() => { - this._previousLeft = toValue; - callback(); - }); - } - - _animateToOpenPosition(): void { - const maxSwipeDistance = this.props.maxSwipeDistance ?? 0; - const directionAwareMaxSwipeDistance = IS_RTL - ? -maxSwipeDistance - : maxSwipeDistance; - this._animateTo(-directionAwareMaxSwipeDistance); - } - - _animateToOpenPositionWith(speed: number, distMoved: number): void { - /** - * Ensure the speed is at least the set speed threshold to prevent a slow - * swiping animation - */ - speed = - speed > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD - ? speed - : HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD; - const maxSwipeDistance = this.props.maxSwipeDistance ?? 0; - /** - * Calculate the duration the row should take to swipe the remaining distance - * at the same speed the user swiped (or the speed threshold) - */ - const duration = Math.abs((maxSwipeDistance - Math.abs(distMoved)) / speed); - const directionAwareMaxSwipeDistance = IS_RTL - ? -maxSwipeDistance - : maxSwipeDistance; - this._animateTo(-directionAwareMaxSwipeDistance, duration); - } - - _animateToClosedPosition(duration: number = SWIPE_DURATION): void { - this._animateTo(CLOSED_LEFT_POSITION, duration); - } - - _animateToClosedPositionDuringBounce = (): void => { - this._animateToClosedPosition(RIGHT_SWIPE_BOUNCE_BACK_DURATION); - }; - - _animateBounceBack(duration: number): void { - /** - * When swiping right, we want to bounce back past closed position on release - * so users know they should swipe right to get content. - */ - const swipeBounceBackDistance = IS_RTL - ? -RIGHT_SWIPE_BOUNCE_BACK_DISTANCE - : RIGHT_SWIPE_BOUNCE_BACK_DISTANCE; - this._animateTo( - -swipeBounceBackDistance, - duration, - this._animateToClosedPositionDuringBounce, - ); - } - - // Ignore swipes due to user's finger moving slightly when tapping - _isValidSwipe(gestureState: GestureState): boolean { - const preventSwipeRight = this.props.preventSwipeRight ?? false; - if ( - preventSwipeRight && - this._previousLeft === CLOSED_LEFT_POSITION && - gestureState.dx > 0 - ) { - return false; - } - - return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD; - } - - _shouldAnimateRemainder(gestureState: GestureState): boolean { - /** - * If user has swiped past a certain distance, animate the rest of the way - * if they let go - */ - const swipeThreshold = this.props.swipeThreshold ?? DEFAULT_SWIPE_THRESHOLD; - return ( - Math.abs(gestureState.dx) > swipeThreshold || - gestureState.vx > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD - ); - } -} - -const styles = StyleSheet.create({ - slideOutContainer: { - bottom: 0, - left: 0, - position: 'absolute', - right: 0, - top: 0, - }, -}); - -module.exports = SwipeableRow; diff --git a/Libraries/react-native/react-native-implementation.js b/Libraries/react-native/react-native-implementation.js index 0fba5df8d6b..deee26c0d53 100644 --- a/Libraries/react-native/react-native-implementation.js +++ b/Libraries/react-native/react-native-implementation.js @@ -137,9 +137,6 @@ module.exports = { ); return require('StatusBar'); }, - get SwipeableFlatList() { - return require('SwipeableFlatList'); - }, get Text() { return require('Text'); }, diff --git a/RNTester/js/RNTesterList.android.js b/RNTester/js/RNTesterList.android.js index d4bf68db97d..9946ad0df62 100644 --- a/RNTester/js/RNTesterList.android.js +++ b/RNTester/js/RNTesterList.android.js @@ -71,10 +71,6 @@ const ComponentExamples: Array = [ key: 'StatusBarExample', module: require('./StatusBarExample'), }, - { - key: 'SwipeableFlatListExample', - module: require('./SwipeableFlatListExample'), - }, { key: 'SwitchExample', module: require('./SwitchExample'), diff --git a/RNTester/js/RNTesterList.ios.js b/RNTester/js/RNTesterList.ios.js index c5d6c2b0122..0a5557727c5 100644 --- a/RNTester/js/RNTesterList.ios.js +++ b/RNTester/js/RNTesterList.ios.js @@ -128,11 +128,6 @@ const ComponentExamples: Array = [ module: require('./StatusBarExample'), supportsTVOS: false, }, - { - key: 'SwipeableFlatListExample', - module: require('./SwipeableFlatListExample'), - supportsTVOS: false, - }, { key: 'SwitchExample', module: require('./SwitchExample'), diff --git a/RNTester/js/SwipeableFlatListExample.js b/RNTester/js/SwipeableFlatListExample.js deleted file mode 100644 index d79336cc30a..00000000000 --- a/RNTester/js/SwipeableFlatListExample.js +++ /dev/null @@ -1,150 +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. - * - * @flow - * @format - */ -'use strict'; - -const React = require('react'); -const ReactNative = require('react-native'); -const { - Image, - SwipeableFlatList, - TouchableHighlight, - StyleSheet, - Text, - View, - Alert, -} = ReactNative; - -const RNTesterPage = require('./RNTesterPage'); - -import type {RNTesterProps} from 'RNTesterTypes'; - -const data = [ - { - key: 'like', - icon: require('./Thumbnails/like.png'), - data: 'Like!', - }, - { - key: 'heart', - icon: require('./Thumbnails/heart.png'), - data: 'Heart!', - }, - { - key: 'party', - icon: require('./Thumbnails/party.png'), - data: 'Party!', - }, -]; - -class SwipeableFlatListExample extends React.Component { - render() { - return ( - '} - noSpacer={true} - noScroll={true}> - - - ); - } - - _renderItem({item}): ?React.Element { - return ( - - - - {item.data} - - - ); - } - - _renderQuickActions({item}: Object): ?React.Element { - return ( - - { - Alert.alert( - 'Tips', - 'You could do something with this edit action!', - ); - }}> - Edit - - { - Alert.alert( - 'Tips', - 'You could do something with this remove action!', - ); - }}> - Remove - - - ); - } -} - -const styles = StyleSheet.create({ - row: { - flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center', - padding: 10, - backgroundColor: '#F6F6F6', - }, - rowIcon: { - width: 64, - height: 64, - marginRight: 20, - }, - rowData: { - flex: 1, - }, - rowDataText: { - fontSize: 24, - }, - actionsContainer: { - flex: 1, - flexDirection: 'row', - justifyContent: 'flex-end', - alignItems: 'center', - }, - actionButton: { - padding: 10, - width: 80, - backgroundColor: '#999999', - }, - actionButtonDestructive: { - backgroundColor: '#FF0000', - }, - actionButtonText: { - textAlign: 'center', - }, -}); - -exports.title = ''; -exports.description = 'Performant, scrollable, swipeable list of data.'; -exports.examples = [ - { - title: 'Simple swipable list', - render: function(): React.Element { - return ; - }, - }, -];