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: added prop to handle moving focus to loader overlay on initial render; updated readme #562

Merged
merged 12 commits into from
Mar 25, 2022

Conversation

tbusillo
Copy link
Contributor

ref: https://github.com/dequelabs/walnut/issues/3039

Additional comments at above ref as well.

Purpose

To address moving focus to the loader, which was less of an issue with the component itself and more of an issue with its implementation in and need for handling focus outside of the component (e.g., via forwardRef).

This solution addresses one part of the problem, with the second part needing to be addressed where the loader is being used without implementing some kind of focus (this PR will make it easier to fix that, however).

See comments in https://github.com/dequelabs/walnut/issues/3039 and the diffs for additional information.

@github-actions
Copy link
Contributor

Preview branch generated at https://fix-move-focus-to-loader.d1gko6en628vir.amplifyapp.com

Comment on lines +24 to +29
### build (if first time building dev environment, must be run before yarn dev)

```sh
$ yarn build
```

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a bit unrelated to the overlay issue, but added to the README that upon first run, must run yarn build prior to yarn dev.

Comment on lines +64 to +77
test('handles being passed a ref', () => {
const loaderRef = React.createRef(null);

const loaderOverlay = mount(
<LoaderOverlay className="baz" role="alert" label="loading" ref={loaderRef}>
Some text
</LoaderOverlay>
);

setTimeout(() => {
expect(document.activeElement).toStrictEqual(loaderOverlay.getDOMNode());
});
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Test cases above this test for implementation of the new focus prop, but also added in a test to ensure backwards compatibility. As it stands, if we were to remove backwards compatibility for use of forwardRef, it would be a breaking change for current implementations where that prop is used.

? 'Loader__overlay--small'
: ''
)}
ref={ref ? ref : overlayRef}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For backwards compatibility purposes, checks if a ref was passed via prop, and if so, uses that ref instead of the overlayRef.

Copy link
Member

Choose a reason for hiding this comment

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

I'd make a small tweak here, have the ref set as a variable in the body of the component so that the same ref is being consumed everywhere:

const overlayRef = ref || createRef<HTMLDivElement>()

Then you can just utilize overlayRef where needed.

@tbusillo tbusillo changed the title Fix/move focus to loader fix: move focus to loader Mar 21, 2022
@tbusillo tbusillo marked this pull request as ready for review March 21, 2022 19:11
@tbusillo tbusillo requested a review from a team as a code owner March 21, 2022 19:11

useEffect(() => {
if ((!!focus && overlayRef) || ref) {
setTimeout(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Trying to move focus prior to the next tick was causing issues where the styling for the focus indicator would not be applied, even thought he element was the active element.

Copy link
Member

Choose a reason for hiding this comment

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

So I think this setTimeout is identifying a different issue where the ref is initially null on the first render. We may need to instead have the useEffect check that we have a ref value before setting focus:

useEffect(() => {
  overlayRef.current?.focus()
}, [overlayRef.current])

@tbusillo tbusillo requested a review from scurker March 21, 2022 21:44
Copy link
Member

@scurker scurker left a comment

Choose a reason for hiding this comment

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

Just a few minor nitpicks then I think we're good to go!


useEffect(() => {
if ((!!focus && overlayRef) || ref) {
setTimeout(() => {
Copy link
Member

Choose a reason for hiding this comment

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

So I think this setTimeout is identifying a different issue where the ref is initially null on the first render. We may need to instead have the useEffect check that we have a ref value before setting focus:

useEffect(() => {
  overlayRef.current?.focus()
}, [overlayRef.current])

? 'Loader__overlay--small'
: ''
)}
ref={ref ? ref : overlayRef}
Copy link
Member

Choose a reason for hiding this comment

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

I'd make a small tweak here, have the ref set as a variable in the body of the component so that the same ref is being consumed everywhere:

const overlayRef = ref || createRef<HTMLDivElement>()

Then you can just utilize overlayRef where needed.

@tbusillo tbusillo requested a review from scurker March 24, 2022 17:56
@scurker
Copy link
Member

scurker commented Mar 24, 2022

The github status for security reviews isn't available so

🚨 🚨 REVIEWED FOR SECURITY 🚨 🚨

Small nitpick: You may want to update the PR title to accurately reflect the changes we made

@tbusillo
Copy link
Contributor Author

The github status for security reviews isn't available so

🚨 🚨 REVIEWED FOR SECURITY 🚨 🚨

Small nitpick: You may want to update the PR title to accurately reflect the changes we made

Will do and thank you again for the help!

@tbusillo tbusillo changed the title fix: move focus to loader fix: added prop to handle moving focus to loader overlay; updated readme Mar 25, 2022
@tbusillo tbusillo changed the title fix: added prop to handle moving focus to loader overlay; updated readme fix: added prop to handle moving focus to loader overlay on initial render; updated readme Mar 25, 2022
@tbusillo tbusillo enabled auto-merge (squash) March 25, 2022 14:24
@scurker scurker disabled auto-merge March 25, 2022 14:30
@scurker scurker merged commit a5dcfee into develop Mar 25, 2022
@scurker scurker deleted the fix/move-focus-to-loader branch March 25, 2022 14:30
@github-actions
Copy link
Contributor

Preview branch generated at https://fix-move-focus-to-loader.d1gko6en628vir.amplifyapp.com

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