@office-iss/react-native-win32 0.68.0 → 0.69.0-preview.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.flowconfig +1 -3
  3. package/CHANGELOG.json +386 -32
  4. package/CHANGELOG.md +166 -19
  5. package/IntegrationTests/BUCK +4 -1
  6. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +7 -0
  7. package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +1 -0
  8. package/Libraries/Alert/Alert.win32.js +1 -1
  9. package/Libraries/Animated/AnimatedImplementation.js +1 -1
  10. package/Libraries/Animated/NativeAnimatedHelper.js +55 -9
  11. package/Libraries/Animated/NativeAnimatedModule.js +1 -0
  12. package/Libraries/Animated/NativeAnimatedTurboModule.js +1 -0
  13. package/Libraries/Animated/animations/TimingAnimation.js +6 -11
  14. package/Libraries/Animated/createAnimatedComponent.js +2 -2
  15. package/Libraries/Animated/nodes/AnimatedColor.js +95 -29
  16. package/Libraries/Animated/nodes/AnimatedInterpolation.js +19 -22
  17. package/Libraries/Animated/nodes/AnimatedNode.js +2 -2
  18. package/Libraries/Animated/nodes/AnimatedValue.js +1 -1
  19. package/Libraries/AppState/AppState.js +1 -1
  20. package/Libraries/Blob/URL.js +7 -1
  21. package/Libraries/Components/Button.js +3 -0
  22. package/Libraries/Components/DatePickerAndroid/NativeDatePickerAndroid.js +5 -0
  23. package/Libraries/Components/Pressable/Pressable.js +3 -3
  24. package/Libraries/Components/Pressable/Pressable.win32.js +3 -3
  25. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +47 -38
  26. package/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js +15 -7
  27. package/Libraries/Components/ScrollView/ScrollView.js +1 -1
  28. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +16 -3
  29. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +3 -1
  30. package/Libraries/Components/Slider/Slider.js +0 -2
  31. package/Libraries/Components/Slider/SliderNativeComponent.js +0 -1
  32. package/Libraries/Components/StatusBar/StatusBar.js +6 -1
  33. package/Libraries/Components/Switch/Switch.js +11 -1
  34. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +114 -109
  35. package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +17 -9
  36. package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +13 -5
  37. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +10 -0
  38. package/Libraries/Components/TextInput/TextInput.js +1 -8
  39. package/Libraries/Components/TextInput/TextInputState.js +10 -2
  40. package/Libraries/Components/TextInput/TextInputState.win32.js +10 -2
  41. package/Libraries/Components/Touchable/Tests/TouchableWin32Test.js.map +1 -1
  42. package/Libraries/Components/Touchable/TouchableBounce.js +1 -0
  43. package/Libraries/Components/Touchable/TouchableHighlight.js +1 -0
  44. package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -0
  45. package/Libraries/Components/Touchable/TouchableOpacity.js +7 -1
  46. package/Libraries/Components/Touchable/TouchableWin32.Props.d.ts +3 -1
  47. package/Libraries/Components/Touchable/TouchableWin32.Props.js.map +1 -1
  48. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +2 -0
  49. package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
  50. package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +1 -0
  51. package/Libraries/Components/View/View.win32.js +33 -1
  52. package/Libraries/Components/View/ViewNativeComponent.js +68 -8
  53. package/Libraries/Components/View/ViewPropTypes.js +36 -4
  54. package/Libraries/Components/View/ViewPropTypes.win32.js +36 -4
  55. package/Libraries/Components/View/ViewWin32.Props.d.ts +1 -1
  56. package/Libraries/Components/View/ViewWin32.Props.js.map +1 -1
  57. package/Libraries/Core/Devtools/parseHermesStack.js +1 -1
  58. package/Libraries/Core/ExceptionsManager.js +1 -1
  59. package/Libraries/Core/RawEventEmitter.js +38 -0
  60. package/Libraries/Core/ReactNativeVersion.js +2 -2
  61. package/Libraries/Core/polyfillPromise.js +32 -0
  62. package/Libraries/Core/setUpReactDevTools.js +3 -2
  63. package/Libraries/EventEmitter/NativeEventEmitter.js +3 -3
  64. package/Libraries/EventEmitter/RCTDeviceEventEmitter.js +2 -1
  65. package/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js +3 -3
  66. package/Libraries/Events/CustomEvent.js +32 -0
  67. package/Libraries/Events/EventPolyfill.js +239 -0
  68. package/Libraries/Image/Image.android.js +0 -6
  69. package/Libraries/Image/Image.ios.js +0 -6
  70. package/Libraries/Image/Image.win32.js +2 -8
  71. package/Libraries/Image/ImageViewNativeComponent.js +18 -3
  72. package/Libraries/Image/TextInlineImageNativeComponent.js +23 -15
  73. package/Libraries/Image/resolveAssetSource.win32.js +1 -1
  74. package/Libraries/Inspector/Inspector.js +2 -4
  75. package/Libraries/Inspector/Inspector.win32.js +7 -9
  76. package/Libraries/Interaction/BridgeSpyStallHandler.js +4 -3
  77. package/Libraries/Interaction/InteractionManager.js +1 -12
  78. package/Libraries/Interaction/TaskQueue.js +5 -4
  79. package/Libraries/LayoutAnimation/LayoutAnimation.js +13 -0
  80. package/Libraries/Linking/Linking.js +1 -1
  81. package/Libraries/Lists/FlatList.js +27 -6
  82. package/Libraries/Lists/VirtualizedList.js +71 -55
  83. package/Libraries/Lists/VirtualizedListContext.js +7 -3
  84. package/Libraries/Lists/VirtualizedSectionList.js +2 -2
  85. package/Libraries/Lists/__tests__/{FillRateHelper-test.windows.js → FillRateHelper-test.js} +2 -2
  86. package/Libraries/Lists/__tests__/{FlatList-test.windows.js → FlatList-test.js} +2 -2
  87. package/Libraries/Lists/__tests__/{SectionList-test.windows.js → SectionList-test.js} +14 -14
  88. package/Libraries/Lists/__tests__/{VirtualizeUtils-test.windows.js → VirtualizeUtils-test.js} +3 -3
  89. package/Libraries/Lists/__tests__/{VirtualizedList-test.windows.js → VirtualizedList-test.js} +92 -43
  90. package/Libraries/Lists/__tests__/{VirtualizedSectionList-test.windows.js → VirtualizedSectionList-test.js} +16 -14
  91. package/Libraries/LogBox/Data/LogBoxData.js +2 -2
  92. package/Libraries/LogBox/Data/LogBoxLog.js +1 -1
  93. package/Libraries/LogBox/Data/LogBoxSymbolication.js +1 -1
  94. package/Libraries/LogBox/Data/parseLogBoxLog.js +1 -1
  95. package/Libraries/LogBox/LogBox.js +2 -21
  96. package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +1 -0
  97. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +2 -1
  98. package/Libraries/NativeComponent/BaseViewConfig.android.js +295 -0
  99. package/Libraries/NativeComponent/BaseViewConfig.ios.js +333 -0
  100. package/Libraries/NativeComponent/BaseViewConfig.win32.js +334 -0
  101. package/Libraries/NativeComponent/NativeComponentRegistry.js +0 -2
  102. package/Libraries/NativeComponent/PlatformBaseViewConfig.js +24 -0
  103. package/Libraries/NativeComponent/StaticViewConfigValidator.js +7 -42
  104. package/Libraries/NativeComponent/ViewConfig.js +4 -4
  105. package/Libraries/NativeComponent/ViewConfigIgnore.js +54 -0
  106. package/Libraries/Network/FormData.js +7 -1
  107. package/Libraries/Network/RCTNetworking.win32.js +1 -1
  108. package/Libraries/Pressability/Pressability.js +115 -46
  109. package/Libraries/Pressability/Pressability.win32.js +174 -69
  110. package/Libraries/Pressability/PressabilityDebug.js +5 -9
  111. package/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js +1 -0
  112. package/Libraries/ReactNative/AppContainer.js +1 -1
  113. package/Libraries/ReactNative/{DummyUIManager.js → BridgelessUIManager.js} +62 -40
  114. package/Libraries/ReactNative/PaperUIManager.win32.js +5 -5
  115. package/Libraries/ReactNative/ReactNativeFeatureFlags.js +39 -0
  116. package/Libraries/ReactNative/UIManager.js +2 -3
  117. package/Libraries/ReactNative/renderApplication.js +4 -0
  118. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +8 -0
  119. package/Libraries/Renderer/implementations/ReactFabric-dev.js +5908 -4906
  120. package/Libraries/Renderer/implementations/ReactFabric-prod.js +2100 -1918
  121. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2567 -2352
  122. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +5610 -4844
  123. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +1710 -1556
  124. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +1830 -1639
  125. package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
  126. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -1
  127. package/Libraries/StyleSheet/EdgeInsetsPropType.js +4 -1
  128. package/Libraries/StyleSheet/StyleSheetTypes.js +59 -66
  129. package/Libraries/StyleSheet/normalizeColor.js +1 -1
  130. package/Libraries/StyleSheet/private/_StyleSheetTypesOverrides.js +15 -0
  131. package/Libraries/StyleSheet/private/_TransformStyle.js +53 -0
  132. package/Libraries/Text/Text.js +13 -7
  133. package/Libraries/Text/TextNativeComponent.js +2 -0
  134. package/Libraries/Text/TextNativeComponent.win32.js +2 -0
  135. package/Libraries/Text/TextProps.js +10 -0
  136. package/Libraries/Types/CoreEventTypes.js +13 -1
  137. package/Libraries/Types/CoreEventTypes.win32.js +26 -1
  138. package/Libraries/Utilities/Appearance.js +0 -8
  139. package/Libraries/Utilities/HMRClient.js +1 -1
  140. package/Libraries/Utilities/ReactNativeTestTools.js +1 -0
  141. package/Libraries/Utilities/codegenNativeComponent.js +16 -6
  142. package/Libraries/Utilities/stringifySafe.js +4 -1
  143. package/Libraries/Utilities/useColorScheme.js +9 -15
  144. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +3 -3
  145. package/Libraries/WebSocket/WebSocket.js +1 -1
  146. package/Libraries/vendor/emitter/_EmitterSubscription.js +1 -1
  147. package/Libraries/vendor/emitter/_EventEmitter.js +1 -1
  148. package/Libraries/vendor/emitter/_EventSubscription.js +1 -1
  149. package/flow/{use-subscription.js → use-sync-external-store.js} +4 -4
  150. package/index.js +30 -25
  151. package/index.win32.js +30 -25
  152. package/jest/preprocessor.js +24 -107
  153. package/jest/preprocessor_DO_NOT_USE.js +122 -0
  154. package/metro.config.js +3 -47
  155. package/overrides.json +39 -46
  156. package/package.json +32 -29
  157. package/rntypes/index.d.ts +19 -7
  158. package/src/Libraries/Components/Touchable/Tests/TouchableWin32Test.tsx +1 -1
  159. package/src/Libraries/Components/Touchable/TouchableWin32.Props.tsx +3 -1
  160. package/src/Libraries/Components/View/ViewWin32.Props.ts +1 -0
  161. package/src/Libraries/Lists/__tests__/__snapshots__/FlatList-test.js.snap +427 -0
  162. package/src/Libraries/Lists/__tests__/__snapshots__/SectionList-test.js.snap +391 -0
  163. package/src/Libraries/Lists/__tests__/__snapshots__/VirtualizeUtils-test.js.snap +3 -0
  164. package/src/Libraries/Lists/__tests__/__snapshots__/VirtualizedList-test.js.snap +4565 -0
  165. package/src/Libraries/Lists/__tests__/__snapshots__/VirtualizedSectionList-test.js.snap +1153 -0
  166. package/src/rntypes/index.d.ts +19 -7
  167. package/typings-index.js +5 -1
  168. package/typings-index.js.map +1 -1
  169. package/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js +0 -44
  170. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +0 -45
  171. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +0 -123
  172. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.js +0 -45
  173. package/Libraries/Components/View/ReactNativeViewViewConfig.js +0 -360
  174. package/Libraries/Components/View/ReactNativeViewViewConfig.win32.js +0 -401
  175. package/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js +0 -83
  176. package/Libraries/ReactNative/UIManagerInjection.js +0 -15
  177. package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +0 -24527
  178. package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +0 -8309
  179. package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +0 -8961
  180. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +0 -24948
  181. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +0 -8400
  182. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +0 -9049
  183. package/flow/Promise.js +0 -47
