Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions packages/virtualized-lists/Lists/ListMetricsAggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type CellMetrics = {
// based implementation instead of transform.
export type ListOrientation = {
horizontal: boolean,
reversed: boolean,
rtl: boolean,
};

Expand Down Expand Up @@ -66,6 +67,7 @@ export default class ListMetricsAggregator {
_orientation: ListOrientation = {
horizontal: false,
rtl: false,
reversed: false,
};

/**
Expand Down Expand Up @@ -268,9 +270,9 @@ export default class ListMetricsAggregator {
layout: LayoutRectangle,
referenceContentLength?: ?number,
): number {
const {horizontal, rtl} = this._orientation;
const {horizontal, reversed, rtl} = this._orientation;

if (horizontal && rtl) {
if ((horizontal && rtl) || reversed) {
const contentLength = referenceContentLength ?? this._contentLength;
invariant(
contentLength != null,
Expand All @@ -289,9 +291,9 @@ export default class ListMetricsAggregator {
* Converts a flow-relative offset to a cartesian offset
*/
cartesianOffset(flowRelativeOffset: number): number {
const {horizontal, rtl} = this._orientation;
const {horizontal, reversed, rtl} = this._orientation;

if (horizontal && rtl) {
if ((horizontal && rtl) || reversed) {
invariant(
this._contentLength != null,
'ListMetricsAggregator must be notified of list content layout before resolving offsets',
Expand All @@ -314,6 +316,14 @@ export default class ListMetricsAggregator {
this._measuredCellsCount = 0;
}

if (orientation.reversed !== this._orientation.reversed) {
this._cellMetrics.clear();
this._averageCellLength = 0;
this._highestMeasuredCellIndex = 0;
this._measuredCellsLength = 0;
this._measuredCellsCount = 0;
}

this._orientation = orientation;
}

Expand Down
29 changes: 21 additions & 8 deletions packages/virtualized-lists/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,14 @@ class VirtualizedList extends StateSafePureComponent<
return;
}

const {horizontal, rtl} = this._orientation();
if (horizontal && rtl && !this._listMetrics.hasContentLength()) {
const {horizontal, reversed, rtl} = this._orientation();
if (
((horizontal && rtl) || reversed) &&
!this._listMetrics.hasContentLength()
) {
const mode = horizontal && rtl ? 'RTL' : 'reversed lists';
console.warn(
'scrollToOffset may not be called in RTL before content is laid out',
`scrollToOffset may not be called in ${mode} before content is laid out`,
);
return;
}
Expand All @@ -270,8 +274,8 @@ class VirtualizedList extends StateSafePureComponent<
}

_scrollToParamsFromOffset(offset: number): {x?: number, y?: number} {
const {horizontal, rtl} = this._orientation();
if (horizontal && rtl) {
const {horizontal, reversed, rtl} = this._orientation();
if ((horizontal && rtl) || reversed) {
// Add the visible length of the scrollview so that the offset is right-aligned
const cartOffset = this._listMetrics.cartesianOffset(
offset + this._scrollMetrics.visibleLength,
Expand Down Expand Up @@ -1491,8 +1495,17 @@ class VirtualizedList extends StateSafePureComponent<
}

_orientation(): ListOrientation {
const horizontal = horizontalOrDefault(this.props.horizontal);
const contentFlexDirection = StyleSheet.flatten(
this.props.contentContainerStyle,
)?.flexDirection;
const reversed =
(horizontal && contentFlexDirection === 'row-reverse') ||
contentFlexDirection === 'column-reverse';

return {
horizontal: horizontalOrDefault(this.props.horizontal),
horizontal,
reversed,
rtl: I18nManager.isRTL,
};
}
Expand Down Expand Up @@ -1737,8 +1750,8 @@ class VirtualizedList extends StateSafePureComponent<

_offsetFromScrollEvent(e: ScrollEvent): number {
const {contentOffset, contentSize, layoutMeasurement} = e.nativeEvent;
const {horizontal, rtl} = this._orientation();
if (horizontal && rtl) {
const {horizontal, reversed, rtl} = this._orientation();
if ((horizontal && rtl) || reversed) {
return (
this._selectLength(contentSize) -
(this._selectOffset(contentOffset) +
Expand Down
Loading