Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

fix(FocusTrapZone): Set focus into zone when inner content is lazy loaded #1505

Merged
merged 18 commits into from
Jun 25, 2019

Conversation

sophieH29
Copy link
Contributor

@sophieH29 sophieH29 commented Jun 17, 2019

Fixes #1429

BREAKING CHANGES

Renamed prop forceFocusInsideTrap to forceFocusInsideTrapOnOutsideFocus

Improvements

  • Added props forceFocusInsideTrapOnComponentUpdate - false by default
    - once componentDidUpdate called in FocusTrapZone and current focused element is outside the FTZ's container, it will grab focus and put it on the inner element
  • To make it work for lazy loaded content there are 2 options:
    1. trigger componetDidUpdate by using state change when new content is loaded:
   const ButtonExampleEmphasis = () => {
  const loader = <Loader />;
  const [content, setContent] = React.useState(loader);

  setTimeout(() => {
    if (content === loader) {
      setContent(
        <Button content="has focus?" onClick={() => alert("I was clicked")} />
      );
    }
  }, 3000);

  return (
    <Popup
      accessibility={popupFocusTrapBehavior}
      trigger={<Button content="Click Me!" primary />}
      content={{ content }}
    />
  );
};
  1. put the focus inside the Popup manually after content is loaded

@sophieH29 sophieH29 added 🚀 ready for review 🧰 fix Introduces fix for broken behavior. accessibility All the Accessibility tasks and bugs should be tagged with this. labels Jun 17, 2019
@sophieH29 sophieH29 self-assigned this Jun 17, 2019
sophieH29 and others added 4 commits June 17, 2019 13:27
…ardust-ui/react into fix/focus-trap-zone-lazy-load

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
@codecov
Copy link

codecov bot commented Jun 17, 2019

Codecov Report

Merging #1505 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1505      +/-   ##
==========================================
+ Coverage   73.21%   73.24%   +0.02%     
==========================================
  Files         822      822              
  Lines        6194     6200       +6     
  Branches     1782     1802      +20     
==========================================
+ Hits         4535     4541       +6     
  Misses       1654     1654              
  Partials        5        5
