Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Generic Discontiguous Regions within VirtualizedList #32638

Closed

Conversation

NickGerleman
Copy link
Contributor

@NickGerleman NickGerleman commented Nov 21, 2021

Summary

This builds upon the CellRenderMask data structure added with #31420, and VirtualizedList coverage added with #31401, to allow more discontinuous structures in VirtualizedList. This enables keyboard/a11y scenarios, where focus may be outside of a viewport-derived region.

VirtualizedList currently keeps a [first, last] range as state, tracking the region of cells to render. The render functions uses this as an input, along with a few special cases to render more (sticky headers, initial render region.)

This change moves to instead keep state which describes discontinuous render regions. This mask is continually updated as the viewport changes, batch renders expand the region, etc. Special cases are baked into the render mask, with a relatively simple transformation from the mask to render function.

MS/FB folks have a video discussion about VirtualizedList here: https://msit.microsoftstream.com/video/fe01a1ff-0400-94b1-d4f1-f1eb924b1809

Changelog

[Internal] [Added] - Discontiguous VirtualizedList Regions

Test Plan

#31401 added quite a few snapshot tests, centering around the logic this change is touching. I manually validated RNTester FlatList examples (and there should be some upstream UI testing for them).

Builds upon the `CellRenderMask` data structure added with facebook#31420, and VirtualizedList coverage added with facebook#31401.

VirtualizedList currently keeps a [first, last] range as state, tracking the region of cells to render. The render functions uses this as an input, along with a few special cases to render more (sticky headers, initial render region.)

This change moves to instead keep state which describes discontiguous render regions. This mask is continually updated as the viewport changes, batch renders expand the region, etc. Special cases are baked into the render mask, with a relatively simple tranformation from the mask to render function.

This representation makes it much easier to support keyboarding scenarios, which require keeping distinct regions (e.g. for last focused) realized while out of viewport.

MS/FB folks have a video discussion about VirtualizedList here: https://msit.microsoftstream.com/video/fe01a1ff-0400-94b1-d4f1-f1eb924b1809

facebook#31401 added quite a few snapshot tests, centering around the logic this change is touching. I manually validated RNTester FlatList examples (and their should be some upstream UI testing for them).
@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. p: Microsoft Partner: Microsoft Partner labels Nov 21, 2021
}
}
/>
<View
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some cases like this, where we render less, but the new behavior looks more correct to me given inputs.

@react-native-bot react-native-bot added the Type: Enhancement A new feature or enhancement of an existing feature. label Nov 21, 2021
@analysis-bot
Copy link

analysis-bot commented Nov 21, 2021

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: 51fe190
Branch: main

@NickGerleman
Copy link
Contributor Author

FYI to reviewers, there is quite a bit of code where chunks of logic have moved. I've tried to keep most of the existing blocks where possible, but you might need to hop around a bit to see where some of the chunks came from.

@analysis-bot
Copy link

analysis-bot commented Nov 21, 2021

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 8,479,777 +192,259
android hermes armeabi-v7a 7,778,988 +159,362
android hermes x86 8,948,552 +190,623
android hermes x86_64 8,892,626 +196,328
android jsc arm64-v8a 9,793,613 +117,652
android jsc armeabi-v7a 8,754,038 +89,276
android jsc x86 9,742,330 +110,441
android jsc x86_64 10,343,151 +115,306

Base commit: 51fe190
Branch: main

NickGerleman added a commit to NickGerleman/react-native that referenced this pull request Nov 23, 2021
This change also includes the contents of facebook#32638

This change makes VirtualizedList track the last focused cell, through the capture phase of `onFocus`. It will keep the last focus cell, and its neighbors rendered. This allows for some basic keyboard interactions, like tab/up/down when on an item out of viewport. We keep the last focused rendered even if blurred for the scenario of tabbing in and and out of the VirtualizedList.

Validated via UT.
Copy link
Contributor

@lunaleaps lunaleaps left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to split up this diff into just changing the state representation of the existing contiguous region and then the changes in supporting discontiguous?

Or perhaps even more granular if possible in other aspects in the case that something ends up breaking some of our products, it might be clearer which parts are problematic or reveals problematic assumptions. And additionally if we could use a feature flag

@NickGerleman
Copy link
Contributor Author

I didn't see a straightforward way to split this much further. The discontiguous regions added to the mask are present before, but special cased into the render function.

I agree we should gate this though. Way long ago, @TheSavior recomended keeping the changes inline for review, then cloning to a second component that can be injected before merging. That would allow FB folks to flight the change (the infrastructure is not in OSS).

We're separately doing a gated rollout of this to Office right now.

@NickGerleman
Copy link
Contributor Author

I can also let this change rest until we get feedback from a production-level audience internally.

@github-actions
Copy link

This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Jun 16, 2022
@github-actions
Copy link

This PR was closed because it has been stalled for 7 days with no activity.

@github-actions github-actions bot closed this Jun 24, 2022
NickGerleman added a commit to NickGerleman/react-native that referenced this pull request Jul 20, 2022
This change also includes the contents of facebook#32638

This change makes VirtualizedList track the last focused cell, through the capture phase of `onFocus`. It will keep the last focus cell, and its neighbors rendered. This allows for some basic keyboard interactions, like tab/up/down when on an item out of viewport. We keep the last focused rendered even if blurred for the scenario of tabbing in and and out of the VirtualizedList.

Validated via UT.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Needs: React Native Team Attention p: Microsoft Partner: Microsoft Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. Stale There has been a lack of activity on this issue and it may be closed soon. Type: Enhancement A new feature or enhancement of an existing feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants