Commit Graph
365 Commits
Author SHA1 Message Date
Nick Gerleman 7aa203beda Attempt fix for cellsAroundViewport reaching out of bounds
Summary: VirtualizedList would more gracefully handle out of range cells than VirtualizedList_EXPERIMENTAL, which treats it as an invariant violation. This attempts to fix an issue where recalculation of cells around viewport can include out of range cells.

Reviewed By: rshest

Differential Revision: D39244112

fbshipit-source-id: 20fe6ea552035061d9d00720fcab77b29a785771
2022-09-05 11:45:12 -07:00
Pieter Vanderwerff 3db19b464d Deploy 0.186.0 to xplat
Summary: Changelog: [Internal]

Reviewed By: SamChou19815

Differential Revision: D39185318

fbshipit-source-id: ca154a5c43eef3e30d5eab382947eedf30e9e850
2022-08-31 16:05:55 -07:00
Tim Yung 459b25ce43 RN: Minor Flow Cleanup in FlatList
Summary:
Cleans up a few minor Flow suppression comments in `FlatList`. This reveals a new Flow error that is the result of `FlatList`'s props object being inexact whereas `VirtualizedList`'s props object is exact. For now, I introduce another -- but more specific -- Flow suppression for that type error.

The code changes should not have any consequential behavior change.

Changelog:
[Internal]

Reviewed By: NickGerleman

Differential Revision: D38646228

fbshipit-source-id: f4f9b0ad95323157ff1519353b38e8486adc841d
2022-08-12 17:16:40 -07:00
Genki Kondo 3f8071d638 Back out "TalkBack support for ScrollView accessibility announcements (list and grid) - Javascript Only Changes"
Summary:
Original commit changeset: 7ba4068405fd

