@react-native/virtualized-lists 0.74.0 → 0.74.1
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.
- package/Lists/FillRateHelper.js +1 -0
- package/Lists/ListMetricsAggregator.js +2 -2
- package/Lists/ViewabilityHelper.js +1 -0
- package/Lists/VirtualizedList.d.ts +4 -4
- package/Lists/VirtualizedList.js +42 -53
- package/Lists/VirtualizedListCellRenderer.js +14 -12
- package/Lists/VirtualizedListProps.js +6 -6
- package/Lists/VirtualizedSectionList.js +1 -1
- package/index.js +4 -4
- package/package.json +2 -1
package/Lists/FillRateHelper.js
CHANGED
|
@@ -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 {
|
|
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 = {
|
|
@@ -18,8 +18,8 @@ import type {
|
|
|
18
18
|
ScrollView,
|
|
19
19
|
} from 'react-native';
|
|
20
20
|
|
|
21
|
-
export interface ViewToken {
|
|
22
|
-
item:
|
|
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;
|
package/Lists/VirtualizedList.js
CHANGED
|
@@ -8,12 +8,7 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {
|
|
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 {
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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={
|
|
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
|
|
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
|
-
//
|
|
1259
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1574
|
-
this._sentStartForContentLength =
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
this._sentEndForContentLength =
|
|
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?: (
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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={
|
|
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={
|
|
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
|
|
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
|
|
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.
|
|
3
|
+
"version": "0.74.1",
|
|
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
|
}
|