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

Fix FocusScope StrictMode issues #3878

Merged
merged 16 commits into from
Jan 11, 2023
Merged

Fix FocusScope StrictMode issues #3878

merged 16 commits into from
Jan 11, 2023

Conversation

LFDanLu
Copy link
Member

@LFDanLu LFDanLu commented Jan 3, 2023

Closes

An alternative refactor for FocusScope has been started in focusscope_strict_refactor_all_things that changes how the focusscope tree is constructed. This branch should serve as a new baseline

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

Note: test off the branch locally for strictmode. You'll have to pull in the changes in #3870 (provides a strictmode checkbox toggle) or from #3837 in order to test the storybook with strict mode. Without either of those changes, the strict mode storybook always crashes with the Rendered more hooks than during the previous render. error.

Turn on StrictMode and do a test sweep. There shouldn't be anymore FocusScope related crashes (aka TypeError: Cannot read properties of undefined (reading 'parent')). Components that render collections may rendering issues still

Running the strict mode tests will yield a mixed bag of passes/fails due to other strict mode bugs.

🧢 Your Project:

RSP

@LFDanLu LFDanLu force-pushed the focusscope_strict_mode_fix branch from d9a63bf to ff373a7 Compare January 3, 2023 21:57
@LFDanLu LFDanLu changed the title (WIP) Fix FocusScope StrictMode issues Fix FocusScope StrictMode issues Jan 3, 2023
Copy link
Member

@snowystinger snowystinger left a comment

Choose a reason for hiding this comment

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

generally looks good, one small comment

@@ -137,7 +137,14 @@ describe('ButtonGroup', function () {
};
let {getByTestId} = render(<ButtonGroupWithRefs setUp={setUp} />);
let buttonGroup = getByTestId(buttonGroupId);
expect(buttonGroup).not.toHaveAttribute('class', expect.stringContaining('spectrum-ButtonGroup--vertical'));

if (process.env.STRICT_MODE) {
Copy link
Member

Choose a reason for hiding this comment

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

can we solve this with the util we worked on instead? I'd prefer the results be the same

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm a bit tricky due to how setUp is called in the useEffect in ButtonGroupWithRefs which means our mock implmementations aren't actually set until the first overflow measurements happen in ButtonGroup. Digging now

Copy link
Member Author

Choose a reason for hiding this comment

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

I opted to remove the first expect that this test originally had since it was an assertion made before any of our mock widths even were applied (aka widths were undefined for the button/buttongroup). That felt a bit unrealistic for the test and would require me to set the mock widths to 0 for StrictMode to preserve that assertion's logic so I removed it instead

snowystinger
snowystinger previously approved these changes Jan 5, 2023
Base automatically changed from strict-mode-fixes to main January 5, 2023 23:32
LFDanLu added 14 commits January 5, 2023 15:51
fix case where deleting a row via actionbar didnt restore focus to the new first row.
since strict mode unmounts and rerenders the dialog, we will always run into the "unmounted while open" error in the tests if defaultOpen or isOpen is true. Since I think we cant distingush a true unmount case vs strict modes unmount case, I opted to suppress the warning in the test instead
in strict mode, the layouteffect cleanup triggers even when the focusscope hasnt unmounted. This makes activeScope inaccurate and breaks the parentScope for future nested focusscopes (e.g. nested dialog trigger case)
the previous expect was relying on the fact that ButtonGroup first measurement happened before we mock the widths and positions of the buttons + buttongroups. That doesnt work well in strict mode and didnt feel reflective of browser behavior so I removed that expect
let {addParentToFocusScopeTree: addParentToTreeMap} = useContext(FocusContext) || {};

// Call to add current scope to Tree if it hasn't been added yet. Adds parent scope to Tree if it doesn't exist.
let addParentToFocusScopeTree = useCallback(() => {
Copy link
Member

Choose a reason for hiding this comment

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

Should this be named addSelfToFocusScopeTree? I was confused by the name for a minute.

@devongovett
Copy link
Member

I managed to get the simplification we were hacking on before break to work: #3898

@LFDanLu LFDanLu merged commit 9e2d10b into main Jan 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants