From 729c6d2f415d6fe60fd00f2f3585a3c103e08783 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Thu, 18 Mar 2021 06:53:41 -0700 Subject: [PATCH 01/10] Fix accessibilityElement accessibility frame Summary: Changelog: [internal] `accessibilityElement.accessibilityFrame` returns CGRect in screen's coordinate space. Screen coordinate space changes whenever user scrolls. Therefore they have to be computed whenever on demand rather than precomputed. Reviewed By: mdvacca Differential Revision: D27118793 fbshipit-source-id: c48a2b9fc3f25b6ae797104371a2627193f4f79a --- .../Text/RCTAccessibilityElement.h | 16 ++++++++++++++++ .../Text/RCTAccessibilityElement.mm | 18 ++++++++++++++++++ ...TParagraphComponentAccessibilityProvider.mm | 4 +++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h create mode 100644 React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h new file mode 100644 index 00000000000000..905844d9f5bcdd --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h @@ -0,0 +1,16 @@ +/* + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTAccessibilityElement : UIAccessibilityElement + +@end + +NS_ASSUME_NONNULL_END diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm new file mode 100644 index 00000000000000..751c1817bad495 --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm @@ -0,0 +1,18 @@ +/* + * 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. + */ + +#import "RCTAccessibilityElement.h" + +@implementation RCTAccessibilityElement + +- (CGRect)accessibilityFrame +{ + UIView *container = (UIView *)self.accessibilityContainer; + return UIAccessibilityConvertFrameToScreenCoordinates(container.bounds, container); +} + +@end diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm index fc40be86aceefc..08ae2cafa1761d 100644 --- a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm @@ -13,6 +13,7 @@ #import #import +#import "RCTAccessibilityElement.h" #import "RCTConversions.h" #import "RCTFabricComponentsPlugins.h" #import "RCTLocalizationProvider.h" @@ -61,7 +62,8 @@ - (instancetype)initWithString:(facebook::react::AttributedString)attributedStri accessibilityLabel = RCTNSStringFromString(_attributedString.getString()); } // add first element has the text for the whole textview in order to read out the whole text - UIAccessibilityElement *firstElement = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:_view]; + UIAccessibilityElement *firstElement = + [[RCTAccessibilityElement alloc] initWithAccessibilityContainer:_view.superview]; firstElement.isAccessibilityElement = YES; firstElement.accessibilityTraits = UIAccessibilityTraitStaticText; firstElement.accessibilityLabel = accessibilityLabel; From f293d41eade6245c0a0d8cc45f55ce56905dcd6a Mon Sep 17 00:00:00 2001 From: Jimmy Zhang Date: Thu, 18 Mar 2021 07:40:01 -0700 Subject: [PATCH 02/10] Back out "Update typed export and fix test", Back out "[VirtualizedSectionList] Remove defaultProps", Back out "[VirtualizedList] Remove keyExtractor defaultProps" Summary: Changelog: Partial revert the stack Reviewed By: makovkastar Differential Revision: D27156625 fbshipit-source-id: b158c9102047bb64ce708b200a8e5786f5a0c176 --- Libraries/Lists/FlatList.js | 37 +++-- Libraries/Lists/SectionList.js | 7 +- Libraries/Lists/VirtualizeUtils.js | 10 -- Libraries/Lists/VirtualizedList.js | 71 +++++----- Libraries/Lists/VirtualizedSectionList.js | 37 +++-- .../__tests__/VirtualizedSectionList-test.js | 45 +++--- .../VirtualizedList-test.js.snap | 18 +++ .../VirtualizedSectionList-test.js.snap | 134 ------------------ 8 files changed, 104 insertions(+), 255 deletions(-) diff --git a/Libraries/Lists/FlatList.js b/Libraries/Lists/FlatList.js index 5ec67e27c9247f..186e93f6e3c99f 100644 --- a/Libraries/Lists/FlatList.js +++ b/Libraries/Lists/FlatList.js @@ -25,7 +25,6 @@ import type { ViewabilityConfigCallbackPair, } from './ViewabilityHelper'; import type {RenderItemType, RenderItemProps} from './VirtualizedList'; -import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils'; type RequiredProps = {| /** @@ -121,7 +120,7 @@ type OptionalProps = {| * and as the react key to track item re-ordering. The default extractor checks `item.key`, then * falls back to using the index, like React does. */ - keyExtractor?: ?(item: ItemT, index: number) => string, + keyExtractor: (item: ItemT, index: number) => string, /** * Multiple columns can only be rendered with `horizontal={false}` and will zig-zag like a * `flexWrap` layout. Items should all be the same height - masonry layouts are not supported. @@ -157,6 +156,7 @@ export type Props = { }; const defaultProps = { + ...VirtualizedList.defaultProps, numColumns: 1, /** * Enabling this prop on Android greatly improves scrolling performance with no known issues. @@ -503,24 +503,20 @@ class FlatList extends React.PureComponent, void> { }; _keyExtractor = (items: ItemT | Array, index: number) => { - const {numColumns} = this.props; - const keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor; - + const {keyExtractor, numColumns} = this.props; if (numColumns > 1) { - if (Array.isArray(items)) { - return items - .map((item, kk) => - keyExtractor(((item: $FlowFixMe): ItemT), index * numColumns + kk), - ) - .join(':'); - } else { - invariant( - Array.isArray(items), - 'FlatList: Encountered internal consistency error, expected each item to consist of an ' + - 'array with 1-%s columns; instead, received a single item.', - numColumns, - ); - } + invariant( + Array.isArray(items), + 'FlatList: Encountered internal consistency error, expected each item to consist of an ' + + 'array with 1-%s columns; instead, received a single item.', + numColumns, + ); + return ( + items + // $FlowFixMe[incompatible-call] + .map((it, kk) => keyExtractor(it, index * numColumns + kk)) + .join(':') + ); } else { // $FlowFixMe Can't call keyExtractor with an array return keyExtractor(items, index); @@ -528,8 +524,7 @@ class FlatList extends React.PureComponent, void> { }; _pushMultiColumnViewable(arr: Array, v: ViewToken): void { - const {numColumns} = this.props; - const keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor; + const {numColumns, keyExtractor} = this.props; v.item.forEach((item, ii) => { invariant(v.index != null, 'Missing index!'); const index = v.index * numColumns + ii; diff --git a/Libraries/Lists/SectionList.js b/Libraries/Lists/SectionList.js index 85687bb18f5755..90124df8e40666 100644 --- a/Libraries/Lists/SectionList.js +++ b/Libraries/Lists/SectionList.js @@ -78,7 +78,7 @@ type OptionalProps> = {| * falls back to using the index, like react does. Note that this sets keys for each item, but * each overall section still needs its own key. */ - keyExtractor?: ?(item: Item, index: number) => string, + keyExtractor: (item: Item, index: number) => string, /** * Called once when the scroll position gets within `onEndReachedThreshold` of the rendered * content. @@ -105,10 +105,6 @@ export type Props = {| VirtualizedSectionListProps, 'renderItem', >, - keyExtractor: $PropertyType< - VirtualizedSectionListProps, - 'keyExtractor', - >, ... }, >, @@ -117,6 +113,7 @@ export type Props = {| |}; const defaultProps = { + ...VirtualizedSectionList.defaultProps, stickySectionHeadersEnabled: Platform.OS === 'ios', }; diff --git a/Libraries/Lists/VirtualizeUtils.js b/Libraries/Lists/VirtualizeUtils.js index 1d80b378aa8d7a..126839d3f92f97 100644 --- a/Libraries/Lists/VirtualizeUtils.js +++ b/Libraries/Lists/VirtualizeUtils.js @@ -233,13 +233,3 @@ export function computeWindowedRenderLimits( } return {first, last}; } - -export function keyExtractor(item: any, index: number): string { - if (typeof item === 'object' && item?.key != null) { - return item.key; - } - if (typeof item === 'object' && item?.id != null) { - return item.id; - } - return String(index); -} diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index b23c3b6921ad77..ae53b7f85d7bb4 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -22,10 +22,7 @@ const infoLog = require('../Utilities/infoLog'); const invariant = require('invariant'); import VirtualizedListInjection from './VirtualizedListInjection'; -import { - keyExtractor as defaultKeyExtractor, - computeWindowedRenderLimits, -} from './VirtualizeUtils'; +import {computeWindowedRenderLimits} from './VirtualizeUtils'; import * as React from 'react'; import type {ScrollResponderType} from '../Components/ScrollView/ScrollView'; @@ -135,7 +132,7 @@ type OptionalProps = {| * Reverses the direction of scroll. Uses scale transforms of -1. */ inverted?: ?boolean, - keyExtractor?: ?(item: Item, index: number) => string, + keyExtractor: (item: Item, index: number) => string, /** * Each cell is rendered using this element. Can be a React Component Class, * or a render function. Defaults to using View. @@ -306,6 +303,10 @@ type Props = {| ...OptionalProps, |}; +type DefaultProps = {| + keyExtractor: (item: Item, index: number) => string, +|}; + let _usedIndexForKey = false; let _keylessItemComponentName: string = ''; @@ -314,37 +315,26 @@ type State = { last: number, }; -/** - * Default Props Helper Functions - * Use the following helper functions for default values - */ - -// horizontalOrDefault(this.props.horizontal) function horizontalOrDefault(horizontal: ?boolean) { return horizontal ?? false; } -// initialNumToRenderOrDefault(this.props.initialNumToRenderOrDefault) function initialNumToRenderOrDefault(initialNumToRender: ?number) { return initialNumToRender ?? 10; } -// maxToRenderPerBatchOrDefault(this.props.maxToRenderPerBatch) function maxToRenderPerBatchOrDefault(maxToRenderPerBatch: ?number) { return maxToRenderPerBatch ?? 10; } -// onEndReachedThresholdOrDefault(this.props.onEndReachedThreshold) function onEndReachedThresholdOrDefault(onEndReachedThreshold: ?number) { return onEndReachedThreshold ?? 2; } -// scrollEventThrottleOrDefault(this.props.scrollEventThrottle) function scrollEventThrottleOrDefault(scrollEventThrottle: ?number) { return scrollEventThrottle ?? 50; } -// windowSizeOrDefault(this.props.windowSize) function windowSizeOrDefault(windowSize: ?number) { return windowSize ?? 21; } @@ -375,7 +365,6 @@ function windowSizeOrDefault(windowSize: ?number) { * and we are working on improving it behind the scenes. * - By default, the list looks for a `key` or `id` prop on each item and uses that for the React key. * Alternatively, you can provide a custom `keyExtractor` prop. - * - As an effort to remove defaultProps, use helper functions when referencing certain props * */ class VirtualizedList extends React.PureComponent { @@ -591,6 +580,22 @@ class VirtualizedList extends React.PureComponent { } } + static defaultProps: DefaultProps = { + keyExtractor: (item: Item, index: number) => { + if (item.key != null) { + return item.key; + } + if (item.id != null) { + return item.id; + } + _usedIndexForKey = true; + if (item.type && item.type.displayName) { + _keylessItemComponentName = item.type.displayName; + } + return String(index); + }, + }; + _getCellKey(): string { return this.context?.cellKey || 'rootList'; } @@ -799,6 +804,7 @@ class VirtualizedList extends React.PureComponent { getItem, getItemCount, horizontal, + keyExtractor, } = this.props; const stickyOffset = this.props.ListHeaderComponent ? 1 : 0; const end = getItemCount(data) - 1; @@ -806,7 +812,7 @@ class VirtualizedList extends React.PureComponent { last = Math.min(end, last); for (let ii = first; ii <= last; ii++) { const item = getItem(data, ii); - const key = this._keyExtractor(item, ii); + const key = keyExtractor(item, ii); this._indicesToKeys.set(ii, key); if (stickyIndicesFromProps.has(ii + stickyOffset)) { stickyHeaderIndices.push(cells.length); @@ -858,21 +864,6 @@ class VirtualizedList extends React.PureComponent { _getSpacerKey = (isVertical: boolean): string => isVertical ? 'height' : 'width'; - _keyExtractor(item: Item, index: number) { - if (this.props.keyExtractor != null) { - return this.props.keyExtractor(item, index); - } - - const key = defaultKeyExtractor(item, index); - if (key === String(index)) { - _usedIndexForKey = true; - if (item.type && item.type.displayName) { - _keylessItemComponentName = item.type.displayName; - } - } - return key; - } - render(): React.Node { if (__DEV__) { const flatStyles = flattenStyle(this.props.contentContainerStyle); @@ -1825,9 +1816,9 @@ class VirtualizedList extends React.PureComponent { }; _createViewToken = (index: number, isViewable: boolean) => { - const {data, getItem} = this.props; + const {data, getItem, keyExtractor} = this.props; const item = getItem(data, index); - return {index, item, key: this._keyExtractor(item, index), isViewable}; + return {index, item, key: keyExtractor(item, index), isViewable}; }; _getFrameMetricsApprox = ( @@ -1863,13 +1854,19 @@ class VirtualizedList extends React.PureComponent { inLayout?: boolean, ... } => { - const {data, getItem, getItemCount, getItemLayout} = this.props; + const { + data, + getItem, + getItemCount, + getItemLayout, + keyExtractor, + } = this.props; invariant( getItemCount(data) > index, 'Tried to get frame for out of range index ' + index, ); const item = getItem(data, index); - let frame = item && this._frames[this._keyExtractor(item, index)]; + let frame = item && this._frames[keyExtractor(item, index)]; if (!frame || frame.index !== index) { if (getItemLayout) { frame = getItemLayout(data, index); diff --git a/Libraries/Lists/VirtualizedSectionList.js b/Libraries/Lists/VirtualizedSectionList.js index 5a5ddabd9ae084..af85f52d3512bf 100644 --- a/Libraries/Lists/VirtualizedSectionList.js +++ b/Libraries/Lists/VirtualizedSectionList.js @@ -17,7 +17,6 @@ const VirtualizedList = require('./VirtualizedList'); const invariant = require('invariant'); import type {ViewToken} from './ViewabilityHelper'; -import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils'; type Item = any; @@ -100,18 +99,14 @@ type OptionalProps> = {| onEndReached?: ?({distanceFromEnd: number, ...}) => void, |}; -type VirtualizedListProps = React.ElementConfig; +type VirtualizedListProps = React.ElementProps; export type Props = {| ...RequiredProps, ...OptionalProps, ...$Diff< VirtualizedListProps, - { - renderItem: $PropertyType, - data: $PropertyType, - ... - }, + {renderItem: $PropertyType, ...}, >, |}; export type ScrollToLocationParamsType = {| @@ -122,6 +117,11 @@ export type ScrollToLocationParamsType = {| viewPosition?: number, |}; +type DefaultProps = {| + ...typeof VirtualizedList.defaultProps, + data: $ReadOnlyArray, +|}; + type State = {childProps: VirtualizedListProps, ...}; /** @@ -132,6 +132,11 @@ type State = {childProps: VirtualizedListProps, ...}; class VirtualizedSectionList< SectionT: SectionBase, > extends React.PureComponent, State> { + static defaultProps: DefaultProps = { + ...VirtualizedList.defaultProps, + data: [], + }; + scrollToLocation(params: ScrollToLocationParamsType) { let index = params.itemIndex; for (let i = 0; i < params.sectionIndex; i++) { @@ -212,11 +217,11 @@ class VirtualizedSectionList< ); } - _getItem( + _getItem = ( props: Props, sections: ?$ReadOnlyArray, index: number, - ): ?Item { + ): ?Item => { if (!sections) { return null; } @@ -238,7 +243,7 @@ class VirtualizedSectionList< } } return null; - } + }; _keyExtractor = (item: Item, index: number) => { const info = this._subExtractor(index); @@ -287,8 +292,7 @@ class VirtualizedSectionList< trailingSection: sections[i + 1], }; } else { - const extractor = - section.keyExtractor || keyExtractor || defaultKeyExtractor; + const extractor = section.keyExtractor || keyExtractor; return { section, key: @@ -577,11 +581,4 @@ class ItemWithSeparator extends React.Component< } } -module.exports = (VirtualizedSectionList: React.AbstractComponent< - React.ElementConfig, - $ReadOnly<{ - getListRef: () => ?React.ElementRef, - scrollToLocation: (params: ScrollToLocationParamsType) => void, - ... - }>, ->); +module.exports = VirtualizedSectionList; diff --git a/Libraries/Lists/__tests__/VirtualizedSectionList-test.js b/Libraries/Lists/__tests__/VirtualizedSectionList-test.js index 260da5555f7585..8a13d7556b45a9 100644 --- a/Libraries/Lists/__tests__/VirtualizedSectionList-test.js +++ b/Libraries/Lists/__tests__/VirtualizedSectionList-test.js @@ -103,37 +103,26 @@ describe('VirtualizedSectionList', () => { it('handles separators correctly', () => { const infos = []; - let component; - ReactTestRenderer.act(() => { - component = ReactTestRenderer.create( - } - sections={[ - {title: 's0', data: [{key: 'i0'}, {key: 'i1'}, {key: 'i2'}]}, - ]} - renderItem={info => { - infos.push(info); - return ; - }} - getItem={(data, key) => data[key]} - getItemCount={data => data.length} - />, - ); - }); - expect(component).toMatchSnapshot(); - - ReactTestRenderer.act(() => { - infos[1].separators.highlight(); - }); + const component = ReactTestRenderer.create( + } + sections={[ + {title: 's0', data: [{key: 'i0'}, {key: 'i1'}, {key: 'i2'}]}, + ]} + renderItem={info => { + infos.push(info); + return ; + }} + getItem={(data, key) => data[key]} + getItemCount={data => data.length} + />, + ); expect(component).toMatchSnapshot(); - ReactTestRenderer.act(() => { - infos[2].separators.updateProps('leading', {press: true}); - }); + infos[1].separators.highlight(); expect(component).toMatchSnapshot(); - ReactTestRenderer.act(() => { - infos[1].separators.unhighlight(); - }); + infos[2].separators.updateProps('leading', {press: true}); expect(component).toMatchSnapshot(); + infos[1].separators.unhighlight(); }); it('handles nested lists', () => { diff --git a/Libraries/Lists/__tests__/__snapshots__/VirtualizedList-test.js.snap b/Libraries/Lists/__tests__/__snapshots__/VirtualizedList-test.js.snap index 6bd99586b38897..9763a8bd8b5962 100644 --- a/Libraries/Lists/__tests__/__snapshots__/VirtualizedList-test.js.snap +++ b/Libraries/Lists/__tests__/__snapshots__/VirtualizedList-test.js.snap @@ -44,6 +44,7 @@ exports[`VirtualizedList forwards correct stickyHeaderIndices when all in initia getItemCount={[Function]} getItemLayout={[Function]} initialNumToRender={10} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -185,6 +186,7 @@ exports[`VirtualizedList forwards correct stickyHeaderIndices when partially in getItemCount={[Function]} getItemLayout={[Function]} initialNumToRender={5} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -264,6 +266,7 @@ exports[`VirtualizedList handles nested lists 1`] = ` } getItem={[Function]} getItemCount={[Function]} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -294,6 +297,7 @@ exports[`VirtualizedList handles nested lists 1`] = ` getItem={[Function]} getItemCount={[Function]} horizontal={false} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -341,6 +345,7 @@ exports[`VirtualizedList handles nested lists 1`] = ` getItem={[Function]} getItemCount={[Function]} horizontal={true} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -408,6 +413,7 @@ exports[`VirtualizedList handles separators correctly 1`] = ` } getItem={[Function]} getItemCount={[Function]} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -482,6 +488,7 @@ exports[`VirtualizedList handles separators correctly 2`] = ` } getItem={[Function]} getItemCount={[Function]} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -556,6 +563,7 @@ exports[`VirtualizedList handles separators correctly 3`] = ` } getItem={[Function]} getItemCount={[Function]} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -703,6 +711,7 @@ exports[`VirtualizedList keeps sticky headers realized after scrolled out of vie getItemCount={[Function]} getItemLayout={[Function]} initialNumToRender={1} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -891,6 +900,7 @@ exports[`VirtualizedList realizes sticky headers in viewport on batched render 1 getItemCount={[Function]} getItemLayout={[Function]} initialNumToRender={1} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -1162,6 +1172,7 @@ exports[`VirtualizedList renders empty list 1`] = ` data={Array []} getItem={[Function]} getItemCount={[Function]} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -1185,6 +1196,7 @@ exports[`VirtualizedList renders empty list with empty component 1`] = ` data={Array []} getItem={[Function]} getItemCount={[Function]} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -1224,6 +1236,7 @@ exports[`VirtualizedList renders list with empty component 1`] = ` } getItem={[Function]} getItemCount={[Function]} + keyExtractor={[Function]} onContentSizeChange={[Function]} onLayout={[Function]} onMomentumScrollBegin={[Function]} @@ -1252,6 +1265,7 @@ exports[`VirtualizedList renders null list 1`] = ` `; -exports[`VirtualizedSectionList handles separators correctly 4`] = ` - - - - - - - - - - - - - - - - - - - - - -`; - exports[`VirtualizedSectionList renders all the bells and whistles 1`] = ` Date: Thu, 18 Mar 2021 08:01:17 -0700 Subject: [PATCH 03/10] Switch AdsManagerRefreshableScrollView to use ElementConfig instead of ElementProps Summary: Changelog: [Changed] Removed rest operator from ScrollViewStickyHeader props Reviewed By: lunaleaps Differential Revision: D27100507 fbshipit-source-id: 7d90ebeaf757bcaed0b125a4a8abf44f07adf98f --- Libraries/Components/ScrollView/ScrollViewStickyHeader.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Libraries/Components/ScrollView/ScrollViewStickyHeader.js b/Libraries/Components/ScrollView/ScrollViewStickyHeader.js index db5ae18682b852..d2c8e1d322fef0 100644 --- a/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +++ b/Libraries/Components/ScrollView/ScrollViewStickyHeader.js @@ -22,7 +22,7 @@ import type {LayoutEvent} from '../../Types/CoreEventTypes'; const AnimatedView = AnimatedImplementation.createAnimatedComponent(View); -export type Props = { +export type Props = $ReadOnly<{ children?: React.Element, nextHeaderLayoutY: ?number, onLayout: (event: LayoutEvent) => void, @@ -34,8 +34,7 @@ export type Props = { scrollViewHeight: ?number, nativeID?: ?string, hiddenOnScroll?: ?boolean, - ... -}; +}>; type State = { measured: boolean, From 54f754b3908a94c7a73550625e0d03d98585cc45 Mon Sep 17 00:00:00 2001 From: Kacie Bawiec Date: Thu, 18 Mar 2021 08:10:18 -0700 Subject: [PATCH 04/10] Add LTR and RTL Horizontal ScrollViews for E2E Tests Summary: This diff splits up the LTR and RTL examples in RNTester for Horizontal ScrollView into two examples for ease of E2E testing. Changelog: [Changed] Split RTL and LTR Horizontal ScrollView tests in RNTester into two tests Reviewed By: lunaleaps Differential Revision: D27139885 fbshipit-source-id: aae8aa06f4827507d1bc26a6b173d39cc92e20fe --- .../examples/ScrollView/ScrollViewExample.js | 89 ++++++++++--------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js b/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js index ab0170176e40fc..35bf0b968a03b6 100644 --- a/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js +++ b/packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js @@ -83,53 +83,27 @@ exports.examples = ([ }, }, { + name: 'horizontalScrollTo', title: ' (horizontal = true)\n', description: "You can display 's child components horizontally rather than vertically", render: function(): React.Node { - function renderScrollView( - title: string, - additionalStyles: ViewStyleProp, - ) { - let _scrollView: ?React.ElementRef; - return ( - - {title} - { - _scrollView = scrollView; - }} - automaticallyAdjustContentInsets={false} - horizontal={true} - style={[styles.scrollView, styles.horizontalScrollView]}> - {ITEMS.map(createItemRow)} - -