From bbf571cf1105151aced775127c40d976b3b1ab6f Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Thu, 18 Mar 2021 11:33:32 -0700 Subject: [PATCH] Adapt SectionListExamples Summary: # Changelog: [General][Added] - Added more RNTester examples for FlatList as similar to SectionListExamples. Reviewed By: kacieb Differential Revision: D27104601 fbshipit-source-id: 0a2cb24382d42956bacf455fd0a699adb61c7c83 --- .../FlatList/FlatList-onEndReached.js | 28 ++ .../FlatList-onViewableItemsChanged.js | 38 +++ .../FlatList/FlatList-withSeparators.js | 27 ++ .../js/examples/FlatList/FlatListExamples.js | 312 ++++++++++++++++++ .../SectionList/SectionListExamples.js | 9 +- .../js/utils/RNTesterList.android.js | 15 + .../rn-tester/js/utils/RNTesterList.ios.js | 15 + 7 files changed, 438 insertions(+), 6 deletions(-) create mode 100644 packages/rn-tester/js/examples/FlatList/FlatList-onEndReached.js create mode 100644 packages/rn-tester/js/examples/FlatList/FlatList-onViewableItemsChanged.js create mode 100644 packages/rn-tester/js/examples/FlatList/FlatList-withSeparators.js create mode 100644 packages/rn-tester/js/examples/FlatList/FlatListExamples.js diff --git a/packages/rn-tester/js/examples/FlatList/FlatList-onEndReached.js b/packages/rn-tester/js/examples/FlatList/FlatList-onEndReached.js new file mode 100644 index 00000000000..ea4f16a892d --- /dev/null +++ b/packages/rn-tester/js/examples/FlatList/FlatList-onEndReached.js @@ -0,0 +1,28 @@ +/** + * 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'; +import {FlatList_onEndReached} from './FlatListExamples'; +const React = require('react'); + +exports.title = 'FlatList onEndReached'; +exports.testTitle = 'Test onEndReached callback'; +exports.category = 'ListView'; +exports.documentationURL = 'https://reactnative.dev/docs/flatlist'; +exports.description = + 'Scroll to end of list or tap Test button to see `onEndReached` triggered.'; +exports.examples = [ + { + title: 'FlatList onEndReached', + render: function(): React.Element { + return ; + }, + }, +]; diff --git a/packages/rn-tester/js/examples/FlatList/FlatList-onViewableItemsChanged.js b/packages/rn-tester/js/examples/FlatList/FlatList-onViewableItemsChanged.js new file mode 100644 index 00000000000..f65f51a461c --- /dev/null +++ b/packages/rn-tester/js/examples/FlatList/FlatList-onViewableItemsChanged.js @@ -0,0 +1,38 @@ +/** + * 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'; +import {FlatList_onViewableItemsChanged} from './FlatListExamples'; +const React = require('react'); + +const VIEWABILITY_CONFIG = { + minimumViewTime: 1000, + viewAreaCoveragePercentThreshold: 100, + waitForInteraction: true, +}; + +exports.title = 'FlatList onViewableItemsChanged'; +exports.testTitle = 'Test onViewableItemsChanged callback'; +exports.category = 'ListView'; +exports.documentationURL = 'https://reactnative.dev/docs/sectionlist'; +exports.description = + 'Scroll list to see what items are returned in `onViewableItemsChanged` callback.'; +exports.examples = [ + { + title: 'FlatList onViewableItemsChanged', + render: function(): React.Element { + return ( + + ); + }, + }, +]; diff --git a/packages/rn-tester/js/examples/FlatList/FlatList-withSeparators.js b/packages/rn-tester/js/examples/FlatList/FlatList-withSeparators.js new file mode 100644 index 00000000000..eccf762de53 --- /dev/null +++ b/packages/rn-tester/js/examples/FlatList/FlatList-withSeparators.js @@ -0,0 +1,27 @@ +/** + * 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'; +import {FlatList_withSeparators} from './FlatListExamples'; +const React = require('react'); + +exports.title = 'FlatList with Separators'; +exports.testTitle = 'Test custom separator components'; +exports.category = 'ListView'; +exports.documentationURL = 'https://reactnative.dev/docs/sectionlist'; +exports.description = 'Tap to see pressed states for separator components.'; +exports.examples = [ + { + title: 'FlatList with Separators', + render: function(): React.Element { + return ; + }, + }, +]; diff --git a/packages/rn-tester/js/examples/FlatList/FlatListExamples.js b/packages/rn-tester/js/examples/FlatList/FlatListExamples.js new file mode 100644 index 00000000000..b8144eb7e4a --- /dev/null +++ b/packages/rn-tester/js/examples/FlatList/FlatListExamples.js @@ -0,0 +1,312 @@ +/** + * 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 strict-local + * @format + */ + +import { + Pressable, + Button, + FlatList, + StyleSheet, + Text, + View, +} from 'react-native'; + +import * as React from 'react'; +type FlatListProps = React.ElementProps; + +type ViewabilityConfig = $PropertyType; + +const DATA = [ + 'Pizza', + 'Burger', + 'Risotto', + 'French Fries', + 'Onion Rings', + 'Fried Shrimps', + 'Water', + 'Coke', + 'Beer', + 'Cheesecake', + 'Ice Cream', +]; + +const Item = ({item, separators}) => { + return ( + { + separators.highlight(); + }} + onPress={() => { + separators.updateProps('trailing', {hasBeenHighlighted: true}); + separators.updateProps('leading', {hasBeenHighlighted: true}); + }} + onPressOut={() => { + separators.unhighlight(); + }} + style={({pressed}) => [ + styles.item, + { + backgroundColor: pressed ? 'red' : 'pink', + }, + ]} + testID={item}> + {item} + + ); +}; + +const Separator = (defaultColor, highlightColor) => ({ + leadingItem, + trailingItem, + highlighted, + hasBeenHighlighted, +}) => { + const text = `Separator for leading ${leadingItem} and trailing ${trailingItem} has ${ + !hasBeenHighlighted ? 'not ' : '' + }been pressed`; + + return ( + + {text} + + ); +}; + +export function FlatList_inverted(): React.Node { + const [output, setOutput] = React.useState('inverted false'); + const [exampleProps, setExampleProps] = React.useState({ + inverted: false, + }); + + const onTest = () => { + setExampleProps({ + inverted: !exampleProps.inverted, + }); + setOutput(`Is inverted: ${(!exampleProps.inverted).toString()}`); + }; + + return ( + + ); +} + +export function FlatList_contentInset(): React.Node { + const [initialContentInset, toggledContentInset] = [44, 88]; + + const [output, setOutput] = React.useState( + `contentInset top: ${initialContentInset.toString()}`, + ); + const [exampleProps, setExampleProps] = React.useState({ + automaticallyAdjustContentInsets: false, + contentInset: {top: initialContentInset}, + contentOffset: {y: -initialContentInset, x: 0}, + }); + + const onTest = () => { + const newContentInset = + exampleProps.contentInset.top === initialContentInset + ? toggledContentInset + : initialContentInset; + setExampleProps({ + automaticallyAdjustContentInsets: false, + contentInset: {top: newContentInset}, + contentOffset: {y: -newContentInset, x: 0}, + }); + setOutput(`contentInset top: ${newContentInset.toString()}`); + }; + + return ( + <> + + Menu + + + + ); +} +export function FlatList_onEndReached(): React.Node { + const [output, setOutput] = React.useState(''); + const exampleProps = { + onEndReached: info => setOutput('onEndReached'), + onEndReachedThreshold: 0, + }; + const ref = React.useRef(null); + + const onTest = () => { + const scrollResponder = ref?.current?.getScrollResponder(); + if (scrollResponder != null) { + scrollResponder.scrollToEnd(); + } + }; + + return ( + + ); +} + +export function FlatList_withSeparators(): React.Node { + const exampleProps = { + ItemSeparatorComponent: Separator('lightgreen', 'green'), + }; + const ref = React.useRef(null); + + return ( + + ); +} + +export function FlatList_onViewableItemsChanged(props: { + viewabilityConfig: ViewabilityConfig, + offScreen?: ?boolean, + horizontal?: ?boolean, +}): React.Node { + const {viewabilityConfig, offScreen, horizontal} = props; + const [output, setOutput] = React.useState(''); + const onViewableItemsChanged = React.useCallback( + info => + setOutput( + info.viewableItems + .filter(viewToken => viewToken.index != null && viewToken.isViewable) + .map(viewToken => viewToken.item) + .join(', '), + ), + [setOutput], + ); + const exampleProps = { + onViewableItemsChanged, + viewabilityConfig, + horizontal, + }; + + return ( + + {offScreen === true ? : null} + + ); +} + +type Props = { + exampleProps: $Shape>, + onTest?: ?() => void, + testLabel?: ?string, + testOutput?: ?string, + children?: ?React.Node, +}; + +const FlatListExampleWithForwardedRef = React.forwardRef( + (props: Props, ref) => { + return ( + + {props.testOutput != null ? ( + + + {props.testOutput} + + {props.onTest != null ? ( +