Commit Graph

88 Commits

Author SHA1 Message Date
Nick Gerleman 524a3f0476 Try fixing bundling outside the repo (#46148)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46148

Try fixing the import path (not sure if access from external modules is allowed though).

Changelog: [Internal]

Reviewed By: realsoelynn

Differential Revision: D61643115

fbshipit-source-id: a840ee375430b0e20050a36b695a5a4c93c29258
2024-08-21 23:19:56 -07:00
Andrei Marchenko 954e294183 perf(virtualized-lists) removing rerender cells for every change of Virtualized list (#46103)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46103

Reducing the boundary of rerender of virtual lists. Previously with prop: "strictMode={true}" the VirtualizedList still re rendered each CellRenderer component. Because method getDerivedStateFromProps generated every time a new uniq state and the cells didn’t have a PureComponent. It helps to improve react performance for lists which have 5+ elements.

I reused recomended approach from react doc https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization

changelog: [internal]
Optimizing CellRenderer of VirtualizedList

Reviewed By: NickGerleman, sammy-SC

Differential Revision: D61493434

fbshipit-source-id: 917a33e48bd2f18e8ac150e5701d2e7c45dbe879
2024-08-21 14:23:07 -07:00
Sam Zhou a622a43764 Replace all exact React.Element type in react-native with ExactReactElement_DEPRECATED (#45998)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45998

The exact `React.Element` type is deprecated and will be removed in a future version of Flow.

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D61205640

fbshipit-source-id: a029a3a46c7d8d9f94b0b931b991b2ce461151b2
2024-08-13 09:08:44 -07:00
Sam Zhou 5b96e90f77 Replace React.Element<any> and unnecessarily specific React.Element with React.MixedElement (#45923)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45923

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D60872182

fbshipit-source-id: b81fb43968c52cbfdb4a9fa57f1175aabc2a3939
2024-08-06 21:33:08 -07:00
Sam Zhou 4f47b385fa Cleanup all uses of internal flow type React$ElementRef in react-native (#45904)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45904

Flow will error on these dollar types soon. For all the ones changed here, they can all be further simplified.

Changelog: [Internal]

Reviewed By: gkz

Differential Revision: D60786768

fbshipit-source-id: e26bf0be1c4a933fc0bd8b59827e10cbd7242a83
2024-08-05 14:51:30 -07:00
Blake Friedman 188a09ef69 fix linting noise (#45465)
Summary:
## Summary:
Fix linting warnings

Changelog: [Internal]

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

Test Plan:
```
$ eslint .
Done in 46.11s.
$ arc f
ok No lint issues.
```

Reviewed By: cipolleschi

Differential Revision: D59805820

Pulled By: blakef

fbshipit-source-id: f33d99a6a06607c3c3762881cc7c182804b981e1
2024-07-17 10:07:00 -07:00
Nick Gerleman 12b64b7824 Loosen SectionList renderItem required return type (#45305)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45305

Allow SectionList render functions to return any React node, instead of just React.Element. This matches VirtualizedList/FlatList, and general Flow component conventions.

Changelog:
[General][Fixed] - Loosen SectionList `renderItem` required return type

Reviewed By: joevilches

Differential Revision: D59404511

fbshipit-source-id: 3055d8f01845ff5ef8ae75b87f60d8cd26dc07b4
2024-07-08 17:40:59 -07:00
Alex Hunt ebf1a7b79b Bump packages for next major release (#45015)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45015

Set package versions to `0.76.0-main` (`0.75-stable` branch was cut).

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D58687399

fbshipit-source-id: 27ed987e4557705845d57d64e7547cddbd982a03
2024-06-26 07:59:49 -07:00
Tim Yung 0dd8224a71 RN/Relay: Bump Dependency to React 19 (#44990)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44990

Upgrades React Native and Relay to depend on React 19, which is currently published as release candidates. This is in preparation for React Native 0.75.

This will depend on updating open source renderers after [facebook/react#29903](https://github.com/facebook/react/pull/29903) is merged.

Changelog:
[General][Changed] - Upgrade to React 19

Reviewed By: robhogan

Differential Revision: D58625271

fbshipit-source-id: f9ad95b18716a9ce02f7cfbcc7248bdfb244c010
2024-06-17 02:59:55 -07:00
Tim Yung 180dbbf0fb RN: Mitigate Remaining Jest Failures for React 19 (#45002)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45002

There are a couple Jest unit test cases for `VirtualizedList-test.js` that require further investigation.

We believe that these are problems with Jest fake timers in the test and not with the component itself, so for now let's skip them so as to unblock the upgrade to React 19.

Changelog:
[Internal]

Reviewed By: robhogan

Differential Revision: D58656948

fbshipit-source-id: d52f3ad8277def6eae20cbbc11751d73b769d929
2024-06-17 02:59:55 -07:00
Tim Yung fe06cbfbf3 Add missing acts to VirtualizedList-test and migrate to async act (#44997)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44997

Wrap `VirtualizedList-test` uses of `react-test-renderer` in `act` as appropriate, so as to pass under current React and mostly pass under React 19, with further fixes to come.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D58649295

fbshipit-source-id: 5e0fa791d581fbf004a2ca7eaa5c4b4d9a15ddfe
2024-06-16 23:02:19 -07:00
Rob Hogan a66ba92526 VirtualizedSectionList-test: use act around react-test-renderer create
Summary:
Migrate `VirtualizedSectionList-test` to use `act`-wrapping in prepation for React 19.

Avoid the `react-native/jest/renderer` abstractions as this is a separate package.

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D58653558

fbshipit-source-id: 0e19fff5c3998fb00b71c3d07100a2064682cb4c
2024-06-16 21:38:01 -07:00
Sam Zhou f4325dac8e Replace direct React.createElement call with jsx in react-native (#44738)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44738

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D58004147

fbshipit-source-id: f42c939d92a876b8746703c134b246567846c3ee
2024-05-31 10:06:09 -07:00
Fabrizio Cucci 95de14dc53 Drop unused code + minor lint fixes (#44645)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44645

Changelog: [Internal]

As per title.

Reviewed By: NickGerleman

Differential Revision: D57664819

fbshipit-source-id: 2388bd01c00d814a12de7f2e285b78f207e6012c
2024-05-22 12:11:33 -07:00
Tim Yung abb7070a51 RN/Relay: Upgrade to React v18.3.1 (#44397)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44397

X-link: https://github.com/facebook/metro/pull/1270

Upgrades `react-native` and `relay` to the newly published `react@18.3.1`.

Changelog:
[General][Changed] - Upgrade to `react@18.3.1`

Reviewed By: jackpope

Differential Revision: D56901818

fbshipit-source-id: 423d35205bb533c6a39c0fed25a1ffea1f0bc12d
2024-05-02 16:18:26 -07:00
Sam Zhou 41f525ccae Pre-suppress unsafe string key access errors in xplat/js (#44221)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44221

This diff pre-suppresses errors of the following pattern, to prepare for the next Flow release.

```
declare const obj: {foo: string};
declare const key: string;
obj[key]; // error: invalid-computed-prop
```

Changelog: [Internal]

Reviewed By: alexmckenley

Differential Revision: D56477899

fbshipit-source-id: 5676b8685bd3157a519fe433cfce0fa28e003502
2024-04-23 11:36:14 -07:00
sebmarkbage 78d6873b04 Don't Rethrow Errors at the Root (#28627)
Summary:
Stacked on top of #28498 for test fixes.

### Don't Rethrow

When we started React it was 1:1 setState calls a series of renders and
if they error, it errors where the setState was called. Simple. However,
then batching came and the error actually got thrown somewhere else.
With concurrent mode, it's not even possible to get setState itself to
throw anymore.

In fact, all APIs that can rethrow out of React are executed either at
the root of the scheduler or inside a DOM event handler.
If you throw inside a React.startTransition callback that's sync, then
that will bubble out of the startTransition but if you throw inside an
async callback or a useTransition we now need to handle it at the hook
site. So in 19 we need to make all React.startTransition swallow the
error (and report them to reportError).

The only one remaining that can throw is flushSync but it doesn't really
make sense for it to throw at the callsite neither because batching.
Just because something rendered in this flush doesn't mean it was
rendered due to what was just scheduled and doesn't mean that it should
abort any of the remaining code afterwards. setState is fire and forget.
It's send an instruction elsewhere, it's not part of the current
imperative code.

Error boundaries never rethrow. Since you should really always have
error boundaries, most of the time, it wouldn't rethrow anyway.

Rethrowing also actually currently drops errors on the floor since we
can only rethrow the first error, so to avoid that we'd need to call
reportError anyway. This happens in RN events.

The other issue with rethrowing is that it logs an extra console.error.
Since we're not sure that user code will actually log it anywhere we
still log it too just like we do with errors inside error boundaries
which leads all of these to log twice.
The goal of this PR is to never rethrow out of React instead, errors
outside of error boundaries get logged to reportError. Event system
errors too.

### Breaking Changes

The main thing this affects is testing where you want to inspect the
errors thrown. To make it easier to port, if you're inside `act` we
track the error into act in an aggregate error and then rethrow it at
the root of `act`. Unlike before though, if you flush synchronously
inside of act it'll still continue until the end of act before
rethrowing.

I expect most user code breakages would be to migrate from `flushSync`
to `act` if you assert on throwing.

However, in the React repo we also have `internalAct` and the
`waitForThrow` helpers. Since these have to use public production
implementations we track these using the global onerror or process
uncaughtException. Unlike regular act, includes both event handler
errors and onRecoverableError by default too. Not just render/commit
errors. So I had to account for that in our tests.

We restore logging an extra log for uncaught errors after the main log
with the component stack in it. We use `console.warn`. This is not yet
ignorable if you preventDefault to the main error event. To avoid
confusion if you don't end up logging the error to console I just added
`An error occurred`.

### Polyfill

All browsers we support really supports `reportError` but not all test
and server environments do, so I implemented a polyfill for browser and
node in `shared/reportGlobalError`. I don't love that this is included
in all builds and gets duplicated into isomorphic even though it's not
actually needed in production. Maybe in the future we can require a
polyfill for this.

### Follow Ups

In a follow up, I'll make caught vs uncaught error handling be
configurable too.

---------

DiffTrain build for commit https://github.com/facebook/react/commit/6786563f3cbbc9b16d5a8187207b5bd904386e53.

Changelog:
[Internal]

Reviewed By: kassens

Differential Revision: D55408481

Pulled By: yungsters

fbshipit-source-id: 598aa306369e21cb3e93ad6041a87bfbaa9eef9e

Co-authored-by: Ricky Hanlon <rickhanlonii@gmail.com>
2024-03-29 01:42:24 -07:00
Andrew Coates dbf8e3f5ba Add @types/react as optional peerDependency on packages that use it (#43509)
Summary:
Now that RN is providing TS type information, many of those .d.ts files depend on types from react.  In modern packagemanagers (Ex: pnpm) types/react will not be available to RN since it does not declare it as a dependency.

I also noticed that the types for react-native-popup-menu-android appear to be pointing to the wrong location.

Add types/react as a peerDependency on the packages that have .d.ts files that import from React.
Add types/react to peerDependencyMeta with optional:true to prevent users not using TS from requiring types/react.

## Changelog:

[GENERAL] [ADDED] Added types/react as an optional peerDependency

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

Reviewed By: cortinico

Differential Revision: D55225940

Pulled By: NickGerleman

fbshipit-source-id: 4cbab071928cb925baec45f55461559acc9a54e6
2024-03-25 12:23:16 -07:00
Blake Friedman a380ea55fb Summary: minor fix found in nightly logs from Publish NPM job (#43519)
Summary:
Minor fix to package.json which newer version of npm warn about when publishing, after running `npm pkg fix -ws` on the workspace.

{F1470070110}

## Changelog: [Internal] npm pkg fix -ws

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

Test Plan: eyescloseddog

Reviewed By: cortinico

Differential Revision: D55012872

Pulled By: blakef

fbshipit-source-id: ff3c63a3eefaf56d369219a3d4b32d44d6d842c9
2024-03-18 08:29:10 -07:00
Rubén Norte dceda565bd Fix RN tests in preparation for D54783723 (#43458)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43458

The React sync in D54783723 was failing because some tests were relying on `console.error` being called as `console.error('Some message')` but it was refactored as `console.error('%s..', 'Some message')`, making them fail.

This fixes the tests by formatting the arguments passed to the console functions and checking against that instead.

Changelog: [internal]

Reviewed By: sammy-SC

Differential Revision: D54849485

fbshipit-source-id: 0648263614725ea3f9c95b9f9bb13005adae46eb
2024-03-13 08:51:03 -07:00
Rick Hanlon 5126bace65 Fix VirtualizedList-test.js (#43377)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43377

Fixes `VirtualizedList-test.js`, which assumes fake timers (e.g. using `jest.runAllTimers()` and `jest.runOnlyPendingTimers()`) but did not actually use fake timers.

Changelog:
[Internal]

Reviewed By: yungsters

Differential Revision: D54668281

fbshipit-source-id: b14757744bb7a21a4e5573053549c36178826021
2024-03-07 23:19:27 -08:00
Alex Hunt f57be12977 Bump packages for next major release (#43132)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43132

Command run:

```
node scripts/releases/set-version 0.75.0-main --skip-react-native-version
```

Changelog: [Internal]

Reviewed By: lunaleaps, cipolleschi

Differential Revision: D54006327

fbshipit-source-id: 7afe9e7ca3020faf399fdba2221fab8a102c56c7
2024-03-04 07:54:37 -08:00
Sam Zhou 2053364e5a Update hermes-parser and related packages in fbsource to 0.20.0
Summary:
Bump hermes-parser and related packages to [0.20.0](https://github.com/facebook/hermes/blob/main/tools/hermes-parser/js/CHANGELOG.md).

Changelog: [internal]

Reviewed By: alexmckenley

Differential Revision: D54368487

fbshipit-source-id: a5a05f1e499ff5d8bda4649433bd285f7215d3da
2024-02-29 14:19:29 -08:00
Biki-das 6204ea36d3 - fixes component unmounting behaviour in itemSeperatorComponent (#43223)
Summary:
Reopen in reference to https://github.com/facebook/react-native/issues/42435 , as it had a lot of commits and fixes making it messed up.
Weirdly when using a [Section List](https://reactnative.dev/docs/sectionlist) specifically when using the [SectionSeperatorComponent](https://reactnative.dev/docs/sectionlist#sectionseparatorcomponent), and adding additional Data on the renderItem List, there is a unmount occurring as the new Data is added, this only happens while using the `SectionSeparatorComponent` and limited to the same

**Here is the Current Behaviour**

https://github.com/facebook/react-native/assets/72331432/0622e789-ddbc-4038-8ccc-a421050eecbf

**Here is the Expected Behaviour After Fixes**

https://github.com/facebook/react-native/assets/72331432/2f0cc3a9-da97-43f5-8a4b-3faca74ae834

The issues is happening because the Parent View gets removed, as we add Data, the separator moves causing the unmount, the solution that i proposed here is to conditionally render to make sure that our separator renders correctly which required to add an empty view as the `itemSeparatorComponent`.

## Changelog:
[General] [Added] - Fixes SectionList Unmounting issue with separatorComponent on data addition and removal.

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

Test Plan:
i used the `rn-tester` App to test out the changes below is the code to test the same.
Update the snapshots to align with the changes.

```
import React, {useEffect, useState} from 'react';
import {
  StyleSheet,
  Text,
  View,
  SafeAreaView,
  StatusBar,
  SectionList,
  Image,
} from 'react-native';

interface Item {
  id: string;
  title: string;
  imgSrc: string;
}

interface Section {
  title: string;
  data: Item[];
}

const keyExtractor = (item: Item, index: number) => `${item.title}-${index}`;

const renderItem = ({item, index}: {item: Item; index: number}) => {
  return <ItemComponent item={item} index={index} />;
};

const additionalFruits = [
  {
    id: '7',
    title: 'Sandwich',
    imgSrc:
      'https://img.freepik.com/premium-vector/sanwich-vector-isolated-fast-food_484148-2.jpg',
  },
  {
    id: '8',
    title: 'Burger',
    imgSrc:
      'https://static.vecteezy.com/system/resources/thumbnails/033/494/666/original/animated-illustration-of-burger-cartoon-for-foods-menu-animation-free-video.jpg',
  },
  {
    id: '9',
    title: 'Juice',
    imgSrc:
      'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHg9yLXE7Jlq4OM9ey64TW4D9qUFaeGU76rg&usqp=CAU',
  },
  {
    id: '10',
    title: 'Milkshake',
    imgSrc:
      'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcROpBez3eZKvEVdxBce9XyG6j6caDFMjV_xUQ&usqp=CAU',
  },
];
const DATA: Section[] = [
  {
    title: 'Items',
    data: [
      {
        id: '1',
        title: 'Cake',
        imgSrc:
          'https://static.vecteezy.com/system/resources/previews/012/132/227/original/cute-cake-cartoon-icon-illustration-food-recreation-icon-concept-isolated-premium-flat-cartoon-style-vector.jpg',
      },
      {
        id: '2',
        title: 'Pizza',
        imgSrc:
          'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR2kYjlsayzKZx4hFo6fbH7S8pde2JRo2a0hfaeoz3O7bjqdJjhI0tFiSROM8G4UbdbwXU&usqp=CAU',
      },
      {
        id: '3',
        title: 'Coke',
        imgSrc:
          'https://png.pngtree.com/png-clipart/20220116/original/pngtree-cartoon-hand-painted-coke-bottle-png-image_7106844.png',
      },
      {
        id: '4',
        title: 'Noodles',
        imgSrc:
          'https://thumbs.dreamstime.com/z/cute-cartoon-vector-bowl-noodle-isolated-white-background-115120959.jpg',
      },
      {
        id: '5',
        title: 'Pasta',
        imgSrc:
          'https://t4.ftcdn.net/jpg/02/65/00/69/360_F_265006936_2dlz2VtcqZZUbco1VnDpU2diyd8OagFS.jpg',
      },
      {
        id: '6',
        title: 'Fries',
        imgSrc:
          'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxISEBUQEBAVFRMTERkVFRISDw8PEBIVFRcWFhcSFRYYHSggGBolGxgVITEhJSkrLi4uFx8zODMtNygtLisBCgoKDg0OGxAQGismICYwLS4vLS0tLS0tLTUvLS0tLS0tLS0vLS0tLS0tLy0tLS0tLS0tLS0tLS0tLS0tLS0tLf/AABEIAOMA3gMBIgACEQEDEQH/xAAcAAEAAgMBAQEAAAAAAAAAAAAABQYCBAcDAQj/xABEEAACAQIBBwgEDAUEAwAAAAAAAQIDEQQFEiExQVGRBhMiYXGBscFSkqHRBxcjMkJygrLC0uHwJDNiY6IUNFPxFUOT/8QAGwEBAAIDAQEAAAAAAAAAAAAAAAQFAQIDBgf/xAAzEQACAQICBwcDBAMBAAAAAAAAAQIDEQQhBRIxQVFhkRNxgaGx0fAUIuEVI2LBJDLxBv/aAAwDAQACEQMRAD8A7iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYZ63riYuDMHxHji62ZByMVJKEXKWxGUruyPcGjhsoQm1FtKbTtFvXbXbebxrSqwqx1oO6EouLswADoYAAAAAAAAAAAAAAAAAAAAAAAAAAAABq4nFZjStfRfXY51asKUdabsjMYuTsjaILKVFZ0otaJL2PX5m9QylCdTmrNSzc7TazV7aGYZYp9FS3Oz7H+viV2kVDEYZzhnq5+/kd6N4VEnv+IrfJzGOjiOZk+jN5vUpfRl36u9FnyvLoLrfkyl5bp2mqi0X2rZJanw8Cw4jKCq0aM9s02/rRspLjcraGK/w6tN7ll4tJ+vmTq9LWqQqLft7188iFyhP5ehb/kX3ol8Od46pfE0ktjg+/P8A0RboZUfO06Uo/wAzOtJO1nFX0o6aHxMIJwltbVjXG05OMLbk/VslgYTnZNvYrkDlDK06UHNNN3Vk0rPTpXC5c4nGU8O0p3z4ECnSlUdolhBhTldJrar8TMlHIAAAAAAAAAAAAAAAAAAAAAGKknqZqY+epX62V/A5SccbKP0ZLMt1xTafHO4kCrj4wrKm1lvd9h3p4eU4uS3K5bSOyqvmvtXgamUcqukoye2ola2y95ey/E3sqroJ7mcsTXhiMNU1N1n5p/0ZhCUJRb3kG6mZiaEt8nB/asl4kzlGs/maLNad+kreXJNQjJa41E1wb8iVxuITk57LJ91kVFPFOGGlBPa15p39LeJLnT1nF8n6/kr+Mq85zlO3zW3D7Ozx4mjhcQ83Mvoi3JdTla/gj3yY71HJ7m+9tEfPoVJLYm+Gsrm7NpcCzhFf68MyZyZk2VSp/qKzsk06cdTlm6py6ty2+O9HFRli6MYu7hUafere888jYzncPCT1pZsu2Ojws+81cHG2Ph11E+Kv7yTh2lVhHmvVEaSlJz1tyeRcco10oON9L0FUytJSnTpN2Td5Pcm7X4ZxJ4qtd6e3iVrHVr1KkvQi0u22b4tm2Lxnb1dfcti+cbnLCUdX54HRKVeDgpxknBq6kmnG3aeeJxShG+u+q20qHJnEy5iVNvoqpdcNKXVezMMp4+UalovRGLbWxtq/u4llV0xJq0I5tbeD395w+gtUcb7PQ9sPyqqqu4SipwlUzUklGSu7LNe3v4l2OZ8lMNzmMp7oXm/srR/lmnTCZoqdWdJym287K/dnn3mNIU6dOajBWyz/AKAALMrwAAAAAAAAAAAAAACOyrDQpdz8isY75OvTrbG7Pq0WvwfsLnWp50XF7UVTKNHOhKD17OqSPNaWpdnWVRbJeqy9LFjgp5WfxM1uUKbUJbm1xt7iy85n4WM99OD79F/MrVSXO4a+1Rv3x1+D4kvkPEKeCtfTC8Xxzl7GjTR801Vg98X5f9OmIi1Tjyl6kXlr+V2SXu8zCdb+Gv8A27cVYzyy/kn2rxNKd5UKdNa5yjFcf0KpvJd5KhH7V3mvkypZu/V5kdleXTnZ7Pwot2HyVQpQbm77XJtxXckVvlDToaZUs/ObtpazHo2Jq+w3dFqTndHajWjOpkn32yPTkfXdqkNmiS7XofguBJOWZjKE98lHi838RFcmYNRuk25S2LYlb3m3liXRjOL+bJNNePFIwp9nWjLg15CpG9VrjddVYlMRWteWxK/BFcqP5GT2zml220+NzYxGNvRenTJ+yTu/Mzo0LypQeqN5vut5sjXtlz9MzNOOorv5YlMDTVKkovYry7dbIPFVG4SqPXUnZdi6T/CiSytXtTzVrk7d233d5A4xylUp0IvctGxzelnenmKMbvWfy2fsWvk1hI0qfOuVpzjdu9lGOtLwbJ3JGUuelNR0wgl03tbvoXVoK7lqtm01BbX/AIx/aLHyfwfNUIprpS6cu16l3KyLvRTnKpZPJLP5zeZV4pJwdSW1vL5yRKgA9EVoAAAAAAAAAAAAAABpV8U4ysrWRCY/EwlWko/OUU5Ldf8Aa4m9jm4zd1r0p7yjyxU41nOXzs55y8YnlcfXnUcqUtz2cPi8mWuEoKX3Lh1JvDdGc4bJfKLv0SXG3E1Mk4t0as6X0al423P6Ev3vMqldPMqxejOs+yWiz7HY8MbG2Ipy9Jx4ppeFirpVZRldbc/RomqKd1LevNG3luXyX2l4M0cnV86tQp+i87xa8GbWW38mvr+TIrITvjF/TB/dt5mYZo2gv2m+8sOX61qaj6UvYv1sVHKM9Nty8SwZdqXqKO6Ptb/6K/lJdP7KN5S2I3wkbJFvVCMcKqdHQnSTutcrq7b7fMg6M86nOnuV4+NuPiS+T694Zno6uwhsQubxHU37Jft8DlVlrJrxOdFPOPiRc3nSpxerOu+taPK5Y8O7zk9yUV95+KITm7VGt0nb2krh5ZlLOe5y9y4WRxrPJW+XJFXNKx4Yipn1uqGjvX6+BrZCjzmMc9kc6X4Y+N+4xc8yjKe2Wrv0LzZIcjMP0ZTf0pW7oq/i3wJMVaPka1Ptpyfh7knQo8/jYwemMPnbrR6Vu9tIu5WcZjo0Y3zdb0JWjd67mzyfx1Ss5SkkqcdC1tuWvX1LxL/RdaMP2krt538PQpcTGU4qexLInQAXpAAAAAAAAAAAAAAAANfFYdTjZ69j3MofKLAtNztaUdE14S/fUX3FqXNzzHaWY817pWdnxOUYnL+JqPp1U9FtMKS0btESi0vRi3GS/wBvJrnzV8snw4FzomhVquTi1ZW23334J8D0w+JzU4v5slp6nskjerVtFN7qkbPcm1+hX6WItJOWmN1ddW32G5UrOClCT1PQ9zi78HYoqlFpplxVw7jJX3k9lv8Alr6/kzR5NU/4ipL0YW75ZvuZM43CZ2HnUldWpupFandRb0kfybh0ak/Skl6sV72c4pxhmQozTpSS7jHKUr133eCI3FYaVSvGnG2dJJK7stulm9jn/EPtX3UfMEv42m90G/ZMxf713HWL1YXXAka2DjQlCbq3bTjmKOluTjpvfUrI0Msq86e9u3tXvNrlBPp0n1vxiRmKxGfiacY6k03xbt7DFTOSaW5mlFN2k+ZjUjfENb5G3lSdoKK+k7dy/aNWH+5+2/BkbyoyjKNWMIStmRu9CfSenb1W4nOnTdSpGK4XJNKk6tSMVwueuWKls2mtiv5LzLXyeo5lKMfRWntbu/M5hWylVc87O6StpzVrXcK3KrGU7KFe19L6FJ+MSyWEm7JNefsd62jqkoaqcfP2Oj5UnKrXVKGlpqKX9T1+XAu2AwqpU4046orXve197OPfBtlTE18pQU6zlFRnOacIaVmta0tHSlE7WX2jMN2cXN7Xl4flnndKQlRlGi3sV8vEAAtCrAAAAAAAAAAAAAAABxTK1Hm61Wn6FWUe5SaXsO1nI+XdHMxtTdLNkvtRV/amVuk43hGXB+qL/wD8/L96cOKv0fsyDlImsi4iLq0ZySdpxhJNXWnown4d8SvuR9o4hwd12NbGtxS6qkeoxGH7Wm47zq2PrRzZQ1uUXF22XVir5Lqyo1HQnqbvF7L9Xb4o8clcoaclm1ZZstkpan2vf1m9j8Oq0M6DTlHTGUWnfquiHUvnGew84qEsO3TqK1/lzUxUvl39ZeCPbB/7qL/tvz95HUqzlNOWvOV9mnUSeDj8vnbqT9sl+pFl9slfgztNWi1yGX5dOn3+KIvJ3SxTfo39izfM2sr1b1lujH3v3EZkzKNOlKc6ktNrJLpSbbu7cNpsk5Qeqru3qb0oSdO0Vd29Tbq4qNOpKpLVFydtrelJLtZUsXXcpSqS+c22+1mxlDGurJvVG7aj27X1kbWlptuLPD0OzV3taLrC4fso3e1+XIwNHGPpdiN0jqzvJ9pNhtO09h0b4EsNfEV6uyFFQ9eSl+A7Ec5+BbC2wlWrb59ZRvvUIR08ZS4HRi5wytTR4PS09fGT5WXRe9wADuVwAAAAAAAAAAAAAAAObfCnQtVpVfSp5vqSv+M6SUz4T8PfCRqL/wBdVX+rJNeOaRcZHWoy69Cz0NU1MbDnddVZedjlzkYOQcjC5Qn0BINn2E5LSm+1Npny58NrGT1WKmndTlffzkr+J6f+Tr/81TuqVF5msfDVwi9qXQ01I8F0M6laUneUm3vlJyftMDEXNjKyVj5OVkazZlUldmBukYYbI5G7Xdos06cG5RjFXblZJa23oSOsDlLaj9A/BvguZyZQT1yi6j+221/i4loNXJ2EVKjTpLVTpxguyMVHyNovIq0Uj5vWqdpUlN7231YABscwAAAAAAAAAAAAAAAQ/KnB87g69NK7dJuK/qh04+2KJg+MxKKknF7zenN05qcdqafQ/O20+NkjyjwPMYqtRSsozeb9WWmH+LRGnmrNOzPp0ZqcVKOx2a7nmj4AfLgyBcHy4APKrPYfZzseLNkjDADZ8ubGDwxctCXWS3ILA89lLDwtdKopy3Wppz0+ql3kJiJXl2HSfgUyZ8rXxTWiMFTi9nTec+9KMfWJWHjrSSK3SVbssPUlyt1yR10AFweBAAAAAAAAAAAAAAAAAAAAAOXfCvk7Nq0sQlonHm5bs6Oni4t+oUK523lvk3n8FVileUFzkd94aWl2xzl3nEeopcbT1at+OZ7nQOI7XCKL2xy8Nq9vA+ny5g5GLqESxcnoecqh5ymY3MpGGw2LmINzUCTsrg8sTLRbeErsw3Y1us/QXwdZL/0+T6UWrSqLnpbHepa1+tQUF3HE+SuSv9VjKNG3RlVTlr0Qh0pdnRT4o/SSVtCLLBwzcjy+n69lCiu9+i/vyMgATzzIAAAAAAAAAAAAAAAAAAAAB8scA5X5NeGxdWl9HPzobsyXSjbsTt9ln6AK7yh5JYbGTjUrZ6lGGZenKKvFNtJ3TvZt8WRsTQdWKttRa6Jx8cJVbnfVas7Z93t3M4PcXOy/Flgd9b16f5D58WOB31vXp/kIP0VTl1PQfr+D/l0/JxkHZviywO+t69P8g+LLA763r0/yD6Kpy6j9ewn8un5OMg7N8WWB31vXp/kHxZYHfW9en+QfRVOXUfr2E/l0/Jxo0687vs0HcfiywO+t69P8h5fFVgPSrf8A1h+Q2jg6nI1lp7CPZrdPyQfwLZH/AJuMkv7UPZKb+4r9p1cjsiZJpYWhGhRTzIX+c86Tcm5Nt7XdkiWNKGpBI8tjcR9RXlU3PZ3LYAAdCKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/Z',
      },
    ],
  },
];

const ItemComponent = ({item, index}: {item: Item; index: number}) => {
  useEffect(() => {
    console.log('Mount of', index, item.title);
    return () => {
      console.log('Unmount of', index, item.title);
    };
  }, []);

  return (
    <View style={styles.card}>
      <Text style={styles.cardText}>{item.title}</Text>
      <Image source={{uri: item.imgSrc}} style={styles.imageStyles} />
    </View>
  );
};

const App = () => {
  const [data, setData] = useState(DATA);
  const fetchNextPage = () => {
    const newInnerData = [...data[0].data, ...additionalFruits];
    setData([{...data[0], data: newInnerData}]);
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.scrollView}>
        <SectionList
          keyExtractor={keyExtractor}
          onEndReachedThreshold={0.5}
          onEndReached={fetchNextPage}
          sections={data}
          renderItem={renderItem}
          ItemSeparatorComponent={() => <View style={{height: 16}} />}
          renderSectionHeader={({section}) => (
            <Text style={styles.sectionHeaderText}>{section.title}</Text>
          )}
        />
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5F5F5',
    paddingTop: StatusBar.currentHeight,
  },
  scrollView: {
    paddingHorizontal: 16,
  },
  card: {
    backgroundColor: '#FFFFFF',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 8,
    height: 200,
    padding: 16,
    borderRadius: 8,
    marginBottom: 16,
    borderWidth: 1,
  },
  cardText: {
    fontSize: 30,
  },
  headerText: {
    fontSize: 24,
    textAlign: 'center',
    marginBottom: 12,
  },
  footerText: {
    fontSize: 24,
    textAlign: 'center',
    marginTop: 12,
  },
  sectionHeaderText: {
    backgroundColor: '#FFFFFF',
    fontSize: 24,
    fontWeight: 'bold',
  },
  imageStyles: {
    height: '100%',
    width: 100,
  },
});

export default App;
```

Reviewed By: yungsters

Differential Revision: D54301991

Pulled By: javache

fbshipit-source-id: d2cfafb1b4eb868761d849111b5abb7e9d584a46
2024-02-29 02:38:46 -08:00
Jakub Romanczyk 62c15bacaa fix(virtualized-lists): declare missing react peer dependency (#42947)
Summary:
In setups with `pnpm`  `react-native/virtualized-lists` gets bundled incorrectly because of the following error:

`Module not found: Error: Can't resolve 'react'`

As 'react' is used inside of the package, it should declared explicitly, instead of being a phantom dependency.

## Changelog:

[GENERAL] [FIXED] - Declare missing peer dependency `react`

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

Test Plan: not needed

Reviewed By: NickGerleman

Differential Revision: D53617462

Pulled By: cortinico

fbshipit-source-id: 19a8fed94263646b0af93339d5c014e629dfa6b1
2024-02-10 17:03:15 -08:00
Janic Duplessis 4dcc1d3efb Fix onStartReached not called when list content is small (#42902)
Summary:
Currently if the virtualized list content is small `onStartReached` won't be called initially when the list is mounted. This is because when the content is small `onEndReached` will be called initially preventing `onStartReached` from being called. In `_maybeCallOnEdgeReached` calling `onEndReached` and `onStartReached` are in the same conditional so they cannot both be triggered at once. To improve the consistency of `onStartReached` we should call both `onEndReached` and `onStartReached` if needed.

## Changelog:

[GENERAL] [FIXED] - Call onStartReached initially when list is small and `onEndReached` is called

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

Test Plan:
I used this code to test in RN Tester (replace content of RNTesterAppShared.js)

```ts
import React, { useState, useEffect } from "react";
import { StyleSheet, FlatList, View, Text, TouchableOpacity } from "react-native";

function App() {
  const [data, setData] = useState(generatePosts(4));
  const [idCount, setIdCount] = useState(1);

  const renderItem = ({ item }) => <Item data={item} />;
  const keyExtractor = (item) => item.id.toString();

  console.log("-------")
  return (
    <View style={{ flex: 1, marginVertical: 20 }}>
      <FlatList
        key={idCount}
        data={data}
        renderItem={renderItem}
        keyExtractor={keyExtractor}
        onEndReachedThreshold={0.05}
        onEndReached={() => console.log("onEndReached")}
        onStartReachedThreshold={0.05}
        onStartReached={() => console.log("onStartReached")}
        inverted
      />
      <TouchableOpacity  style={{height: 50, width: '100%', backgroundColor: 'purple'}} onPress={()=>{
          setIdCount(state => state + 1)
          setData(generatePosts(2))
      }}><Text> Press</Text></TouchableOpacity>
    </View>
  );
}

function Item({ data }) {
  return (
    <View style={styles.item}>
      <Text style={styles.title}>
        {data.id} - {data.title}
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  item: {
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 24,
  },
});

const generatePosts = (count, start = 0) => {
  return Array.from({ length: count }, (_, i) => ({
    title: `Title ${start + i + 1}`,
    vote: 10,
    id: start + i,
  }));
};

export default App;
```

Before the change only onEndReached is called, after the change both onStartReached and onEndReached is called.

Reviewed By: sammy-SC

Differential Revision: D53518434

Pulled By: cipolleschi

fbshipit-source-id: bc34e0d4758df6d5833be7290e5a66efaf252ffd
2024-02-07 20:44:34 -08:00
Michael Lohmann 35f5c3a204 VirtualizedList/FlatList: Stricter typing for onViewableItemsChanged (#42773)
Summary:
The previous typing of FlatList and VirtualizedList did not convey any information on the type of the items passed in to `onViewableItemsChanged`, but instead the type was set to `any`. This PR adds the type information.

I set a default type `any` for thy ViewToken, because the type is exported and not having it would be a breaking change if that type is used. Like this it gracefully falls back to the default behavior of the `any` type.

Notice: I don't know how typing in "flow" works, but the same "issue" seems to be in there as well. Maybe someone with more flow experience can fix that as well:
https://github.com/facebook/react-native/blob/ae42e0202de2c3db489caf63839fced7b52efc5d/packages/virtualized-lists/Lists/ViewabilityHelper.js#L19-L20

## Changelog:

[GENERAL] [FIXED] - Add type information for items of VirtualizedList in `onViewableItemsChanged` signature
[GENERAL] [FIXED] - Add type information for items of FlatList in `onViewableItemsChanged` signature

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

Test Plan:
Without the changes, typecheck of the project was fine, but with the changes applied to the node_modules/react-native copy a type error was found:
```
$ npm run typecheck

> my-project@1.0.0 typecheck
> tsc --skipLibCheck

src/MyComponent.tsx:385:29 - error TS2345: Argument of type '(string | number)[]' is not assignable to parameter of type 'number[]'.
  Type 'string | number' is not assignable to type 'number'.
    Type 'string' is not assignable to type 'number'.

385                             viewableItems
                                ~~~~~~~~~~~~~
386                                 .filter(
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

Reviewed By: rozele

Differential Revision: D53276749

Pulled By: NickGerleman

fbshipit-source-id: 3fa5c65b388a59942c106286ac502a85c583da50
2024-02-01 15:25:10 -08:00
Fabrizio Cucci 9bd69d329a Drop stale comment in VirtualizedList (#42395)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42395

T46547044 has been closed and apparently `React.warn` was removed in [#16126](https://github.com/facebook/react/pull/16126).

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D52907508

fbshipit-source-id: a3621d876f904339791ab184a904e81f7a50b988
2024-01-19 10:38:46 -08:00
Janic Duplessis 3ed4bf9046 Fix last spacer constrain logic in VirtualizedList (#41846)
Summary:
The logic to constrain the last spacer size is incorrect in some cases where the spacer is the last spacer, but not the last section in the list.

For more context, the role of spacer constraining is explained in this comment:

```
// Without getItemLayout, we limit our tail spacer to the _highestMeasuredFrameIndex to
// prevent the user for hyperscrolling into un-measured area because otherwise content will
// likely jump around as it renders in above the viewport.
 ```

For example it is incorrect in the case where we have:

ITEMS
SPACER
ITEMS

In this case the spacer is not actually the tail spacer so the constraining is incorrectly appied.

This causes issues mainly when using `maintainVisibleContentPosition` since it will cause it to scroll to an incorrect position and then cause the view that was supposed to stay visible to be virtualized away.

## Changelog:

[GENERAL] [FIXED] - Fix last spacer constrain logic in VirtualizedList

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

Test Plan:
Tested using https://gist.github.com/janicduplessis/b67d1fafc08ef848378263208ab93d4c in RN tester, before the change content will jump on first click on add items.

Tested using the same example and setting initial posts to 1000, then we can see our content view size is still constrained properly (see scrolling indicator as reference).

Reviewed By: yungsters

Differential Revision: D51964500

Pulled By: NickGerleman

fbshipit-source-id: 4465aa5a36c95466aef6571314973c1e2c9a0f2c
2023-12-12 09:49:49 -08:00
Pieter De Baets 050a5a3797 Fix CellRenderer onCellFocusCapture not being stable (#41381)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41381

Noticed that when scrolling VirtualizedList's CellRenderer was re-rendering due to `onCellFocusCapture` not having a stable identify. Change the interface to CellRenderer to pass in the `cellKey` in the callback to save on creating new callbacks.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D51112928

fbshipit-source-id: 3fcb974d9b5585403895746fbc45f2cf5a9fa6b1
2023-11-08 15:16:54 -08:00
Moti Zilberman d6e0bc714a Enable lint/sort-imports everywhere (#41334)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41334

TSIA.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D51025812

fbshipit-source-id: e10d437be775a6b80946483aa96460f34927f870
2023-11-06 12:59:38 -08:00
Nick Gerleman 817fedb0e7 Bail on hiPri render on missing layout data before checking priority (#41270)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41270

`scheduleCellsToRenderUpdate()` is called in response to new measurements, or component changes. It has logic to decide whether to immediately calculate new state, or to defer it until a later batched period.

It will not immediately update state if we don't yet have measurements for cells, but this condition is after another which calculates priority, relying on these measurements. These are garbage if we don't yet have measurements, and trigger an invariant violation in horizontal RTL.

This switches around the conditions, to avoid offset resolution if we don't yet have valid measurements.

I suspect some "hiPri" renders where cells shift are bugged right now when we update state in response to content size change, before we have new corresponding cell layouts.

Changelog:
[General][Fixed] - Bail on hiPri render on missing layout data before checking priority

Reviewed By: yungsters

Differential Revision: D50791506

fbshipit-source-id: 8dbffc37edd2a42f7842c0090d344dcd6f3e3c6d
2023-10-31 16:49:58 -07:00
Samuel Susla e8a0f0d067 filter out onContentSizeChange from defaultRenderScrollComponent (#41113)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41113

changelog: [internal]

We must prevent VirtualizedList._onContentSizeChange from being triggered by a conflicting bubbling onContentSizeChange event.
For TextInput, we change the event onContentSizeChange from bubbling to direct (https://github.com/facebook/react-native/commit/744fb4a0d23d15a40cd591e31f6c0f6cb3a7f06b). To make this safer, we need to filter out any `onContentSizeChange` event since we can't control 3rd party components from dispatching onContentSizeChange as bubbling event.

Reviewed By: NickGerleman

Differential Revision: D50451232

fbshipit-source-id: b7a446e4efc9c45024d37f35cb53f2fcbb28799f
2023-10-23 02:16:11 -07:00
Gijs Weterings 67c1a806e6 Flow strictify xplat/js/react-native-github where possible (#41051)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41051

Strictifies flow to flow strict-local in files where doing that doesn't cause new flow errors.

Changelog: Internal

Reviewed By: yungsters

Differential Revision: D50369011

fbshipit-source-id: b4a5a26b839b7327a3178e6f5b35246dea365a38
2023-10-18 05:36:33 -07:00
Sam Zhou 11d9b9cef0 Prepare to make React.Element fully opaque (#40798)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/40798

Changelog: [Internal]

Reviewed By: sullenor

Differential Revision: D50194982

fbshipit-source-id: 21d2f86dd787952ceed9a4f862a3fcaa2b063349
2023-10-12 08:43:32 -07:00
Alex Hunt f40bb9331c Bump package versions for next major (#39764)
Summary:
#publish-packages-to-npm

Bump all package versions to `0.74.0` (next major release) for `main`, following instructions at https://reactnative.dev/contributing/release-branch-cut-and-rc0#12-bump-minor-version-of-all-monorepo-packages-in-main.

```sh
yarn bump-all-updated-packages --release-branch-cutoff
```

Changelog: [Internal]

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

Test Plan: —

Reviewed By: robhogan

Differential Revision: D49871039

Pulled By: huntie

fbshipit-source-id: f4df6efeae4d8a9209e7aae7b9e6fea3d15793b5
2023-10-11 08:36:23 -07:00
Nick Gerleman 22a7b8dd37 Remove code to support bottom-up layout events in horizontal RTL (#39646)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39646

We can dramatically simplify this code and remove quirks/hacks, now that we can assume layout events are always fired top down.

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D49628669

fbshipit-source-id: 7de5bbc4597eba1c59aaa7672c70e76d2786c7ef
2023-10-10 11:43:14 -07:00
Nick Gerleman a2fb46ec0d Fix invariant violation when using viewability callbacks with horizontal RTL FlatList on Paper (#39335)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39335

In RTL we must have scrollview content length in order to resolve cell metrics. This means that on Paper, where layout events are bottom up, we cannot immediately calculate viewability in response to cell metric changes, as we may not yet have an accurate length of laid out list content.

This change makes us defer calculation of viewability changes in this case via `setTimeout()`, to run in a single batch after the next layout events are fired.

 ---

We need container dimensions to resolve the right-edge relative child directions. It is tricky to do this at a guaranteed right time with onLayout model on Paper.
When we are laying out children, the first layout on Paper looks like:

1. Child is laid out

2. Container is laid out

However, we will never see container onLayout if a child layout does not change the dimensions of the parent container. This will be the common case of subsequent child layouts, where the spacer size was accurate.

I.e. we may or may not ever see content laid out, but can only rely on having both offsets be up to date if we trigger calculation after the container layout would have happened. This is not an issue on Fabric where layout events are fired top-down, or for the most common cases of VirtualizedList, where we run calculations in idle batches that will happen after layout is set, but ends up causing problems for two scenarios I didn't originally account for:

We may recalculate cells to render immediately instead scheduling a later update if the list thinks blanking is immediate (high priority render). This means we cannot do an immediate update in response to cell layout, but we can in response to events batched after layout events are all dispatched, or in worst case delay in Paper RTL.
We do not batch/schedule viewability calculations in response to cell layout in the same wasy as we do for calculating cells to render, but do need them to trigger recalculation.

The way less hacky, but much more invasive solution, that would simplify a lot of this, would be to include parentWidth and parentHeight in onLayout events for Paper (and Fabric for consistency), so that we don't need to rely on event ordering, or sometimes not firing. I thought this would be too much at first, if we didn't have other use-cases, but am more and more tempted to tear down a lot of what we have here to do that instead, since this is not going to be able to rely on useLayoutEffect or IntersectionObserver in today's VirtualizedList because it will need to support Paper for the forseeable future..

Changelog:
[General][Fixed] - Fix invariant violation when using viewability callbacks with horizontal RTL FlatList on Paper

Reviewed By: yungsters

Differential Revision: D49072963

fbshipit-source-id: accd33e2c50935bb67700d94820f6418f130fe08
2023-09-11 18:35:50 -07:00
Nick Gerleman 4f8a8ce316 Fix inverted contentOffset in scroll events in RTL (#39031)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39031

`UIScrollView` `contentOffset` is flow-relative, so `x` is relative to the right edge of the screen. This coordinate space disagrees with layout events, `scrollTo` coordinates, and other platforms.

This applies the same logic we use for inverting `scrollTo` coordinates to invert `contentOffset` in scroll events, in both Paper and Fabric. We then remove the iOS specific workaround we have in VirtualizedList.

I did not test `contentInset` as part of this, whose structure has explicit edges like `left` and `right`.

Changelog:
[iOS][Fixed] - Fix inverted `contentOffset` in scroll events in RTL

Reviewed By: rozele

Differential Revision: D48379915

fbshipit-source-id: 8a9cbb01608e79ef3b179a76fbe3997a0cd23845
2023-08-21 18:03:43 -07:00
Nick Gerleman c522837d9e ListMetricAggregator UTs - contentLength caching (#38738)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38738

UTs about returned cached content length and cached content length requirement in RTL.

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D47978634

fbshipit-source-id: 509b2b60cae4a8755745710fb5872da27c8ce7a3
2023-08-17 21:31:31 -07:00
Nick Gerleman 298d297e54 Null out ListMetricsAggregator contentLength on orientation change (#38937)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38937

It is a logic error to query for list metrics when a valid list content length has not yet been observed.

An invariant is meant to catch this if it happens, but a non-default orientation causes us to zero out a value which is null, and our null check does not catch this, and we return a nonsense value.

Change from zeroing out the field to nulling it out instead.

Changelog: [Internal]

Reviewed By: lenaic

Differential Revision: D48251645

fbshipit-source-id: 5c7e16f694db4ddb0d37b6092de2e75ee8d6c7d3
2023-08-17 21:31:31 -07:00
Nick Gerleman be2bb51c70 ListMetricAggregator UTs - cell offset APIs (#38732)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38732

Unit tests for cell offset APIs. Mostly the same as previous UTs for VirtualizedList a layer higher.

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D47978633

fbshipit-source-id: 8cb8a2e8125bc7370eabf9f01a3f7529043171c2
2023-08-15 21:56:25 -07:00
Nick Gerleman 966f97acdc ListMetricAggregator UTs - cached measurement adjustment after layout changes (#38936)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38936

Unit tests that validate we continue to return correct measurement results through the lifetime of the list when cells are unmounted, or layout of the list shifts.

Changelog: [Internal]

Reviewed By: lenaic

Differential Revision: D47978632

fbshipit-source-id: b700fafb699e8820de6825f0ead1ef02c6d8f168
2023-08-15 21:56:25 -07:00
Luna Wei 824c1c6d07 Math.floor the top, bottom values of an item in a VirtualizedList (#38962)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38962

Changelog: [General][Changed] Math.floor the top and bottom dimensions of a cell item when determining viewability.

Reviewed By: NickGerleman

Differential Revision: D48212402

fbshipit-source-id: 0ba7d5c218477c257a4504391940d916e4832f91
2023-08-11 13:57:21 -07:00
Nick Gerleman 0e69050612 Use right edge of ScrollView viewport for scrollMetrics.offset in RTL
Summary:
The offset we record should be the one closest to the reference zero-point in the coordinate space. This makes scroller offset reference match the cell reference we keep in D47978631.

Changelog:
[General][Fixed] - Use right edge of ScrollView viewport for `scrollMetrics.offset` in RTL

bypass-github-export-checks

Reviewed By: lenaic

Differential Revision: D48132236

fbshipit-source-id: 3307081e5e859f1b4afbc15a84c5be1b33915206
2023-08-07 19:36:07 -07:00
Nick Gerleman 9eec875a17 ListMetricAggregator UTs - cell measurement (#38735)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38735

UTs around cell measurement results through `getCellMetrics` and `getCellMetricsApprox`. For each orientation, validate basic scenarios for approximation, cached measurement, or measurement by user-provided `getItemLayout`.

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D47978630

fbshipit-source-id: 4c9ba6a60599848034f4f23cde3497dd4c2b8788
2023-08-04 10:37:57 -07:00
Nick Gerleman f3b2d2c759 ListMetricAggregator UTs - statistics collection (#38740)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38740

UTs around ListMetricsAggregator APIs which calculate statistics (average length, max measured index).

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D47978636

fbshipit-source-id: fe83a1fed939fca3d59ecca32945825d3c112739
2023-08-04 10:37:57 -07:00
Nick Gerleman ace0a80dea Fixup contentLength invalidation logic (#38733)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38733

I was working under the assumption that Fabric fired layout events bottom up, but it actually fires them top-down, in constrast to Paper.

Previous invalidation logic wasn't quite correct when fired bottom-up. This corrects the logic by:
1. Deriving direction based on initial event ordering
2. Use last cached contentLength if we are on Fabric (top-down)
3. Use future contentLength if we are on Paper (bottom-up)

Changelog:
[General][Fixed] - Fixup contentLength invalidation logic

Reviewed By: rozele

Differential Revision: D47978638

fbshipit-source-id: 3446d08aa34397b4e6bd9924dad0eba36a12a115
2023-08-04 10:37:57 -07:00
Nick Gerleman 5596f1c25b Right align scrollToIndex in RTL (#38737)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38737

This fixes up behavior on Android so that `scrollToIndex` aligns the right edge of the cell of the given index to the right edge of the scrollview viewport. We do not incorporate RTL on iOS which inverts x/y coordinates from scroller (but not layout).

Changelog:
[General][Fixed] - Right align scrollToIndex in RTL

Reviewed By: lenaic

Differential Revision: D47978637

fbshipit-source-id: 7786b5d97efaced318018409e2c7577a3d8f7402
2023-08-04 10:37:57 -07:00
Nick Gerleman 7319a28d22 Return right edge in RTL Cell metrics (#38734)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38734

Returned measurements from the measurements cache in RTL calculate offset as distance from the left edge of the cell to the right edge of the content, when it should instead be the distance from the right edge of the cell (the logical beginning).

Changelog:
[General][Fixed] - Return right edge in RTL cell metrics

Reviewed By: lenaic

Differential Revision: D47978631

fbshipit-source-id: b0db4e9aff676c5bee81d4491f901a6bbc38e4bf
2023-08-04 10:37:57 -07:00