Original Phabricator Diff: D37668064 (https://github.com/facebook/react-native/commit/463af237539b98289c88e5b491c85cbf53bcaf0c)

D37668064 (https://github.com/facebook/react-native/commit/463af237539b98289c88e5b491c85cbf53bcaf0c) caused issues in VR Store where on tail load, the scroll position would reset and go back to the top.

Changelog:
[Android][Removed] - Backing out "Accessibility announcement for list and grid in FlatList"

Reviewed By: mullender

Differential Revision: D38473805

fbshipit-source-id: f454c15ca0d31294a44f5fd3f6b73e658ca4f00d
2022-08-05 17:58:41 -07:00
Nick Gerleman 051a67784f VirtualizedList up-to-date state: Enforce correct setState() usage
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

This adds a `StateSafePureComponent`, which will override `setState`, along with `this.props` and `this.state`, in order to add runtime enforcement that `this.props` and `this.state` are not accessed during a state update where we should be relying on parameter instead. This should be landed after the fixes for unsafe `this.props`/`this.state` usage.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Changed] - Enable setState() hooks

Reviewed By: rshest

Differential Revision: D38294338

fbshipit-source-id: d04ff39f68df90adc9f4680887d308d997903675
2022-08-05 07:44:13 -07:00
Pieter Vanderwerff 0ccbe5f704 Add missing class annotations and lock xplat/js
Reviewed By: SamChou19815

Differential Revision: D38374141

fbshipit-source-id: 967291a5c1a29f39b7272726c8b41bc74d1be043
2022-08-03 17:45:53 -07:00
Pieter Vanderwerff ee3d3c248d Add missing class annotations xplat/js
Reviewed By: SamChou19815

Differential Revision: D38373443

fbshipit-source-id: 1222c4845ebd6b72bd6f54af1a27cf8542dd883a
2022-08-03 12:43:58 -07:00
fabriziobertoglio1987 463af23753 TalkBack support for ScrollView accessibility announcements (list and grid) - Javascript Only Changes (#33180)
Summary:
This is the Javascript-only changes from D34518929 (https://github.com/facebook/react-native/commit/dd6325bafe1a539d348f3710e717a6344576b859), split out for push safety. Original summary and test plan below:

This issue fixes [30977][17] . The Pull Request was previously published by [intergalacticspacehighway][13] with [31666][19].
The solution consists of:
1. Adding Javascript logic in the [FlatList][14], SectionList, VirtualizedList components to provide accessibility information (row and column position) for each cell in the method [renderItem][20] as a fourth parameter [accessibilityCollectionItem][21]. The information is saved on the native side in the AccessibilityNodeInfo and announced by TalkBack when changing row, column, or page ([video example][12]). The prop accessibilityCollectionItem is available in the View component which wraps each FlatList cell.
2. Adding Java logic in [ReactScrollView.java][16] and HorizontalScrollView to announce pages with TalkBack when scrolling up/down. The missing AOSP logic in [ScrollView.java][10] (see also the [GridView][11] example) is responsible for announcing Page Scrolling with TalkBack.

Relevant Links:
x [Additional notes on this PR][18]
x [discussion on the additional container View around each FlatList cell][22]
x [commit adding prop getCellsInItemCount to VirtualizedList][23]

## Changelog

[Android] [Added] - Accessibility announcement for list and grid in FlatList

Pull Request resolved: https://github.com/facebook/react-native/pull/33180

Test Plan:
[1]. TalkBack announces pages and cells with Horizontal Flatlist in the Paper Renderer ([link][1])
[2]. TalkBack announces pages and cells with Vertical Flatlist in the Paper Renderer ([link][2])
[3]. `FlatList numColumns={undefined}` Should not trigger Runtime Error NoSuchKey exception columnCount when enabling TalkBack. ([link][3])
[4]. TalkBack announces pages and cells with Nested Horizontal Flatlist in the rn-tester app ([link][4])

[1]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050452894
[2]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050462465
[3]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1032340879
[4]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050618308
[10]:https://github.com/aosp-mirror/platform_frameworks_base/blob/1ac46f932ef88a8f96d652580d8105e361ffc842/core/java/android/widget/AdapterView.java#L1027-L1029 "GridView.java method responsible for calling setFromIndex and setToIndex"
[11]:https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1042518901 "test case on Android GridView"
[12]:https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050452894 "TalkBack announces pages and cells with Horizontal Flatlist in the Paper Renderer"
[13]:https://github.com/intergalacticspacehighway "github intergalacticspacehighway"
[14]:https://github.com/fabriziobertoglio1987/react-native/blob/80acf523a4410adac8005d5c9472fb87f78e12ee/Libraries/Lists/FlatList.js#L617-L636 "FlatList accessibilityCollectionItem"
[16]:https://github.com/fabriziobertoglio1987/react-native/blob/5706bd7d3ee35dca48f85322a2bdcaec0bce2c85/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L183-L184 "logic added to ReactScrollView.java"
[17]: https://github.com/facebook/react-native/issues/30977
[18]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6
[19]: https://github.com/facebook/react-native/pull/31666
[20]: https://reactnative.dev/docs/next/flatlist#required-renderitem "FlatList renderItem documentation"
[21]: https://github.com/fabriziobertoglio1987/react-native/commit/75147359c5d070406ebbe488c57c3cd94c08c19d "commit that introduces fourth param accessibilityCollectionItem in callback renderItem"
[22]: https://github.com/facebook/react-native/pull/33180#discussion_r826748664 "discussion on the additional container View around each FlatList cell"
[23]: https://github.com/fabriziobertoglio1987/react-native/commit/d50fd1a68112f40f4be3ac3aa4d67f96df33e387 "commit adding prop getCellsInItemCount to VirtualizedList"

Reviewed By: lunaleaps

Differential Revision: D37668064

Pulled By: blavalla

fbshipit-source-id: 7ba4068405fdcb9823d0daed2d8c36f0a56dbf0f
2022-08-02 19:49:05 -07:00
Antoine Doubovetzky cc19cdcdbe Fix/flat list not calling render items for nullish values when numColumns > 1 (#34205)
Summary:
Fixes https://github.com/facebook/react-native/issues/34034.

The FlatList doesn't call renderItem on nullish values when numColumns > 1, but it does when numColumns is not set (or equals 1).
I think the behavior should be consistent, so I updated the code so renderItems is called for every items.

I believe the condition `item != null` was here to make sure renderItem isn't called for index outside of data range, so I replaced it with `itemIndex < data.length`.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[General] [Fixed] - Fix FlatList not calling render items for nullish values when numColumns > 1

Pull Request resolved: https://github.com/facebook/react-native/pull/34205

Test Plan:
- I added a failing test corresponding to the issue, and the test now succeeds.
- I used the same code as in the test on a newly initialized app on RN 0.69 and made sure renderItem was called for every items as expected.

Reviewed By: NickGerleman

Differential Revision: D38185103

Pulled By: lunaleaps

fbshipit-source-id: 4baa55caef9574c91c43c047f9e419016ceb39db
2022-08-02 18:11:24 -07:00
Nick Gerleman a53512fda4 VirtualizedList up-to-date state: Thread props to _createViewToken()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

`_createViewToken()` is called during state changes. Use explicit props passed in.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Fixed] - Thread props to _createViewToken()

Reviewed By: genkikondo

Differential Revision: D38294339

fbshipit-source-id: dc215e267f126a3789742c14c35479f509822710
2022-08-02 01:30:21 -07:00
Nick Gerleman e3aad65b35 VirtualizedList up-to-date state: Use correct form of setState() in _onCellFocusCapture()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

`_onCellFocusCapture()` derives state from existing state, so it should be wrapped in a state updater to compare against the latest value in the batch.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Fixed] - Use correct form of setState() in _onCellFocusCapture()

Reviewed By: genkikondo

Differential Revision: D38293583

fbshipit-source-id: 1d0e5152e6c1757408e39dff225e07accc5ee49f
2022-08-02 01:30:21 -07:00
Nick Gerleman f40ceb78e5 VirtualizedList up-to-date state: Thread props to _keyExtractor()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

Use supplied props in `_keyExtractor()`, which is used to map between frame index and identity.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Fixed] - Thread props to _keyExtractor()

Reviewed By: genkikondo

Differential Revision: D38293586

fbshipit-source-id: e50823bacdf45adad3b8b655d66d305a1762e9b8
2022-08-02 01:30:21 -07:00
Nick Gerleman 30db0be33a VirtualizedList up-to-date state: Thread props to __getFrameMetrics()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

This forwards props to `__getFrameMetricsApprox()` and `_getFrameMetrics()` . This is called in a variery of places, so we need to pass `FrameMetricProps` through more places, and update public/test usage.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Fixed] - Thread props to __getFrameMetrics()

Reviewed By: genkikondo

Differential Revision: D38293591

fbshipit-source-id: c1499d722b69eb4b5953124ee8b8c3d15e912d93
2022-08-02 01:30:21 -07:00
Nick Gerleman 6469d4b529 VirtualizedList up-to-date state: Thread props to computeWindowedRenderLimits()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

Use passed props in `computeWindowedRenderLimits()`, which is called during a state update.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Fixed] - Thread props to computeWindowedRenderLimits()

Reviewed By: genkikondo

Differential Revision: D38293588

fbshipit-source-id: 1330a003c1354bbd63c0b7b33a013e85e96fdc64
2022-08-02 01:30:21 -07:00
Nick Gerleman dd9e896645 VirtualizedList up-to-date state: Thread props to _updateViewableItems()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