Impacted Files Coverage Δ
.../src/lib/accessibility/FocusZone/FocusTrapZone.tsx 72.38% <100%> (+1.29%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fae15a8...98c3635. Read the comment docs.

const activeElement = document.activeElement as HTMLElement
// if after componentDidUpdate focus is not inside the focus trap, bring it back
if (!this._root.current.contains(activeElement)) {
this._bringFocusIntoZone()
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure this is a good idea. A component can update for many reasons and I am pretty sure it's not always expected behavior to bring focus back to the zone after every update.

Is see this behavior as risky because it can cause unexpected focus jumps so I'd recommend allowing the users to configure the focus zone to add / disable this behavior. Let's wait for other opinions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Bugaa92 this will only work if the active element (currently focused element) is not inside the focus trap container (for any reason) - focus should also be there once it is rendered.

Copy link
Contributor

Choose a reason for hiding this comment

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

as discusse doffline - one scenario where this might not work is if the popup opens another popup with focus trap. Then if the first popup updates, it might steal focus from the second popup. Can you please test this scenario?

Copy link
Contributor Author

@sophieH29 sophieH29 Jun 18, 2019

Choose a reason for hiding this comment

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

@jurokapsiar I tested this scenario. Since inner popup is rendered on button click in the first popup without relation to the outside state, it doesn't trigger componentDidUpdate.
Maybe there could be another case that I am missing, I see fabric-ui is doing the same thing. Folks, let me know what you think.

Copy link
Member

Choose a reason for hiding this comment

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

@sophieH29 can we make this behavior configurable via prop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've tried this case and it works

<Popup> -- with lazy load state change    
      <InnerPopup> -- with lazy load state change
              <InnerInnerPopup> -- autocontrolled Popup
                      <Input>

fyi @Bugaa92 @jurokapsiar

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@layershifter agree, updated

@codecov
Copy link

codecov bot commented Jun 17, 2019

Codecov Report

Merging #1505 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1505      +/-   ##
==========================================
+ Coverage   73.21%   73.24%   +0.02%     
==========================================
  Files         822      822              
  Lines        6194     6200       +6     
  Branches     1782     1802      +20     
==========================================
+ Hits         4535     4541       +6     
  Misses       1654     1654              
  Partials        5        5
Impacted Files Coverage Δ
.../src/lib/accessibility/FocusZone/FocusTrapZone.tsx 72.38% <100%> (+1.29%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fae15a8...98c3635. Read the comment docs.

3 similar comments
@codecov
Copy link

codecov bot commented Jun 17, 2019

Codecov Report

Merging #1505 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1505      +/-   ##
==========================================
+ Coverage   73.21%   73.24%   +0.02%     
==========================================
  Files         822      822              
  Lines        6194     6200       +6     
  Branches     1782     1802      +20     
==========================================
+ Hits         4535     4541       +6     
  Misses       1654     1654              
  Partials        5        5
Impacted Files Coverage Δ
.../src/lib/accessibility/FocusZone/FocusTrapZone.tsx 72.38% <100%> (+1.29%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fae15a8...98c3635. Read the comment docs.

@codecov
Copy link

codecov bot commented Jun 17, 2019

Codecov Report

Merging #1505 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1505      +/-   ##
==========================================
+ Coverage   73.21%   73.24%   +0.02%     
==========================================
  Files         822      822              
  Lines        6194     6200       +6     
  Branches     1782     1802      +20     
==========================================
+ Hits         4535     4541       +6     
  Misses       1654     1654              
  Partials        5        5
Impacted Files Coverage Δ
.../src/lib/accessibility/FocusZone/FocusTrapZone.tsx 72.38% <100%> (+1.29%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fae15a8...98c3635. Read the comment docs.

@codecov
Copy link

codecov bot commented Jun 17, 2019

Codecov Report

Merging #1505 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1505      +/-   ##
==========================================
+ Coverage   73.21%   73.24%   +0.02%     
==========================================
  Files         822      822              
  Lines        6194     6200       +6     
  Branches     1782     1802      +20     
==========================================
+ Hits         4535     4541       +6     
  Misses       1654     1654              
  Partials        5        5
Impacted Files Coverage Δ
.../src/lib/accessibility/FocusZone/FocusTrapZone.tsx 72.38% <100%> (+1.29%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fae15a8...98c3635. Read the comment docs.

@codecov
Copy link

codecov bot commented Jun 17, 2019

Codecov Report

Merging #1505 into master will decrease coverage by 0.01%.
The diff coverage is 82.35%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1505      +/-   ##
==========================================
- Coverage   73.17%   73.16%   -0.02%     
==========================================
  Files         828      828              
  Lines        6219     6227       +8     
  Branches     1802     1804       +2     
==========================================
+ Hits         4551     4556       +5     
- Misses       1663     1666       +3     
  Partials        5        5
Impacted Files Coverage Δ
packages/react/src/components/Popup/Popup.tsx 68.15% <ø> (ø) ⬆️
.../src/lib/accessibility/FocusZone/FocusTrapZone.tsx 70.58% <82.35%> (-0.51%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b788cf4...9640a60. Read the comment docs.

}

render(): JSX.Element {
const { className, forceFocusInsideTrap, ariaLabelledBy } = this.props
const { className, forceFocusInsideTrapOnOutsideFocus, ariaLabelledBy } = this.props
Copy link
Contributor

Choose a reason for hiding this comment

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

should we use these new props in popupFocusTrapBehavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if we want it by default then probably set this prop to "true" in FocusTrapZone. But I am not sure if want this by default, maybe better to allow a user to do it through customizing the behavior

@sophieH29 sophieH29 merged commit 0a9e616 into master Jun 25, 2019
@delete-merged-branch delete-merged-branch bot deleted the fix/focus-trap-zone-lazy-load branch June 25, 2019 10:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accessibility All the Accessibility tasks and bugs should be tagged with this. 🧰 fix Introduces fix for broken behavior. 🚀 ready for review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Accessibility: Focus trap zone is not properly setting focus for lazy loaded components
4 participants