@react-native/virtualized-lists 0.74.0 → 0.74.75

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.
@@ -11,6 +11,7 @@
11
11
  'use strict';
12
12
 
13
13
  import type {CellMetricProps} from './ListMetricsAggregator';
14
+
14
15
  import ListMetricsAggregator from './ListMetricsAggregator';
15
16
 
16
17
  export type FillRateInfo = Info;
@@ -8,10 +8,10 @@
8
8
  * @format
9
9
  */
10
10
 
11
- import type {Layout} from 'react-native/Libraries/Types/CoreEventTypes';
12
11
  import type {Props as VirtualizedListProps} from './VirtualizedListProps';
13
- import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
12
+ import type {Layout} from 'react-native/Libraries/Types/CoreEventTypes';
14
13
 
14
+ import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
15
15
  import invariant from 'invariant';
16
16
 
17
17
  export type CellMetrics = {
@@ -11,6 +11,7 @@
11
11
  'use strict';
12
12
 
13
13
  import type {CellMetricProps} from './ListMetricsAggregator';
14
+
14
15
  import ListMetricsAggregator from './ListMetricsAggregator';
15
16
 
16
17
  const invariant = require('invariant');
@@ -18,8 +18,8 @@ import type {
18
18
  ScrollView,
19
19
  } from 'react-native';
20
20
 
21
- export interface ViewToken {
22
- item: any;
21
+ export interface ViewToken<ItemT = any> {
22
+ item: ItemT;
23
23
  key: string;
24
24
  index: number | null;
25
25
  isViewable: boolean;
@@ -330,8 +330,8 @@ export interface VirtualizedListWithoutRenderItemProps<ItemT>
330
330
  */
331
331
  onViewableItemsChanged?:
332
332
  | ((info: {
333
- viewableItems: Array<ViewToken>;
334
- changed: Array<ViewToken>;
333
+ viewableItems: Array<ViewToken<ItemT>>;
334
+ changed: Array<ViewToken<ItemT>>;
335
335
  }) => void)
336
336
  | null
337
337
  | undefined;
@@ -8,12 +8,7 @@
8
8
  * @format
9
9
  */
10
10
 
11
- import type {ScrollResponderType} from 'react-native/Libraries/Components/ScrollView/ScrollView';
12
- import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
13
- import type {
14
- LayoutEvent,
15
- ScrollEvent,
16
- } from 'react-native/Libraries/Types/CoreEventTypes';
11
+ import type {CellMetricProps, ListOrientation} from './ListMetricsAggregator';
17
12
  import type {ViewToken} from './ViewabilityHelper';
18
13
  import type {
19
14
  Item,
@@ -22,17 +17,13 @@ import type {
22
17
  RenderItemType,
23
18
  Separators,
24
19
  } from './VirtualizedListProps';
25
- import type {CellMetricProps, ListOrientation} from './ListMetricsAggregator';
20
+ import type {ScrollResponderType} from 'react-native/Libraries/Components/ScrollView/ScrollView';
21
+ import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
22
+ import type {
23
+ LayoutEvent,
24
+ ScrollEvent,
25
+ } from 'react-native/Libraries/Types/CoreEventTypes';
26
26
 
27
- import {
28
- I18nManager,
29
- Platform,
30
- RefreshControl,
31
- ScrollView,
32
- View,
33
- StyleSheet,
34
- findNodeHandle,
35
- } from 'react-native';
36
27
  import Batchinator from '../Interaction/Batchinator';
37
28
  import clamp from '../Utilities/clamp';
38
29
  import infoLog from '../Utilities/infoLog';
@@ -48,6 +39,14 @@ import {
48
39
  VirtualizedListContext,
49
40
  VirtualizedListContextProvider,
50
41
  } from './VirtualizedListContext.js';
42
+ import {
43
+ horizontalOrDefault,
44
+ initialNumToRenderOrDefault,
45
+ maxToRenderPerBatchOrDefault,
46
+ onEndReachedThresholdOrDefault,
47
+ onStartReachedThresholdOrDefault,
48
+ windowSizeOrDefault,
49
+ } from './VirtualizedListProps';
51
50
  import {
52
51
  computeWindowedRenderLimits,
53
52
  keyExtractor as defaultKeyExtractor,
@@ -55,15 +54,15 @@ import {
55
54
  import invariant from 'invariant';
56
55
  import nullthrows from 'nullthrows';
57
56
  import * as React from 'react';
58
-
59
57
  import {
60
- horizontalOrDefault,
61
- initialNumToRenderOrDefault,
62
- maxToRenderPerBatchOrDefault,
63
- onStartReachedThresholdOrDefault,
64
- onEndReachedThresholdOrDefault,
65
- windowSizeOrDefault,
66
- } from './VirtualizedListProps';
58
+ I18nManager,
59
+ Platform,
60
+ RefreshControl,
61
+ ScrollView,
62
+ StyleSheet,
63
+ View,
64
+ findNodeHandle,
65
+ } from 'react-native';
67
66
 
68
67
  export type {RenderItemProps, RenderItemType, Separators};
69
68
 
@@ -91,19 +90,6 @@ type State = {
91
90
  pendingScrollUpdateCount: number,
92
91
  };
93
92
 
94
- function findLastWhere<T>(
95
- arr: $ReadOnlyArray<T>,
96
- predicate: (element: T) => boolean,
97
- ): T | null {
98
- for (let i = arr.length - 1; i >= 0; i--) {
99
- if (predicate(arr[i])) {
100
- return arr[i];
101
- }
102
- }
103
-
104
- return null;
105
- }
106
-
107
93
  function getScrollingThreshold(threshold: number, visibleLength: number) {
108
94
  return (threshold * visibleLength) / 2;
109
95
  }
@@ -825,7 +811,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
825
811
  key={key}
826
812
  prevCellKey={prevCellKey}
827
813
  onUpdateSeparators={this._onUpdateSeparators}
828
- onCellFocusCapture={e => this._onCellFocusCapture(key)}
814
+ onCellFocusCapture={this._onCellFocusCapture}
829
815
  onUnmount={this._onCellUnmount}
830
816
  ref={ref => {
831
817
  this._cellRefs[key] = ref;
@@ -969,10 +955,12 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
969
955
  {React.cloneElement(element, {
970
956
  onLayout: (event: LayoutEvent) => {
971
957
  this._onLayoutEmpty(event);
958
+ // $FlowFixMe[prop-missing] React.Element internal inspection
972
959
  if (element.props.onLayout) {
973
960
  element.props.onLayout(event);
974
961
  }
975
962
  },
963
+ // $FlowFixMe[prop-missing] React.Element internal inspection
976
964
  style: StyleSheet.compose(inversionStyle, element.props.style),
977
965
  })}
978
966
  </VirtualizedListCellContextProvider>,
@@ -986,7 +974,8 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
986
974
  const spacerKey = this._getSpacerKey(!horizontal);
987
975
 
988
976
  const renderRegions = this.state.renderMask.enumerateRegions();
989
- const lastSpacer = findLastWhere(renderRegions, r => r.isSpacer);
977
+ const lastRegion = renderRegions[renderRegions.length - 1];
978
+ const lastSpacer = lastRegion?.isSpacer ? lastRegion : null;
990
979
 
991
980
  for (const section of renderRegions) {
992
981
  if (section.isSpacer) {
@@ -1146,7 +1135,6 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1146
1135
  this.context == null &&
1147
1136
  this.props.scrollEnabled !== false
1148
1137
  ) {
1149
- // TODO (T46547044): use React.warn once 16.9 is sync'd: https://github.com/facebook/react/pull/15170
1150
1138
  console.error(
1151
1139
  'VirtualizedLists should never be nested inside plain ScrollViews with the same ' +
1152
1140
  'orientation because it can break windowing and other functionality - use another ' +
@@ -1255,8 +1243,10 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1255
1243
  _defaultRenderScrollComponent = props => {
1256
1244
  const onRefresh = props.onRefresh;
1257
1245
  if (this._isNestedWithSameOrientation()) {
1258
- // $FlowFixMe[prop-missing] - Typing ReactNativeComponent revealed errors
1259
- return <View {...props} />;
1246
+ // Prevent VirtualizedList._onContentSizeChange from being triggered by a bubbling onContentSizeChange event.
1247
+ // This could lead to internal inconsistencies within VirtualizedList.
1248
+ const {onContentSizeChange, ...otherProps} = props;
1249
+ return <View {...otherProps} />;
1260
1250
  } else if (onRefresh) {
1261
1251
  invariant(
1262
1252
  typeof props.refreshing === 'boolean',
@@ -1311,10 +1301,10 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1311
1301
  this._updateViewableItems(this.props, this.state.cellsAroundViewport);
1312
1302
  };
1313
1303
 
1314
- _onCellFocusCapture(cellKey: string) {
1304
+ _onCellFocusCapture = (cellKey: string) => {
1315
1305
  this._lastFocusedCellKey = cellKey;
1316
1306
  this._updateCellsToRender();
1317
- }
1307
+ };
1318
1308
 
1319
1309
  _onCellUnmount = (cellKey: string) => {
1320
1310
  delete this._cellRefs[cellKey];
@@ -1558,7 +1548,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1558
1548
  // Next check if the user just scrolled within the start threshold
1559
1549
  // and call onStartReached only once for a given content length,
1560
1550
  // and only if onEndReached is not being executed
1561
- else if (
1551
+ if (
1562
1552
  onStartReached != null &&
1563
1553
  this.state.cellsAroundViewport.first === 0 &&
1564
1554
  isWithinStartThreshold &&
@@ -1570,13 +1560,11 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1570
1560
 
1571
1561
  // If the user scrolls away from the start or end and back again,
1572
1562
  // cause onStartReached or onEndReached to be triggered again
1573
- else {
1574
- this._sentStartForContentLength = isWithinStartThreshold
1575
- ? this._sentStartForContentLength
1576
- : 0;
1577
- this._sentEndForContentLength = isWithinEndThreshold
1578
- ? this._sentEndForContentLength
1579
- : 0;
1563
+ if (!isWithinStartThreshold) {
1564
+ this._sentStartForContentLength = 0;
1565
+ }
1566
+ if (!isWithinEndThreshold) {
1567
+ this._sentEndForContentLength = 0;
1580
1568
  }
1581
1569
  }
1582
1570
 
@@ -1748,8 +1736,9 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1748
1736
  // If this is triggered in an `componentDidUpdate` followed by a hiPri cellToRenderUpdate
1749
1737
  // We shouldn't do another hipri cellToRenderUpdate
1750
1738
  if (
1739
+ (this._listMetrics.getAverageCellLength() > 0 ||
1740
+ this.props.getItemLayout != null) &&
1751
1741
  this._shouldRenderWithPriority() &&
1752
- (this._listMetrics.getAverageCellLength() || this.props.getItemLayout) &&
1753
1742
  !this._hiPriInProgress
1754
1743
  ) {
1755
1744
  this._hiPriInProgress = true;
@@ -8,17 +8,17 @@
8
8
  * @format
9
9
  */
10
10
 
11
+ import type {CellRendererProps, RenderItemType} from './VirtualizedListProps';
11
12
  import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
12
13
  import type {
13
14
  FocusEvent,
14
15
  LayoutEvent,
15
16
  } from 'react-native/Libraries/Types/CoreEventTypes';
16
- import type {CellRendererProps, RenderItemType} from './VirtualizedListProps';
17
17
 
18
- import {View, StyleSheet} from 'react-native';
19
18
  import {VirtualizedListCellContextProvider} from './VirtualizedListContext.js';
20
19
  import invariant from 'invariant';
21
20
  import * as React from 'react';
21
+ import {StyleSheet, View} from 'react-native';
22
22
 
23
23
  export type Props<ItemT> = {
24
24
  CellRendererComponent?: ?React.ComponentType<CellRendererProps<ItemT>>,
@@ -32,7 +32,7 @@ export type Props<ItemT> = {
32
32
  inversionStyle: ViewStyleProp,
33
33
  item: ItemT,
34
34
  onCellLayout?: (event: LayoutEvent, cellKey: string, index: number) => void,
35
- onCellFocusCapture?: (event: FocusEvent) => void,
35
+ onCellFocusCapture?: (cellKey: string) => void,
36
36
  onUnmount: (cellKey: string) => void,
37
37
  onUpdateSeparators: (
38
38
  cellKeys: Array<?string>,
@@ -115,12 +115,15 @@ export default class CellRenderer<ItemT> extends React.Component<
115
115
  }
116
116
 
117
117
  _onLayout = (nativeEvent: LayoutEvent): void => {
118
- this.props.onCellLayout &&
119
- this.props.onCellLayout(
120
- nativeEvent,
121
- this.props.cellKey,
122
- this.props.index,
123
- );
118
+ this.props.onCellLayout?.(
119
+ nativeEvent,
120
+ this.props.cellKey,
121
+ this.props.index,
122
+ );
123
+ };
124
+
125
+ _onCellFocusCapture = (e: FocusEvent): void => {
126
+ this.props.onCellFocusCapture?.(this.props.cellKey);
124
127
  };
125
128
 
126
129
  _renderElement(
@@ -174,7 +177,6 @@ export default class CellRenderer<ItemT> extends React.Component<
174
177
  item,
175
178
  index,
176
179
  inversionStyle,
177
- onCellFocusCapture,
178
180
  onCellLayout,
179
181
  renderItem,
180
182
  } = this.props;
@@ -206,7 +208,7 @@ export default class CellRenderer<ItemT> extends React.Component<
206
208
  const result = !CellRendererComponent ? (
207
209
  <View
208
210
  style={cellStyle}
209
- onFocusCapture={onCellFocusCapture}
211
+ onFocusCapture={this._onCellFocusCapture}
210
212
  {...(onCellLayout && {onLayout: this._onLayout})}>
211
213
  {element}
212
214
  {itemSeparator}
@@ -217,7 +219,7 @@ export default class CellRenderer<ItemT> extends React.Component<
217
219
  index={index}
218
220
  item={item}
219
221
  style={cellStyle}
220
- onFocusCapture={onCellFocusCapture}
222
+ onFocusCapture={this._onCellFocusCapture}
221
223
  {...(onCellLayout && {onLayout: this._onLayout})}>
222
224
  {element}
223
225
  {itemSeparator}
@@ -8,19 +8,19 @@
8
8
  * @format
9
9
  */
10
10
 
11
- import {typeof ScrollView} from 'react-native';
12
- import type {
13
- FocusEvent,
14
- LayoutEvent,
15
- } from 'react-native/Libraries/Types/CoreEventTypes';
16
- import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
17
11
  import type {
18
12
  ViewabilityConfig,
19
13
  ViewabilityConfigCallbackPair,
20
14
  ViewToken,
21
15
  } from './ViewabilityHelper';
16
+ import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
17
+ import type {
18
+ FocusEvent,
19
+ LayoutEvent,
20
+ } from 'react-native/Libraries/Types/CoreEventTypes';
22
21
 
23
22
  import * as React from 'react';
23
+ import {typeof ScrollView} from 'react-native';
24
24
 
25
25
  export type Item = any;
26
26
 
@@ -10,11 +10,11 @@
10
10
 
11
11
  import type {ViewToken} from './ViewabilityHelper';
12
12
 
13
- import {View} from 'react-native';
14
13
  import VirtualizedList from './VirtualizedList';
15
14
  import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
16
15
  import invariant from 'invariant';
17
16
  import * as React from 'react';
17
+ import {View} from 'react-native';
18
18
 
19
19
  type Item = any;
20
20
 
package/index.js CHANGED
@@ -10,13 +10,13 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- import {keyExtractor} from './Lists/VirtualizeUtils';
14
-
13
+ import typeof FillRateHelper from './Lists/FillRateHelper';
14
+ import typeof ViewabilityHelper from './Lists/ViewabilityHelper';
15
15
  import typeof VirtualizedList from './Lists/VirtualizedList';
16
16
  import typeof VirtualizedSectionList from './Lists/VirtualizedSectionList';
17
+
17
18
  import {typeof VirtualizedListContextResetter} from './Lists/VirtualizedListContext';
18
- import typeof ViewabilityHelper from './Lists/ViewabilityHelper';
19
- import typeof FillRateHelper from './Lists/FillRateHelper';
19
+ import {keyExtractor} from './Lists/VirtualizeUtils';
20
20
 
21
21
  export type {
22
22
  ViewToken,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/virtualized-lists",
3
- "version": "0.74.0",
3
+ "version": "0.74.75",
4
4
  "description": "Virtualized lists for React Native.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,6 +27,7 @@
27
27
  "react-test-renderer": "18.2.0"
28
28
  },
29
29
  "peerDependencies": {
30
+ "react": "*",
30
31
  "react-native": "*"
31
32
  }
32
33
  }