Change `_updateViewableItems()` to accept an explicit set of props, and a CellRenderMask, instead of using `this.props` and `this.state`. The eventual sink are the `_getFrameMetric*` functions, so a minimal projection of props is added that we can pass through to it.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Changed] - Move Props to VirtualizedListProps

Reviewed By: genkikondo

Differential Revision: D38293587

fbshipit-source-id: 164fd4af7c370d905af53b0e9aafb3592d8659cc
2022-08-02 01:30:21 -07:00
Nick Gerleman cd595bd090 VirtualizedList up-to-date state: Remove _isVirtualizationDisabled()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

Remove `this.props` usage during state update where we can just use the props directly.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}

Changelog:
[Internal][Fixed] - Remove _isVirtualizationDisabled()

Reviewed By: genkikondo

Differential Revision: D38293589

fbshipit-source-id: af18f867fc880d5363134fe0d6f985efaf8be6c5
2022-08-01 15:00:33 -07:00
Nick Gerleman 03b4764836 VirtualizedList up-to-date state: Move Props to VirtualizedListProps
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

This moves public VirtualizedList types to a new file, shared between both `VirtualizedList`, and `VirtualizedList_EXPERIMENTAL`. This allows us to make public interface changes in a single place.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Changed] - Move Props to VirtualizedListProps

Reviewed By: genkikondo

Differential Revision: D38293585

fbshipit-source-id: 344d94466a2741ee67eb5754de5506eb3e265c5b
2022-08-01 14:56:24 -07:00
Nick Gerleman 9fb34ef567 VirtualizedList up-to-date state: Remove bad usage in _adjustCellsAroundViewport()
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.

## Diff Summary

Replace usages of `this.state` and `this.props` where we are already passed the newer revision of the state we want.

## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.

From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
 ---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
 ---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.

This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:

{F756963772}

Changelog:
[Internal][Fixed] - Remove bad usage in _adjustCellsAroundViewport()

Reviewed By: genkikondo

Differential Revision: D38293584

fbshipit-source-id: 807f36600d2fd82c87205195dd61956785bdbd2c
2022-08-01 14:51:33 -07:00
Nick Gerleman 0cfe5ae526 Allow empty cell ranges in CellRenderMask.addCells()
Summary:
VirtualizedList state is represented in terms of [first, last] ranges, where it is possible to express a zero-cell range by having [n, n-1]. This includes some awkward examples, like [0, -1] being valid.

CellRenderMask assumes `addCells` is called with at least one cell, with VirtualizedList previously guarding against adding the no cell case. This guard is present for adding main cell regions, but not for `_initialRenderRegion()`, which can be overridden to have a zero length as well.

This moves the `CellRenderMask` to be permissive of zero-length cell regions, and removes the caller guard.

Changelog:
[Internal][Fixed] - Allow empty cell ranges in CellRenderMask

Reviewed By: rshest

Differential Revision: D38184444

fbshipit-source-id: d2dadfdd9628b24f894126d63b1eb93f6387b877
2022-07-28 11:08:18 -07:00
Nick Gerleman 3f50440cc8 Gracefully handle negative initialScrollIndex in VirtualizedList_EXPERIMENTAL
Summary:
Existing code may pass negative values for `initialScrollIndex`, which the previous implemnentation handled gracefully. Handle the case gracefully in VirtualizedList_EXPERIMENTAL as well.

Changelog:
[Internal][Fixed] - Gracefully handle negative initialScrollIndex in VirtualizedList_EXPERIMENTAL

Reviewed By: rshest

Differential Revision: D38183625

fbshipit-source-id: 9aea91c4cf3ce2190d769f34ce728a109efc88d4
2022-07-27 18:52:47 -07:00
Nick Gerleman d574ea3526 Guard FlatList getItemCount() against incorrect data type
Summary:
If FlatList is passed non-array data it will return `undefined` as the result of `getItemCount()` to VirtualizedList. This change makes it return `0` instead, to signify there are no valid items to attempt to accces.

There are a set of invariants on properties passed to FlatList, to curb incorrect types at runtime, but there is existing code which runs into the condition.

Changelog:
[Internal][Fixed] - Guard FlatList getItemCount() against non-array data

Reviewed By: javache

Differential Revision: D38198351

fbshipit-source-id: 9efd0df7eeeba17078e2c838d470c4b0d621b9a0
2022-07-27 17:11:43 -07:00
Nick Gerleman f8e1fedf3d Allow injecting looser VirtualizedList
Summary:
VirtualizedList_EXPERIMENTAL has a different flow signature from VirtualizedList. This does not cause an error in unit tests, which are untyped, but prevents injecting VirtualizedList_EXPERIMENTAL via the current API from flowtype. This diff updates the injection interface to allow a more relaxed type, validating safety at runtime.

Changelog:
[Internal][Changed] - Allow injecting looser VirtualizedList

Reviewed By: javache

Differential Revision: D38143682

fbshipit-source-id: 054bbc5092823f4e4413d69d3d72a7ecdd71a6a2
2022-07-27 14:27:52 -07:00
Nick Gerleman 479053cb3c Add VirtualizedList_EXPERIMENTAL (CellRenderMask Usage)
Summary:
# This Change

https://github.com/react-native-community/discussions-and-proposals/pull/335  discussed a set of problems with VirtualizedList and focus. These were seen as severe externally for a11y on desktop. The issues center on users of keyboard and accessibility tools, where users expect to be able to move focus in an uninterrupted loop.

The design and implementation evolved to be a bit more general, and without any API-surface behavior changes. It was implemented and rolled out externally as a series of changes. The remaining changes that were not upstreamed into RN are rolled into https://github.com/facebook/react-native/pull/32646