@@ -26,6 +26,7 @@ import type {
26
26
  } from './ViewabilityHelper';
27
27
  import type {RenderItemType, RenderItemProps} from './VirtualizedList';
28
28
  import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
29
+ import memoizeOne from 'memoize-one';
29
30
 
30
31
  type RequiredProps<ItemT> = {|
31
32
  /**
@@ -141,6 +142,10 @@ type OptionalProps<ItemT> = {|
141
142
  * See `ScrollView` for flow type and further documentation.
142
143
  */
143
144
  fadingEdgeLength?: ?number,
145
+ /**
146
+ * Enable an optimization to memoize the item renderer to prevent unnecessary rerenders.
147
+ */
148
+ strictMode?: boolean,
144
149
  |};
145
150
 
146
151
  /**
@@ -578,9 +583,14 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
578
583
  };
579
584
  }
580
585
 
581
- _renderer = () => {
582
- const {ListItemComponent, renderItem, columnWrapperStyle} = this.props;
583
- const numColumns = numColumnsOrDefault(this.props.numColumns);
586
+ _renderer = (
587
+ ListItemComponent: ?(React.ComponentType<any> | React.Element<any>),
588
+ renderItem: ?RenderItemType<ItemT>,
589
+ columnWrapperStyle: ?ViewStyleProp,
590
+ numColumns: ?number,
591
+ extraData: ?any,
592
+ ) => {
593
+ const cols = numColumnsOrDefault(numColumns);
584
594
 
585
595
  let virtualizedListRenderKey = ListItemComponent
586
596
  ? 'ListItemComponent'
@@ -605,7 +615,7 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
605
615
  * This comment suppresses an error found when Flow v0.111 was deployed.
606
616
  * To see the error, delete this comment and run Flow. */
