@react-native/virtualized-lists 0.73.1 → 0.73.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.
@@ -14,8 +14,6 @@ import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
14
14
 
15
15
  import invariant from 'invariant';
16
16
 
17
- type LayoutEventDirection = 'top-down' | 'bottom-up';
18
-
19
17
  export type CellMetrics = {
20
18
  /**
21
19
  * Index of the item in the list
@@ -55,25 +53,12 @@ export type CellMetricProps = {
55
53
  ...
56
54
  };
57
55
 
58
- type UnresolvedCellMetrics = {
59
- index: number,
60
- layout: Layout,
61
- isMounted: boolean,
62
-
63
- // The length of list content at the time of layout is needed to correctly
64
- // resolve flow relative offset in RTL. We are lazily notified of this after
65
- // the layout of the cell, unless the cell relayout does not cause a length
66
- // change. To keep stability, we use content length at time of query, or
67
- // unmount if never queried.
68
- listContentLength?: ?number,
69
- };
70
-
71
56
  /**
72
57
  * Provides an interface to query information about the metrics of a list and its cells.
73
58
  */
74
59
  export default class ListMetricsAggregator {
75
60
  _averageCellLength = 0;
76
- _cellMetrics: Map<string, UnresolvedCellMetrics> = new Map();
61
+ _cellMetrics: Map<string, CellMetrics> = new Map();
77
62
  _contentLength: ?number;
78
63
  _highestMeasuredCellIndex = 0;
79
64
  _measuredCellsLength = 0;
@@ -83,10 +68,6 @@ export default class ListMetricsAggregator {
83
68
  rtl: false,
84
69
  };
85
70
 
86
- // Fabric and Paper may call onLayout in different orders. We can tell which
87
- // direction layout events happen on the first layout.
88
- _onLayoutDirection: LayoutEventDirection = 'top-down';
89
-
90
71
  /**
91
72
  * Notify the ListMetricsAggregator that a cell has been laid out.
92
73
  *
@@ -103,39 +84,22 @@ export default class ListMetricsAggregator {
103
84
  orientation: ListOrientation,
104
85
  layout: Layout,
105
86
  }): boolean {
106
- if (this._contentLength == null) {
107
- this._onLayoutDirection = 'bottom-up';
108
- }
109
-
110
87
  this._invalidateIfOrientationChanged(orientation);
111
88
 
112
- // If layout is top-down, our most recently cached content length
113
- // corresponds to this cell. Otherwise, we need to resolve when events fire
114
- // up the tree to the new length.
115
- const listContentLength =
116
- this._onLayoutDirection === 'top-down' ? this._contentLength : null;
117
-
118
- const next: UnresolvedCellMetrics = {
89
+ const next: CellMetrics = {
119
90
  index: cellIndex,
120
- layout: layout,
91
+ length: this._selectLength(layout),
121
92
  isMounted: true,
122
- listContentLength,
93
+ offset: this.flowRelativeOffset(layout),
123
94
  };
124
95
  const curr = this._cellMetrics.get(cellKey);
125
96
 
126
- if (
127
- !curr ||
128
- this._selectOffset(next.layout) !== this._selectOffset(curr.layout) ||
129
- this._selectLength(next.layout) !== this._selectLength(curr.layout) ||
130
- (curr.listContentLength != null &&
131
- curr.listContentLength !== this._contentLength)
132
- ) {
97
+ if (!curr || next.offset !== curr.offset || next.length !== curr.length) {
133
98
  if (curr) {
134
- const dLength =
135
- this._selectLength(next.layout) - this._selectLength(curr.layout);
99
+ const dLength = next.length - curr.length;
136
100
  this._measuredCellsLength += dLength;
137
101
  } else {
138
- this._measuredCellsLength += this._selectLength(next.layout);
102
+ this._measuredCellsLength += next.length;
139
103
  this._measuredCellsCount += 1;
140
104
  }
141
105
 
@@ -174,21 +138,7 @@ export default class ListMetricsAggregator {
174
138
  layout: $ReadOnly<{width: number, height: number}>,
175
139
  }): void {
176
140
  this._invalidateIfOrientationChanged(orientation);
177
- const newLength = this._selectLength(layout);
178
-
179
- // Fill in any just-measured cells which did not have this length available.
180
- // This logic assumes that cell relayout will always change list content
181
- // size, which isn't strictly correct, but issues should be rare and only
182
- // on Paper.
183
- if (this._onLayoutDirection === 'bottom-up') {
184
- for (const cellMetric of this._cellMetrics.values()) {
185
- if (cellMetric.listContentLength == null) {
186
- cellMetric.listContentLength = newLength;
187
- }
188
- }
189
- }
190
-
191
- this._contentLength = newLength;
141
+ this._contentLength = this._selectLength(layout);
192
142
  }
193
143
 
194
144
  /**
@@ -245,7 +195,7 @@ export default class ListMetricsAggregator {
245
195
  keyExtractor(getItem(data, index), index),
246
196
  );
247
197
  if (frame && frame.index === index) {
248
- return this._resolveCellMetrics(frame);
198
+ return frame;
249
199
  }
250
200
 
251
201
  if (getItemLayout) {
@@ -286,26 +236,6 @@ export default class ListMetricsAggregator {
286
236
  return this._contentLength != null;
287
237
  }
288
238
 
289
- /**
290
- * Whether the ListMetricsAggregator is notified of cell metrics before
291
- * ScrollView metrics (bottom-up) or ScrollView metrics before cell metrics
292
- * (top-down).
293
- *
294
- * Must be queried after cell layout
295
- */
296
- getLayoutEventDirection(): LayoutEventDirection {
297
- return this._onLayoutDirection;
298
- }
299
-
300
- /**
301
- * Whether the ListMetricsAggregator must be aware of the current length of
302
- * ScrollView content to be able to correctly resolve the (flow-relative)
303
- * metrics of a cell.
304
- */
305
- needsContentLengthForCellMetrics(): boolean {
306
- return this._orientation.horizontal && this._orientation.rtl;
307
- }
308
-
309
239
  /**
310
240
  * Finds the flow-relative offset (e.g. starting from the left in LTR, but
311
241
  * right in RTL) from a layout box.
@@ -352,7 +282,6 @@ export default class ListMetricsAggregator {
352
282
 
353
283
  if (orientation.horizontal !== this._orientation.horizontal) {
354
284
  this._averageCellLength = 0;
355
- this._contentLength = null;
356
285
  this._highestMeasuredCellIndex = 0;
357
286
  this._measuredCellsLength = 0;
358
287
  this._measuredCellsCount = 0;
@@ -371,15 +300,4 @@ export default class ListMetricsAggregator {
371
300
  _selectOffset({x, y}: $ReadOnly<{x: number, y: number, ...}>): number {
372
301
  return this._orientation.horizontal ? x : y;
373
302
  }
374
-
375
- _resolveCellMetrics(metrics: UnresolvedCellMetrics): CellMetrics {
376
- const {index, layout, isMounted, listContentLength} = metrics;
377
-
378
- return {
379
- index,
380
- length: this._selectLength(layout),
381
- isMounted,
382
- offset: this.flowRelativeOffset(layout, listContentLength),
383
- };
384
- }
385
303
  }
@@ -1302,39 +1302,13 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1302
1302
  orientation: this._orientation(),
1303
1303
  });
1304
1304
 
1305
- // In RTL layout we need parent content length to calculate the offset of a
1306
- // cell from the start of the list. In Paper, layout events are bottom up,
1307
- // so we do not know this yet, and must defer calculation until after
1308
- // `onContentSizeChange` is called.
1309
- const deferCellMetricCalculation =
1310
- this._listMetrics.getLayoutEventDirection() === 'bottom-up' &&
1311
- this._listMetrics.needsContentLengthForCellMetrics();
1312
-
1313
- // Note: In Paper RTL logical position may have changed when
1314
- // `layoutHasChanged` is false if a cell maintains same X/Y coordinates,
1315
- // but contentLength shifts. This will be corrected by
1316
- // `onContentSizeChange` triggering a cell update.
1317
1305
  if (layoutHasChanged) {
1318
- this._scheduleCellsToRenderUpdate({
1319
- allowImmediateExecution: !deferCellMetricCalculation,
1320
- });
1306
+ this._scheduleCellsToRenderUpdate();
1321
1307
  }
1322
1308
 
1323
1309
  this._triggerRemeasureForChildListsInCell(cellKey);
1324
-
1325
1310
  this._computeBlankness();
1326
-
1327
- if (deferCellMetricCalculation) {
1328
- if (!this._pendingViewabilityUpdate) {
1329
- this._pendingViewabilityUpdate = true;
1330
- setTimeout(() => {
1331
- this._updateViewableItems(this.props, this.state.cellsAroundViewport);
1332
- this._pendingViewabilityUpdate = false;
1333
- }, 0);
1334
- }
1335
- } else {
1336
- this._updateViewableItems(this.props, this.state.cellsAroundViewport);
1337
- }
1311
+ this._updateViewableItems(this.props, this.state.cellsAroundViewport);
1338
1312
  };
1339
1313
 
1340
1314
  _onCellFocusCapture(cellKey: string) {
@@ -1765,9 +1739,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1765
1739
  }
1766
1740
  }
1767
1741
 
1768
- _scheduleCellsToRenderUpdate(opts?: {allowImmediateExecution?: boolean}) {
1769
- const allowImmediateExecution = opts?.allowImmediateExecution ?? true;
1770
-
1742
+ _scheduleCellsToRenderUpdate() {
1771
1743
  // Only trigger high-priority updates if we've actually rendered cells,
1772
1744
  // and with that size estimate, accurately compute how many cells we should render.
1773
1745
  // Otherwise, it would just render as many cells as it can (of zero dimension),
@@ -1776,9 +1748,9 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
1776
1748
  // If this is triggered in an `componentDidUpdate` followed by a hiPri cellToRenderUpdate
1777
1749
  // We shouldn't do another hipri cellToRenderUpdate
1778
1750
  if (
1779
- allowImmediateExecution &&
1751
+ (this._listMetrics.getAverageCellLength() > 0 ||
1752
+ this.props.getItemLayout != null) &&
1780
1753
  this._shouldRenderWithPriority() &&
1781
- (this._listMetrics.getAverageCellLength() || this.props.getItemLayout) &&
1782
1754
  !this._hiPriInProgress
1783
1755
  ) {
1784
1756
  this._hiPriInProgress = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/virtualized-lists",
3
- "version": "0.73.1",
3
+ "version": "0.73.3",
4
4
  "description": "Virtualized lists for React Native.",
5
5
  "license": "MIT",
6
6
  "repository": {