This diff brings this change into the repo, as a separate copy of VirtualizedList, to measure its impact to guardrail metrics, without yet making it the default implementation. The intention is for this to be temporary, until there is confidence the implementation is correct.

## List Implementation (more on GitHub)

This change makes it possible to synchronously move native focus to arbitrary items in a VirtualizedList. This is implemented by switching component state to a sparse bitset. This was previously implemented and upstreamed as `CellRenderMask`.

A usage of this is added, to keep the last focused item rendered. This allows the focus loop to remain unbroken, when scrolling away, or tab loops which leave/re-enter the list.

VirtualizedList tracks the last focused cell through the capture phase of `onFocus`. It will keep the cell, and a viewport above and below the last focused cell rendered, to allow movement to it without blanking (without using too much memory).

## Experimentation Implementation

A mechanism is added to gate the change via VirtualizedListInjection, mirroring the approach taken for Switch with D27381306 (https://github.com/facebook/react-native/commit/683b825b327e7fa71e87e3d613cb9acd37c24288).

It allows VirtualizedList to delegate to a global override. It has a slight penalty to needing to import both modules, but means code which imports VirtualizedList directly is affected the changes.

Changelog:
[Internal][Added] - Add VirtualizedList_EXPERIMENTAL (CellRenderMask Usage)

Reviewed By: lunaleaps

Differential Revision: D38020408

fbshipit-source-id: ad0aaa6791f3f4455e3068502a2841f3ffb40b41
2022-07-26 20:06:58 -07:00
Nick Gerleman 04e43544b8 Allow VirtualizedListContext to support different component type
Summary:
This change is in preparation of adding a separate `VirtualizedList_EXPERIMENTAL` component.

Both the original, and experimental lists use `VirtualizedListContext`, which itself references back to the VirtualizedList class type. VirtualizedList private methods are currently included in the type system, and are called in other VirtualizedList code (see https://github.com/facebook/react-native/commit/b2f871a6fa9c92dd0712055384b9eca6d828e37d). This prevents Flow from seeing the two classes are compatible if "private" methods change.

My first attempt was to parameterize the context, to allow both `VirtualizedList`, and `VirtualizedList_EXPERIMENTAL` to use the same code without sacrificing type safety or adding further duplication. This added more complexity than it is worth, so I am instead loosening the type on VirtualizedListContext to pass around a more generic handle.

Changelog:
[Internal][Changed] - Allow VirtualizedListContext to support different component type

Reviewed By: javache

Differential Revision: D38017086

fbshipit-source-id: 91e8f6ab2591d3ae9b7f9263711b4a39b78f68e0
2022-07-26 20:06:58 -07:00
Pieter Vanderwerff 66c6a75650 Suppress missing annotations in xplat/js
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predictable.

Reviewed By: bradzacher

Differential Revision: D37388949

fbshipit-source-id: cdcbc98035ce9b6994842005ea46df42de54f9b8
2022-06-23 16:54:29 -07:00
Pieter Vanderwerff c940eb0c49 Add LTI annotations to function params in xplat/js [manually-modified]
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predicatable.

Reviewed By: bradzacher

Differential Revision: D37363351

fbshipit-source-id: a9d3df7db6f9d094ac2ce81aae1f3ab4f62b243a
2022-06-22 23:01:55 -07:00
Pieter Vanderwerff e7a4dbcefc Add LTI annotations to function params in xplat/js [1/2]
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predicatable.

Reviewed By: evanyeung

Differential Revision: D37353648

fbshipit-source-id: e5a0c685ced85a8ff353d578b373f836b376bb28
2022-06-22 21:36:52 -07:00
Kacie Bawiec 4bb551d018 Back out "TalkBack support for ScrollView accessibility announcements (list and grid) - Javascript Only Changes"
Summary:
Original commit changeset: 3765213c5d8b

Original Phabricator Diff: D37189197 (https://github.com/facebook/react-native/commit/2d5882132fb2c533fe9bbba83576b8fac4aca727)

Changelog: [Internal]

Reviewed By: bvanderhoof

Differential Revision: D37260990

fbshipit-source-id: bfcb10f2d5a2a1427b72a10ef380df194b041ba0
2022-06-17 22:08:57 -07:00
fabriziobertoglio1987 2d5882132f TalkBack support for ScrollView accessibility announcements (list and grid) - Javascript Only Changes (#33180)
Summary:
This is the Javascript-only changes from D34518929 (https://github.com/facebook/react-native/commit/dd6325bafe1a539d348f3710e717a6344576b859), split out for push safety. Original summary and test plan below:

This issue fixes [30977][17] . The Pull Request was previously published by [intergalacticspacehighway][13] with [31666][19].
The solution consists of:
1. Adding Javascript logic in the [FlatList][14], SectionList, VirtualizedList components to provide accessibility information (row and column position) for each cell in the method [renderItem][20] as a fourth parameter [accessibilityCollectionItem][21]. The information is saved on the native side in the AccessibilityNodeInfo and announced by TalkBack when changing row, column, or page ([video example][12]). The prop accessibilityCollectionItem is available in the View component which wraps each FlatList cell.
2. Adding Java logic in [ReactScrollView.java][16] and HorizontalScrollView to announce pages with TalkBack when scrolling up/down. The missing AOSP logic in [ScrollView.java][10] (see also the [GridView][11] example) is responsible for announcing Page Scrolling with TalkBack.

Relevant Links:
x [Additional notes on this PR][18]
x [discussion on the additional container View around each FlatList cell][22]
x [commit adding prop getCellsInItemCount to VirtualizedList][23]

## Changelog

[Android] [Added] - Accessibility announcement for list and grid in FlatList

Pull Request resolved: https://github.com/facebook/react-native/pull/33180

Test Plan:
[1]. TalkBack announces pages and cells with Horizontal Flatlist in the Paper Renderer ([link][1])
[2]. TalkBack announces pages and cells with Vertical Flatlist in the Paper Renderer ([link][2])
[3]. `FlatList numColumns={undefined}` Should not trigger Runtime Error NoSuchKey exception columnCount when enabling TalkBack. ([link][3])
[4]. TalkBack announces pages and cells with Nested Horizontal Flatlist in the rn-tester app ([link][4])

[1]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050452894
[2]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050462465
[3]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1032340879
[4]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050618308
[10]:https://github.com/aosp-mirror/platform_frameworks_base/blob/1ac46f932ef88a8f96d652580d8105e361ffc842/core/java/android/widget/AdapterView.java#L1027-L1029 "GridView.java method responsible for calling setFromIndex and setToIndex"
[11]:https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1042518901 "test case on Android GridView"
[12]:https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050452894 "TalkBack announces pages and cells with Horizontal Flatlist in the Paper Renderer"
[13]:https://github.com/intergalacticspacehighway "github intergalacticspacehighway"
[14]:https://github.com/fabriziobertoglio1987/react-native/blob/80acf523a4410adac8005d5c9472fb87f78e12ee/Libraries/Lists/FlatList.js#L617-L636 "FlatList accessibilityCollectionItem"
[16]:https://github.com/fabriziobertoglio1987/react-native/blob/5706bd7d3ee35dca48f85322a2bdcaec0bce2c85/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L183-L184 "logic added to ReactScrollView.java"
[17]: https://github.com/facebook/react-native/issues/30977
[18]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6
[19]: https://github.com/facebook/react-native/pull/31666
[20]: https://reactnative.dev/docs/next/flatlist#required-renderitem "FlatList renderItem documentation"
[21]: https://github.com/fabriziobertoglio1987/react-native/commit/75147359c5d070406ebbe488c57c3cd94c08c19d "commit that introduces fourth param accessibilityCollectionItem in callback renderItem"
[22]: https://github.com/facebook/react-native/pull/33180#discussion_r826748664 "discussion on the additional container View around each FlatList cell"
[23]: https://github.com/fabriziobertoglio1987/react-native/commit/d50fd1a68112f40f4be3ac3aa4d67f96df33e387 "commit adding prop getCellsInItemCount to VirtualizedList"

Reviewed By: kacieb

Differential Revision: D37189197

Pulled By: blavalla

fbshipit-source-id: 3765213c5d8bfde56e0e5f155cdd899c368512e7
2022-06-17 17:59:51 -07:00
David 5854b11bf9 Add ability to pass ItemSeparatorComponent as React Element (#32748)
Summary:
Currently `ListHeaderComponent` & `ListFooterComponent` allow to use React Componetn & Elemelen

```tsx
<FlatList
  ListHeaderComponent={<View />} // valid
  ListHeaderComponent={View}     // valid
/>
```

But when you try to pass `ItemSeparatorComponent` as React Element it will throw an error

```tsx
<FlatList
  ItemSeparatorComponent={View}     // ok
  ItemSeparatorComponent={<View />} /* not valid:
    Error: Element type is invalid: expected a string (for built-in components) or a class/function
    (for composite components) but got: object.
    Check the render method of `CellRenderer`.
  */
/>
```

So, this PR adds this ability

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[General] [Changed] - Add ability to pass `ItemSeparatorComponent` as React Element

Pull Request resolved: https://github.com/facebook/react-native/pull/32748

Test Plan: ...

Reviewed By: lyahdav

Differential Revision: D37227719

Pulled By: cortinico

fbshipit-source-id: 1c4943fa9d42bf5e61fbd999d1f5be46b51ecb14
2022-06-17 16:28:03 -07:00
Christian Ruink b869680c11 Fixing onEndReachedThreshold === 0 not firing onEndReached function on Android.
Summary:
Changelog:
[Android][Fix] - When `onEndReachedThreshold` is set to 0 `onEndReached` function on `VirtualizedList` properly fires once the user scrolls to the bottom of the list.

Reviewed By: genkikondo

Differential Revision: D36488189

fbshipit-source-id: b95f3291f2957273280696d8840c1e000d669380
2022-06-07 16:22:12 -07:00
Jordan Brown 6064fd0600 Presuppress xplat and upgrade to 0.178.1
Summary:
This diff upgrades xplat to 0.178.1 and pre-suppresses errors from turning on constrained writes.

To generate this diff I:
* Modified every `env_mode=constrain_writes` to `env_mode=ssa` and made a commit (this is so our upgrade script will work)
* Ran   scripts/flow/upgrade.sh 0.178.1 to upgrade all the flowconfigs to 178.1 and suppress new-env errors
* Modified arvr/js/flowconfig.ejs to use 0.178.1 and ran `scripts/gen-flowconfig/gen-flowconfig --project arvr`
* Modified xplat/js/flowconfig.ejs to use 0.178.1 and ran `scripts/gen-flowconfig/gen-flowconfig --project xplat`
* Unstacked from the commit in point 1

Reviewed By: SamChou19815

Differential Revision: D36676019

fbshipit-source-id: c3032f18ed838afc327f00de563e7f20713bdc26
2022-05-26 12:59:52 -07:00
Blair Vanderhoof bc7b5c3011 Fix issue with RTL locales and zoomScale
Summary:
Changelog:
[iOS][Fixed] - When in an RTL locale on iOS, e.nativeEvent.zoomScale is -1. This seems to cause erratic blank spaces that don't recover as you scroll. Set the value to 1 instead when negative.

Differential Revision: D36499121

fbshipit-source-id: f82812ca00ae4162fbff617df8c716a4964b3a8f
2022-05-20 21:49:34 -07:00
Blair Vanderhoof 82b268f884 Revert D36468390: Fix negative zoomScale in RTL
Differential Revision:
D36468390 (https://github.com/facebook/react-native/commit/2f491bfa9f86c3db2e459e331f39bc3cf12e7239)

Original commit changeset: f18244f1421f

Original Phabricator Diff: D36468390 (https://github.com/facebook/react-native/commit/2f491bfa9f86c3db2e459e331f39bc3cf12e7239)

fbshipit-source-id: 925a7b811aaeefb0cda20493365c1e12cab66ee0
2022-05-18 14:44:46 -07:00
Blair Vanderhoof 2f491bfa9f Fix negative zoomScale in RTL
Summary:
Changelog:
[iOS][Fixed] - When in an RTL locale on iOS, e.nativeEvent.zoomScale is -1. This seems to cause erratic blank spaces that don't recover as you scroll. Taking Math.abs of the value fixes it. Blame: D36169686 (https://github.com/facebook/react-native/commit/13a72e0ccceb2db6aeacd03b4f429d200392c17b)

Differential Revision: D36468390

fbshipit-source-id: f18244f1421fc1ccbb0d1035df8a7c6de10ccf62
2022-05-17 21:50:25 -07:00
Genki Kondo 57d3b9e2ca Modify VirtualizeUtils.elementsThatOverlapOffsets to use binary search
Summary:
elementsThatOverlapOffsets was quite inefficient as it was doing a linear scan over all items without an early out for each input offset.

The number of items can be large, so we'd want to use binary search here.
Before: O(MN), where M is the # offsets and N is the # items
After: O(MlogN)

As a utility method, elementsThatOverlapOffsets should not be responsible for checking that the offsets are in increasing order

'binary-search' dep added via https://www.internalfb.com/intern/wiki/React_Native/Building_Product_Experiences/Third_Party_Packages_(npm)/

Changelog:
[Internal] - Modify VirtualizeUtils.elementsThatOverlapOffsets to use binary search

Reviewed By: javache

Differential Revision: D36292326

fbshipit-source-id: 5f22eb5533b69e2ebe5c1cb34e4f82605838f0a7
2022-05-16 13:14:35 -07:00
Genki Kondo 73ad6514cc Fix bounds calculation with initialScrollIndex
Summary:
Sometimes this._scrollMetrics.offset is 0 even after initial scroll is triggered, because the offset is updated only upon _onScroll, which may not have been called in time for the next computation of the render limits. Thus, there is a window of time where computeWindowedRenderLimits calculates undesired render limits as it uses the offset. This results in 2 extra rerenders of the VirtualizedList if an initial scroll offset is applied, as the render limits shifts from the expected bounds (calculated using initialScrollIndex), to the 0 offset bounds (calculated using computeWindowedRenderLimits due to offset = 0), back to the expected bounds (onScroll triggers recalculation of render limits via _updateCellsToRender).

This issue was introduced in https://www.internalfb.com/diff/D35503114 (https://github.com/facebook/react-native/commit/c5c17985dae402725abb8a3a94ccedc515428711)

We cannot rely on this._hasDoneInitialScroll to indicate that scrolling *actually* finished (specifically, that _onScroll was called). Instead, we want to recalculate the windowed render limits if any of the following hold:
- initialScrollIndex is undefined or is 0
- initialScrollIndex > 0 AND scrolling is complete
- initialScrollIndex > 0 AND the end of the list is visible (this handles the case where the list is shorter than the visible area) <- this is the case that https://www.internalfb.com/diff/D35503114 (https://github.com/facebook/react-native/commit/c5c17985dae402725abb8a3a94ccedc515428711) attempted to address

Changelog:
[Internal][Fixed] - Fix issue where VirtualizedList rerenders multiple times and flickers when initialScrollIndex is set

Reviewed By: JoshuaGross

Differential Revision: D36328891

fbshipit-source-id: aba26aa06b24f6976657dd1e9f95bb666f60d9a6
2022-05-12 00:47:11 -07:00
Genki Kondo 92cf74cd50 Fix render limit calculations by setting default zoomScale to 1
Summary:
During debugging of undesired behavior using VirtualizedList with initialScrollIndex, it was found that zoomScale was sometimes undefined, which resulted in elementsThatOverlapOffsets returning not being able to find the frame at the given offsets.

This does not cause any unexpected behavior when scrolling from the top, as the first item index in VirtualizedList is always calculated to be 0; however, when we set initialScrollIndex, the frame calculations are incorrect, resulting in wasteful re-renders of the VirtualizedList as it renders every frame (row) from the top.

Changelog:
[Internal][Fixed] - Default zoomScale to 1 for computeWindowedRenderLimits and elementsThatOverlapOffsets in order to fix render limit calculation.

Differential Revision: D36294426

fbshipit-source-id: 1e1abec1c95f58a1913bafa2c9680e51e2dc26fa
2022-05-10 16:21:59 -07:00
Sam Zhou 23a160ebf6 Lock down constrain writes in some directories
Summary: Changelog: [internal]

Reviewed By: gkz

Differential Revision: D36214426

fbshipit-source-id: 8498ef0f646d8a38e5d523f4fd2deacf1b649fd2
2022-05-06 15:53:13 -07:00
Evan Yeung 73a43901b4 Deploy 0.177.0 to xplat
Summary: Changelog: [Internal]

Reviewed By: SamChou19815

Differential Revision: D36141544

fbshipit-source-id: 7e322faa6f902547bb68997d02a50352c525d543
2022-05-06 10:51:36 -07:00
islandryu 13a72e0ccc Fix items disappear when zooming VirtualizedList (#33765)
Summary:
fix https://github.com/facebook/react-native/issues/33705
Fixed the disappearance of items when scrolling after zooming VirtualizedList.
example https://github.com/islandryu/zoomVirtualizedList

Before modification

https://user-images.githubusercontent.com/65934663/166849127-9fc3ba84-5172-4ae1-bd44-dd6312f283ec.mov

After modification

https://user-images.githubusercontent.com/65934663/166868632-2f78e118-f705-442d-b94e-ff165bed26c7.mov

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[General] [Fixed] - Fixed the disappearance of items when scrolling after zooming VirtualizedList.

Pull Request resolved: https://github.com/facebook/react-native/pull/33765

Test Plan:
Make the VirtualizedList zoomable with a prop such as maximumZoomScale.
Apply the patch and make sure that items in the VirtualizedList do not disappear when you scroll after zooming the VirtualizedList.

Or apply the patch from this repository and check it.
https://github.com/islandryu/zoomVirtualizedList

Reviewed By: javache

Differential Revision: D36169686

Pulled By: yungsters

fbshipit-source-id: 0f86255c2864be13f6d2dc5a58af1d11c9eedac3
2022-05-06 09:30:15 -07:00
George Zahariev 20d9d3aa6a Fixes to non-product code (e.g React Native)
Summary:
We are working on making the empty object literal `{}` have the type `{}` - i.e. exact empty object - rather than being unsealed.

Some manual fixes, in particular to React Native code, which is used and can be synced to other repos (e.g. WWW).

With these changes, error diff in Xplat is down to ~1990 errors

Note that after I roll out `exact_empty_objects`, I'll codemod all the `{...null}` (the only way to get an exact empty object currently) back to `{}`

Changelog: [Internal]

Reviewed By: SamChou19815

Differential Revision: D36142838

fbshipit-source-id: 054caf370db230f42a4c5f5706c88979ef246537
2022-05-04 16:13:07 -07:00
George Zahariev 0337a2981d Add annotations to empty objects that look like indexers in Xplat
Summary:
We are working on making the empty object literal `{}` have the type `{}` - i.e. exact empty object - rather than being unsealed.
Making this change exposes a variety of errors. We can prevent these errors by annotating what we want the type of the empty object to be.

Reduces Xplat error diff to 2.3k

- Announcement: [post](https://fb.workplace.com/groups/flowlang/posts/903386663600331)
- Support group: [Flow Support](https://fb.workplace.com/groups/flow)

drop-conflicts

Format:
```
arc f
```
Sort imports
```
hg l -n | xargs js1 lint --fix --rule 'fb-tools/sort-requires'
```

Changelog: [Internal]

Reviewed By: samwgoldman

Differential Revision: D36086696

fbshipit-source-id: 90447279f2e6e38f44189b74ec0297719f7adf58
2022-05-03 19:59:28 -07:00
Sam Zhou 0c4c6ca319 Add annotations to unannotated variable declarations [manually-modified]
Reviewed By: panagosg7

Differential Revision: D35948108

fbshipit-source-id: 7d286c9dd66dbd25281e2d831691f8bb34504b5d
2022-04-27 19:15:55 -07:00
Pieter De Baets ceb0a54608 Memoize VirtualizedListCellContextProvider
Summary:
When a FlatList is nested inside another FlatList, it may be re-rendered whenever the outer FlatList renders. Apply the same optimization we already had in `VirtualizedListContextProvider` to avoid changing the context object if no values have changed.

Changelog: [General][Changed] - Optimized VirtualizedList context when used with nested lists

Reviewed By: genkikondo

Differential Revision: D35905952

fbshipit-source-id: 695253c85db2043d22e208ad94ecc7daa1455055
2022-04-26 04:04:45 -07:00
Luna Wei 6958bbb28c Fix up lint errors under react-native-github (#33622)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/33622

Changelog: [Internal] Clean up eslint errors

Reviewed By: yungsters

Differential Revision: D35599445

fbshipit-source-id: bbb9061a3cf9df32daacad9a9b44eba94d3ce48c
2022-04-22 16:25:25 -07:00
Antoine Doubovetzky c5c17985da Fix VirtualizedList with initialScrollIndex not rendering all elements when data is updated (#33558)
Summary:
Fixes https://github.com/facebook/react-native/issues/33529 (note that I reproduced the bug on iOS too).

The bug comes from the fact that we were using `this._scrollMetrics.offset` to determine if the initial scroll was done. But sometimes it equals 0 even after the initial scroll is done, for example when the content does not fill the list. So I replaced it with `this._hasDoneInitialScroll`.
I believe that `this._hasDoneInitialScroll` was not used in the first place because it was introduced later (3 years ago vs 5 years ago for the original code).

The replacement correctly fixes the broken test case and the example given in the issue.

Then I had to update two test cases (rename the first and remove the second), that shows explicitly the broken behavior:
we have to simulate the initial scroll for the content to be adjusted, so when the content does not fill the view and the scroll cannot be executed, the content is not adjusted.

## Changelog

[General] [Fix] - Fix VirtualizedList with initialScrollIndex not rendering all elements when data is updated

Pull Request resolved: https://github.com/facebook/react-native/pull/33558

Test Plan:
- I added a broken test case based on the issue
- I tested with the RNTesterApp using the code example given in the issue

Reviewed By: ryancat

Differential Revision: D35503114

Pulled By: yungsters

fbshipit-source-id: 67bb75d7cf1ebac0d59127d0d45afbaa3167dcf3
2022-04-20 10:26:50 -07:00
Moti Zilberman a12959546a Revert D34518929: TalkBack support for ScrollView accessibility announcements (list and grid)
Differential Revision:
D34518929 (https://github.com/facebook/react-native/commit/dd6325bafe1a539d348f3710e717a6344576b859)

Original commit changeset: 410a05263a56

Original Phabricator Diff: D34518929 (https://github.com/facebook/react-native/commit/dd6325bafe1a539d348f3710e717a6344576b859)

fbshipit-source-id: 114d0910970c5f5caefb98c378722faba283f2a1
2022-04-20 06:48:19 -07:00
fabriziobertoglio1987 dd6325bafe TalkBack support for ScrollView accessibility announcements (list and grid) (#33180)
Summary:
This issue fixes [30977][17] . The Pull Request was previously published by [intergalacticspacehighway][13] with [31666][19].
The solution consists of:
1. Adding Javascript logic in the [FlatList][14], SectionList, VirtualizedList components to provide accessibility information (row and column position) for each cell in the method [renderItem][20] as a fourth parameter [accessibilityCollectionItem][21]. The information is saved on the native side in the AccessibilityNodeInfo and announced by TalkBack when changing row, column, or page ([video example][12]). The prop accessibilityCollectionItem is available in the View component which wraps each FlatList cell.
2. Adding Java logic in [ReactScrollView.java][16] and HorizontalScrollView to announce pages with TalkBack when scrolling up/down. The missing AOSP logic in [ScrollView.java][10] (see also the [GridView][11] example) is responsible for announcing Page Scrolling with TalkBack.

Relevant Links:
x [Additional notes on this PR][18]
x [discussion on the additional container View around each FlatList cell][22]
x [commit adding prop getCellsInItemCount to VirtualizedList][23]

## Changelog

[Android] [Added] - Accessibility announcement for list and grid in FlatList

Pull Request resolved: https://github.com/facebook/react-native/pull/33180

Test Plan:
[1]. TalkBack announces pages and cells with Horizontal Flatlist in the Paper Renderer ([link][1])
[2]. TalkBack announces pages and cells with Vertical Flatlist in the Paper Renderer ([link][2])
[3]. `FlatList numColumns={undefined}` Should not trigger Runtime Error NoSuchKey exception columnCount when enabling TalkBack. ([link][3])
[4]. TalkBack announces pages and cells with Nested Horizontal Flatlist in the rn-tester app ([link][4])

[1]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050452894
[2]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050462465
[3]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1032340879
[4]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050618308
[10]:https://github.com/aosp-mirror/platform_frameworks_base/blob/1ac46f932ef88a8f96d652580d8105e361ffc842/core/java/android/widget/AdapterView.java#L1027-L1029 "GridView.java method responsible for calling setFromIndex and setToIndex"
[11]:https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1042518901 "test case on Android GridView"
[12]:https://github.com/fabriziobertoglio1987/react-native-notes/issues/6#issuecomment-1050452894 "TalkBack announces pages and cells with Horizontal Flatlist in the Paper Renderer"
[13]:https://github.com/intergalacticspacehighway "github intergalacticspacehighway"
[14]:https://github.com/fabriziobertoglio1987/react-native/blob/80acf523a4410adac8005d5c9472fb87f78e12ee/Libraries/Lists/FlatList.js#L617-L636 "FlatList accessibilityCollectionItem"
[16]:https://github.com/fabriziobertoglio1987/react-native/blob/5706bd7d3ee35dca48f85322a2bdcaec0bce2c85/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java#L183-L184 "logic added to ReactScrollView.java"
[17]: https://github.com/facebook/react-native/issues/30977
[18]: https://github.com/fabriziobertoglio1987/react-native-notes/issues/6
[19]: https://github.com/facebook/react-native/pull/31666
[20]: https://reactnative.dev/docs/next/flatlist#required-renderitem "FlatList renderItem documentation"
[21]: https://github.com/fabriziobertoglio1987/react-native/commit/75147359c5d070406ebbe488c57c3cd94c08c19d "commit that introduces fourth param accessibilityCollectionItem in callback renderItem"
[22]: https://github.com/facebook/react-native/pull/33180#discussion_r826748664 "discussion on the additional container View around each FlatList cell"
[23]: https://github.com/fabriziobertoglio1987/react-native/commit/d50fd1a68112f40f4be3ac3aa4d67f96df33e387 "commit adding prop getCellsInItemCount to VirtualizedList"

Reviewed By: kacieb

Differential Revision: D34518929

Pulled By: blavalla

fbshipit-source-id: 410a05263a56162bf505a4cad957b24005ed65ed
2022-04-19 19:45:10 -07:00
Rick Hanlon 41cbccd98d @nocommit React Native sync for revisions 1159ff6...34aa5cf
Summary:
I'm kicking this off to see what's the extent of failures we're going to get if we try to bump to React 18 inside RN OSS.

This sync includes the following changes:
- **[34aa5cfe0](https://github.com/facebook/react/commit/34aa5cfe0 )**: Update local package.jsons for 18 //<Andrew Clark>//
- **[e7d0053e6](https://github.com/facebook/react/commit/e7d0053e6 )**: [fizz] Fix validateIterable call ([#24166](https://github.com/facebook/react/pull/24166)) //<salazarm>//
- **[6b85823b3](https://github.com/facebook/react/commit/6b85823b3 )**: Clean up Selective Hydration / Event Replay flag ([#24156](https://github.com/facebook/react/pull/24156)) //<salazarm>//

Changelog:
[General][Changed] - React Native sync for revisions 1159ff6...34aa5cf

jest_e2e[run_all_tests]

Reviewed By: cortinico

Differential Revision: D35504622

fbshipit-source-id: ad0f6b42b6e03d78cd5d6ba51ce5a5730d25b167
2022-04-12 08:50:06 -07:00