607
617
  [virtualizedListRenderKey]: (info: RenderItemProps<ItemT>) => {
608
- if (numColumns > 1) {
618
+ if (cols > 1) {
609
619
  const {item, index} = info;
610
620
  invariant(
611
621
  Array.isArray(item),
@@ -616,7 +626,7 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
616
626
  {item.map((it, kk) => {
617
627
  const element = renderer({
618
628
  item: it,
619
- index: index * numColumns + kk,
629
+ index: index * cols + kk,
620
630
  separators: info.separators,
621
631
  });
622
632
  return element != null ? (
@@ -632,14 +642,19 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
632
642
  };
633
643
  };
634
644
 
645
+ _memoizedRenderer = memoizeOne(this._renderer);
646
+
635
647
  render(): React.Node {
636
648
  const {
637
649
  numColumns,
638
650
  columnWrapperStyle,
639
651
  removeClippedSubviews: _removeClippedSubviews,
652
+ strictMode = false,
640
653
  ...restProps
641
654
  } = this.props;
642
655
 
656
+ const renderer = strictMode ? this._memoizedRenderer : this._renderer;
657
+
643
658
  return (
644
659
  <VirtualizedList
645
660
  {...restProps}
@@ -651,7 +666,13 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
651
666
  removeClippedSubviews={removeClippedSubviewsOrDefault(
652
667
  _removeClippedSubviews,
653
668
  )}
654
- {...this._renderer()}
669
+ {...renderer(
670
+ this.props.ListItemComponent,
671
+ this.props.renderItem,
672
+ columnWrapperStyle,
673
+ numColumns,
674
+ this.props.extraData,
675
+ )}
655
676
  />
656
677
  );
657
678
  }
@@ -34,6 +34,7 @@ import type {
34
34
  ViewToken,
35
35
  ViewabilityConfigCallbackPair,
36
36
  } from './ViewabilityHelper';
37
+ import type {LayoutEvent} from '../Types/CoreEventTypes';
37
38
  import {
38
39
  VirtualizedListCellContextProvider,
39
40
  VirtualizedListContext,
@@ -384,7 +385,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
384
385
  scrollToEnd(params?: ?{animated?: ?boolean, ...}) {
385
386
  const animated = params ? params.animated : true;
386
387
  const veryLast = this.props.getItemCount(this.props.data) - 1;
387
- const frame = this._getFrameMetricsApprox(veryLast);
388
+ const frame = this.__getFrameMetricsApprox(veryLast);
388
389
  const offset = Math.max(
389
390
  0,
390
391
  frame.offset +
@@ -458,7 +459,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
458
459
  });
459
460
  return;
460
461
  }
461
- const frame = this._getFrameMetricsApprox(index);
462
+ const frame = this.__getFrameMetricsApprox(index);
462
463
  const offset =
463
464
  Math.max(
464
465
  0,
@@ -796,12 +797,17 @@ class VirtualizedList extends React.PureComponent<Props, State> {
796
797
  const {
797
798
  CellRendererComponent,
798
799
  ItemSeparatorComponent,
800
+ ListHeaderComponent,
801
+ ListItemComponent,
799
802
  data,
803
+ debug,
800
804
  getItem,
801
805
  getItemCount,
806
+ getItemLayout,
802
807
  horizontal,
808
+ renderItem,
803
809
  } = this.props;
804
- const stickyOffset = this.props.ListHeaderComponent ? 1 : 0;
810
+ const stickyOffset = ListHeaderComponent ? 1 : 0;
805
811
  const end = getItemCount(data) - 1;
806
812
  let prevCellKey;
807
813
  last = Math.min(end, last);
@@ -816,21 +822,24 @@ class VirtualizedList extends React.PureComponent<Props, State> {
816
822
  <CellRenderer
817
823
  CellRendererComponent={CellRendererComponent}
818
824
  ItemSeparatorComponent={ii < end ? ItemSeparatorComponent : undefined}
825
+ ListItemComponent={ListItemComponent}
819
826
  cellKey={key}
827
+ debug={debug}
820
828
  fillRateHelper={this._fillRateHelper}
829
+ getItemLayout={getItemLayout}
821
830
  horizontal={horizontal}
822
831
  index={ii}
823
832
  inversionStyle={inversionStyle}
824
833
  item={item}
825
834
  key={key}
826
835
  prevCellKey={prevCellKey}
836
+ onCellLayout={this._onCellLayout}
827
837
  onUpdateSeparators={this._onUpdateSeparators}
828
- onLayout={e => this._onCellLayout(e, key, ii)}
829
838
  onUnmount={this._onCellUnmount}
830
- parentProps={this.props}
831
839
  ref={ref => {
832
840
  this._cellRefs[key] = ref;
833
841
  }}
842
+ renderItem={renderItem}
834
843
  />,
835
844
  );
836
845
  prevCellKey = key;
@@ -950,8 +959,8 @@ class VirtualizedList extends React.PureComponent<Props, State> {
950
959
  // See if there are any sticky headers in the virtualized space that we need to render.
951
960
  for (let ii = firstAfterInitial - 1; ii > lastInitialIndex; ii--) {
952
961
  if (stickyIndicesFromProps.has(ii + stickyOffset)) {
953
- const initBlock = this._getFrameMetricsApprox(lastInitialIndex);
954
- const stickyBlock = this._getFrameMetricsApprox(ii);
962
+ const initBlock = this.__getFrameMetricsApprox(lastInitialIndex);
963
+ const stickyBlock = this.__getFrameMetricsApprox(ii);
955
964
  const leadSpace =
956
965
  stickyBlock.offset -
957
966
  initBlock.offset -
@@ -968,7 +977,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
968
977
  inversionStyle,
969
978
  );
970
979
  const trailSpace =
971
- this._getFrameMetricsApprox(first).offset -
980
+ this.__getFrameMetricsApprox(first).offset -
972
981
  (stickyBlock.offset + stickyBlock.length);
973
982
  cells.push(
974
983
  <View key="$sticky_trail" style={{[spacerKey]: trailSpace}} />,
@@ -979,9 +988,9 @@ class VirtualizedList extends React.PureComponent<Props, State> {
979
988
  }
980
989
  }
981
990
  if (!insertedStickySpacer) {
982
- const initBlock = this._getFrameMetricsApprox(lastInitialIndex);
991
+ const initBlock = this.__getFrameMetricsApprox(lastInitialIndex);
983
992
  const firstSpace =
984
- this._getFrameMetricsApprox(first).offset -
993
+ this.__getFrameMetricsApprox(first).offset -
985
994
  (initBlock.offset + initBlock.length);
986
995
  cells.push(
987
996
  <View key="$lead_spacer" style={{[spacerKey]: firstSpace}} />,
@@ -1005,14 +1014,14 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1005
1014
  this._hasWarned.keys = true;
1006
1015
  }
1007
1016
  if (!isVirtualizationDisabled && last < itemCount - 1) {
1008
- const lastFrame = this._getFrameMetricsApprox(last);
1017
+ const lastFrame = this.__getFrameMetricsApprox(last);
1009
1018
  // Without getItemLayout, we limit our tail spacer to the _highestMeasuredFrameIndex to
1010
1019
  // prevent the user for hyperscrolling into un-measured area because otherwise content will
1011
1020
  // likely jump around as it renders in above the viewport.
1012
1021
  const end = this.props.getItemLayout
1013
1022
  ? itemCount - 1
1014
1023
  : Math.min(itemCount - 1, this._highestMeasuredFrameIndex);
1015
- const endFrame = this._getFrameMetricsApprox(end);
1024
+ const endFrame = this.__getFrameMetricsApprox(end);
1016
1025
  const tailSpacerLength =
1017
1026
  endFrame.offset +
1018
1027
  endFrame.length -
@@ -1119,7 +1128,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1119
1128
  )}
1120
1129
  </VirtualizedListContextProvider>
1121
1130
  );
1122
- let ret = innerRet;
1131
+ let ret: React.Node = innerRet;
1123
1132
  if (__DEV__) {
1124
1133
  ret = (
1125
1134
  <ScrollView.Context.Consumer>
@@ -1268,7 +1277,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1268
1277
  }
1269
1278
  };
1270
1279
 
1271
- _onCellLayout(e, cellKey, index) {
1280
+ _onCellLayout = (e: LayoutEvent, cellKey: string, index: number): void => {
1272
1281
  const layout = e.nativeEvent.layout;
1273
1282
  const next = {
1274
1283
  offset: this._selectOffset(layout),
@@ -1301,7 +1310,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1301
1310
 
1302
1311
  this._computeBlankness();
1303
1312
  this._updateViewableItems(this.props.data);
1304
- }
1313
+ };
1305
1314
 
1306
1315
  _onCellUnmount = (cellKey: string) => {
1307
1316
  const curr = this._frames[cellKey];
@@ -1380,7 +1389,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1380
1389
  }
1381
1390
  }
1382
1391
 
1383
- _onLayout = (e: Object) => {
1392
+ _onLayout = (e: LayoutEvent) => {
1384
1393
  if (this._isNestedWithSameOrientation()) {
1385
1394
  // Need to adjust our scroll metrics to be relative to our containing
1386
1395
  // VirtualizedList before we can make claims about list item viewability
@@ -1395,7 +1404,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1395
1404
  this._maybeCallOnEndReached();
1396
1405
  };
1397
1406
 
1398
- _onLayoutEmpty = e => {
1407
+ _onLayoutEmpty = (e: LayoutEvent) => {
1399
1408
  this.props.onLayout && this.props.onLayout(e);
1400
1409
  };
1401
1410
 
@@ -1403,12 +1412,12 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1403
1412
  return this._getCellKey() + '-footer';
1404
1413
  }
1405
1414
 
1406
- _onLayoutFooter = e => {
1415
+ _onLayoutFooter = (e: LayoutEvent) => {
1407
1416
  this._triggerRemeasureForChildListsInCell(this._getFooterCellKey());
1408
1417
  this._footerLength = this._selectLength(e.nativeEvent.layout);
1409
1418
  };
1410
1419
 
1411
- _onLayoutHeader = e => {
1420
+ _onLayoutHeader = (e: LayoutEvent) => {
1412
1421
  this._headerLength = this._selectLength(e.nativeEvent.layout);
1413
1422
  };
1414
1423
 
@@ -1419,7 +1428,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1419
1428
  const framesInLayout = [];
1420
1429
  const itemCount = this.props.getItemCount(this.props.data);
1421
1430
  for (let ii = 0; ii < itemCount; ii++) {
1422
- const frame = this._getFrameMetricsApprox(ii);
1431
+ const frame = this.__getFrameMetricsApprox(ii);
1423
1432
  /* $FlowFixMe[prop-missing] (>=0.68.0 site=react_native_fb) This comment
1424
1433
  * suppresses an error found when Flow v0.68 was deployed. To see the
1425
1434
  * error delete this comment and run Flow. */
@@ -1427,8 +1436,8 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1427
1436
  framesInLayout.push(frame);
1428
1437
  }
1429
1438
  }
1430
- const windowTop = this._getFrameMetricsApprox(this.state.first).offset;
1431
- const frameLast = this._getFrameMetricsApprox(this.state.last);
1439
+ const windowTop = this.__getFrameMetricsApprox(this.state.first).offset;
1440
+ const frameLast = this.__getFrameMetricsApprox(this.state.last);
1432
1441
  const windowLen = frameLast.offset + frameLast.length - windowTop;
1433
1442
  const visTop = this._scrollMetrics.offset;
1434
1443
  const visLen = this._scrollMetrics.visibleLength;
@@ -1642,7 +1651,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1642
1651
  // Mark as high priority if we're close to the start of the first item
1643
1652
  // But only if there are items before the first rendered item
1644
1653
  if (first > 0) {
1645
- const distTop = offset - this._getFrameMetricsApprox(first).offset;
1654
+ const distTop = offset - this.__getFrameMetricsApprox(first).offset;
1646
1655
  hiPri =
1647
1656
  hiPri || distTop < 0 || (velocity < -2 && distTop < scrollingThreshold);
1648
1657
  }
@@ -1650,7 +1659,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1650
1659
  // But only if there are items after the last rendered item
1651
1660
  if (last < itemCount - 1) {
1652
1661
  const distBottom =
1653
- this._getFrameMetricsApprox(last).offset - (offset + visibleLength);
1662
+ this.__getFrameMetricsApprox(last).offset - (offset + visibleLength);
1654
1663
  hiPri =
1655
1664
  hiPri ||
1656
1665
  distBottom < 0 ||
@@ -1733,7 +1742,10 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1733
1742
  return;
1734
1743
  }
1735
1744
  this.setState(state => {
1736
- let newState;
1745
+ let newState: ?(
1746
+ | {first: number, last: number, ...}
1747
+ | $TEMPORARY$object<{first: number, last: number}>
1748
+ );
1737
1749
  const {contentLength, offset, visibleLength} = this._scrollMetrics;
1738
1750
  if (!isVirtualizationDisabled) {
1739
1751
  // If we run this with bogus data, we'll force-render window {first: 0, last: 0},
@@ -1745,14 +1757,14 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1745
1757
  // we'll wipe out the initialNumToRender rendered elements starting at initialScrollIndex.
1746
1758
  // So let's wait until we've scrolled the view to the right place. And until then,
1747
1759
  // we will trust the initialScrollIndex suggestion.
1748
- if (!this.props.initialScrollIndex || this._scrollMetrics.offset) {
1760
+ if (!this.props.initialScrollIndex || this._hasDoneInitialScroll) {
1749
1761
  newState = computeWindowedRenderLimits(
1750
1762
  this.props.data,
1751
1763
  this.props.getItemCount,
1752
1764
  maxToRenderPerBatchOrDefault(this.props.maxToRenderPerBatch),
1753
1765
  windowSizeOrDefault(this.props.windowSize),
1754
1766
  state,
1755
- this._getFrameMetricsApprox,
1767
+ this.__getFrameMetricsApprox,
1756
1768
  this._scrollMetrics,
1757
1769
  );
1758
1770
  }
@@ -1815,13 +1827,11 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1815
1827
  return {index, item, key: this._keyExtractor(item, index), isViewable};
1816
1828
  };
1817
1829
 
1818
- _getFrameMetricsApprox = (
1819
- index: number,
1820
- ): {
1830
+ __getFrameMetricsApprox: (index: number) => {
1821
1831
  length: number,
1822
1832
  offset: number,
1823
1833
  ...
1824
- } => {
1834
+ } = index => {
1825
1835
  const frame = this._getFrameMetrics(index);
1826
1836
  if (frame && frame.index === index) {
1827
1837
  // check for invalid frames due to row re-ordering
@@ -1888,32 +1898,29 @@ type CellRendererProps = {
1888
1898
  ItemSeparatorComponent: ?React.ComponentType<
1889
1899
  any | {highlighted: boolean, leadingItem: ?Item},
1890
1900
  >,
1901
+ ListItemComponent?: ?(React.ComponentType<any> | React.Element<any>),
1891
1902
  cellKey: string,
1903
+ debug?: ?boolean,
1892
1904
  fillRateHelper: FillRateHelper,
1905
+ getItemLayout?: (
1906
+ data: any,
1907
+ index: number,
1908
+ ) => {
1909
+ length: number,
1910
+ offset: number,
1911
+ index: number,
1912
+ ...
1913
+ },
1893
1914
  horizontal: ?boolean,
1894
1915
  index: number,
1895
1916
  inversionStyle: ViewStyleProp,
1896
1917
  item: Item,
1897
1918
  // This is extracted by ScrollViewStickyHeader
1898
- onLayout: (event: Object) => void,
1919
+ onCellLayout: (event: Object, cellKey: string, index: number) => void,
1899
1920
  onUnmount: (cellKey: string) => void,
1900
1921
  onUpdateSeparators: (cellKeys: Array<?string>, props: Object) => void,
1901
- parentProps: {
1902
- // e.g. height, y,
1903
- getItemLayout?: (
1904
- data: any,
1905
- index: number,
1906
- ) => {
1907
- length: number,
1908
- offset: number,
1909
- index: number,
1910
- ...
1911
- },
1912
- renderItem?: ?RenderItemType<Item>,
1913
- ListItemComponent?: ?(React.ComponentType<any> | React.Element<any>),
1914
- ...
1915
- },
1916
1922
  prevCellKey: ?string,
1923
+ renderItem?: ?RenderItemType<Item>,
1917
1924
  ...
1918
1925
  };
1919
1926
 
@@ -1982,6 +1989,15 @@ class CellRenderer extends React.Component<
1982
1989
  this.props.onUnmount(this.props.cellKey);
1983
1990
  }
1984
1991
 
1992
+ _onLayout = (nativeEvent: LayoutEvent): void => {
1993
+ this.props.onCellLayout &&
1994
+ this.props.onCellLayout(
1995
+ nativeEvent,
1996
+ this.props.cellKey,
1997
+ this.props.index,
1998
+ );
1999
+ };
2000
+
1985
2001
  _renderElement(renderItem, ListItemComponent, item, index) {
1986
2002
  if (renderItem && ListItemComponent) {
1987
2003
  console.warn(
@@ -2022,14 +2038,16 @@ class CellRenderer extends React.Component<
2022
2038
  const {
2023
2039
  CellRendererComponent,
2024
2040
  ItemSeparatorComponent,
2041
+ ListItemComponent,
2042
+ debug,
2025
2043
  fillRateHelper,
2044
+ getItemLayout,
2026
2045
  horizontal,
2027
2046
  item,
2028
2047
  index,
2029
2048
  inversionStyle,
2030
- parentProps,
2049
+ renderItem,
2031
2050
  } = this.props;
2032
- const {renderItem, getItemLayout, ListItemComponent} = parentProps;
2033
2051
  const element = this._renderElement(
2034
2052
  renderItem,
2035
2053
  ListItemComponent,
@@ -2038,12 +2056,10 @@ class CellRenderer extends React.Component<
2038
2056
  );
2039
2057
 
2040
2058
  const onLayout =
2041
- /* $FlowFixMe[prop-missing] (>=0.68.0 site=react_native_fb) This comment
2042
- * suppresses an error found when Flow v0.68 was deployed. To see the
2043
- * error delete this comment and run Flow. */
2044
- getItemLayout && !parentProps.debug && !fillRateHelper.enabled()
2059
+ (getItemLayout && !debug && !fillRateHelper.enabled()) ||
2060
+ !this.props.onCellLayout
2045
2061
  ? undefined
2046
- : this.props.onLayout;
2062
+ : this._onLayout;
2047
2063
  // NOTE: that when this is a sticky header, `onLayout` will get automatically extracted and
2048
2064
  // called explicitly by `ScrollViewStickyHeader`.
2049
2065
  const itemSeparator = ItemSeparatorComponent && (
@@ -2096,7 +2112,7 @@ function describeNestedLists(childList: {
2096
2112
  ` listKey: ${childList.key}\n` +
2097
2113
  ` cellKey: ${childList.cellKey}`;
2098
2114
 
2099
- let debugInfo = childList.parentDebugInfo;
2115
+ let debugInfo: ?ListDebugInfo = childList.parentDebugInfo;
2100
2116
  while (debugInfo) {
2101
2117
  trace +=
2102
2118
  `\n Parent (${debugInfo.horizontal ? 'horizontal' : 'vertical'}):\n` +
@@ -142,10 +142,14 @@ export function VirtualizedListCellContextProvider({
142
142
  cellKey: string,
143
143
  children: React.Node,
144
144
  }): React.Node {
145
- const context = useContext(VirtualizedListContext);
145
+ // Avoid setting a newly created context object if the values are identical.
146
+ const currContext = useContext(VirtualizedListContext);
147
+ const context = useMemo(
148
+ () => (currContext == null ? null : {...currContext, cellKey}),
149
+ [currContext, cellKey],
150
+ );
146
151
  return (
147
- <VirtualizedListContext.Provider
148
- value={context == null ? null : {...context, cellKey}}>
152
+ <VirtualizedListContext.Provider value={context}>
149
153
  {children}
150
154
  </VirtualizedListContext.Provider>
151
155
  );
@@ -137,8 +137,7 @@ class VirtualizedSectionList<
137
137
  return;
138
138
  }
139
139
  if (params.itemIndex > 0 && this.props.stickySectionHeadersEnabled) {
140
- // $FlowFixMe[prop-missing] Cannot access private property
141
- const frame = this._listRef._getFrameMetricsApprox(
140
+ const frame = this._listRef.__getFrameMetricsApprox(
142
141
  index - params.itemIndex,
143
142
  );
144
143
  viewOffset += frame.length;
@@ -339,6 +338,7 @@ class VirtualizedSectionList<
339
338
 
340
339
  _renderItem =
341
340
  (listItemCount: number) =>
341
+ // eslint-disable-next-line react/no-unstable-nested-components
342
342
  ({item, index}: {item: Item, index: number, ...}) => {
343
343
  const info = this._subExtractor(index);
344
344
  if (!info) {
@@ -31,7 +31,7 @@ function computeResult({helper, props, state, scroll}): number {
31
31
  return helper.computeBlankness(
32
32
  {
33
33
  data: dataGlobal,
34
- getItemCount: (data2) => data2.length,
34
+ getItemCount: data2 => data2.length,
35
35
  initialNumToRender: 10,
36
36
  ...(props || {}),
37
37
  },
@@ -98,7 +98,7 @@ describe('computeBlankness', function () {
98
98
 
99
99
  it('can handle multiple listeners and unsubscribe', function () {
100
100
  const listeners = [jest.fn(), jest.fn(), jest.fn()];
101
- const subscriptions = listeners.map((listener) =>
101
+ const subscriptions = listeners.map(listener =>
102
102
  FillRateHelper.addListener(listener),
103
103
  );
104
104
  subscriptions[1].remove();
@@ -102,13 +102,13 @@ describe('FlatList', () => {
102
102
  ReactTestRenderer.create(
103
103
  <FlatList
104
104
  data={[{key: 'outer0'}, {key: 'outer1'}]}
105
- renderItem={(outerInfo) => (
105
+ renderItem={outerInfo => (
106
106
  <FlatList
107
107
  data={[
108
108
  {key: outerInfo.item.key + ':inner0'},
109
109
  {key: outerInfo.item.key + ':inner1'},
110
110
  ]}
111
- renderItem={(innerInfo) => {
111
+ renderItem={innerInfo => {
112
112
  return <item title={innerInfo.item.key} />;
113
113
  }}
114
114
  ref={listRef}
@@ -39,21 +39,21 @@ describe('SectionList', () => {
39
39
  const component = ReactTestRenderer.create(
40
40
  <SectionList
41
41
  initialNumToRender={Infinity}
42
- ItemSeparatorComponent={(props) => (
42
+ ItemSeparatorComponent={props => (
43
43
  <defaultItemSeparator v={propStr(props)} />
44
44
  )}
45
- ListEmptyComponent={(props) => <empty v={propStr(props)} />}
46
- ListFooterComponent={(props) => <footer v={propStr(props)} />}
47
- ListHeaderComponent={(props) => <header v={propStr(props)} />}
48
- SectionSeparatorComponent={(props) => (
45
+ ListEmptyComponent={props => <empty v={propStr(props)} />}
46
+ ListFooterComponent={props => <footer v={propStr(props)} />}
47
+ ListHeaderComponent={props => <header v={propStr(props)} />}
48
+ SectionSeparatorComponent={props => (
49
49
  <sectionSeparator v={propStr(props)} />
50
50
  )}
51
51
  sections={[
52
52
  {
53
- renderItem: (props) => <itemForSection1 v={propStr(props)} />,
53
+ renderItem: props => <itemForSection1 v={propStr(props)} />,
54
54
  key: 's1',
55
55
  keyExtractor: (item, index) => item.id,
56
- ItemSeparatorComponent: (props) => (
56
+ ItemSeparatorComponent: props => (
57
57
  <itemSeparatorForSection1 v={propStr(props)} />
58
58
  ),
59
59
  data: [{id: 'i1s1'}, {id: 'i2s1'}],
@@ -69,9 +69,9 @@ describe('SectionList', () => {
69
69
  ]}
70
70
  refreshing={false}
71
71
  onRefresh={jest.fn()}
72
- renderItem={(props) => <defaultItem v={propStr(props)} />}
73
- renderSectionHeader={(props) => <sectionHeader v={propStr(props)} />}
74
- renderSectionFooter={(props) => <sectionFooter v={propStr(props)} />}
72
+ renderItem={props => <defaultItem v={propStr(props)} />}
73
+ renderSectionHeader={props => <sectionHeader v={propStr(props)} />}
74
+ renderSectionFooter={props => <sectionFooter v={propStr(props)} />}
75
75
  />,
76
76
  );
77
77
  expect(component).toMatchSnapshot();
@@ -81,8 +81,8 @@ describe('SectionList', () => {
81
81
  <SectionList
82
82
  sections={[{key: 's1', data: []}]}
83
83
  renderItem={({item}) => <item v={item.key} />}
84
- renderSectionHeader={(props) => <sectionHeader v={propStr(props)} />}
85
- renderSectionFooter={(props) => <sectionFooter v={propStr(props)} />}
84
+ renderSectionHeader={props => <sectionHeader v={propStr(props)} />}
85
+ renderSectionFooter={props => <sectionFooter v={propStr(props)} />}
86
86
  />,
87
87
  );
88
88
  expect(component).toMatchSnapshot();
@@ -92,7 +92,7 @@ describe('SectionList', () => {
92
92
  <SectionList
93
93
  sections={[{key: 's1', data: []}]}
94
94
  renderItem={({item}) => <item v={item.key} />}
95
- renderSectionFooter={(props) => <sectionFooter v={propStr(props)} />}
95
+ renderSectionFooter={props => <sectionFooter v={propStr(props)} />}
96
96
  />,
97
97
  );
98
98
  expect(component).toMatchSnapshot();
@@ -101,7 +101,7 @@ describe('SectionList', () => {
101
101
 
102
102
  function propStr(props) {
103
103
  return Object.keys(props)
104
- .map((k) => {
104
+ .map(k => {
105
105
  const propObj = props[k] || {};
106
106
  return `${k}:${propObj.key || propObj.id || props[k]}`;
107
107
  })
@@ -62,7 +62,7 @@ describe('elementsThatOverlapOffsets', function () {
62
62
  {offset: 950, length: 150},
63
63
  ];
64
64
  expect(
65
- elementsThatOverlapOffsets(offsets, frames.length, (ii) => frames[ii]),
65
+ elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]),
66
66
  ).toEqual([1, 1, 3]);
67
67
  });
68
68
  it('handles out of bounds', function () {
@@ -73,7 +73,7 @@ describe('elementsThatOverlapOffsets', function () {
73
73
  {offset: 250, length: 100},
74
74
  ];
75
75
  expect(
76
- elementsThatOverlapOffsets(offsets, frames.length, (ii) => frames[ii]),
76
+ elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]),
77
77
  ).toEqual([1]);
78
78
  });
79
79
  it('errors on non-increasing offsets', function () {
@@ -84,7 +84,7 @@ describe('elementsThatOverlapOffsets', function () {
84
84
  {offset: 250, length: 100},
85
85
  ];
86
86
  expect(() => {
87
- elementsThatOverlapOffsets(offsets, frames.length, (ii) => frames[ii]);
87
+ elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]);
88
88
  }).toThrowErrorMatchingSnapshot();
89
89
  });
90
90
  });