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(focus-trap): not attaching correctly if element is not in the DOM on init #7665

Merged
merged 1 commit into from
Jun 29, 2018

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Oct 9, 2017

Currently the focus trap attempts to attach itself once on init (e.g. when it is projected inside of an overlay), however in some cases it might not be in the DOM yet. These changes make it so it re-tries to attach itself until it does so successfully.

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Oct 9, 2017
@crisbeto crisbeto changed the title fix(focus-trap): not attaching correctly if element is on in the DOM on init fix(focus-trap): not attaching correctly if element is not in the DOM on init Oct 9, 2017
@crisbeto crisbeto force-pushed the focus-trap-deferred-attach branch from 0a63b61 to 2a8943b Compare October 9, 2017 19:17
// immediately, keep trying until it is.
if (!this.focusTrap.hasAttached()) {
this.focusTrap.attachAnchors();
}
Copy link
Member

Choose a reason for hiding this comment

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

Add a unit test for this?

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 had a hard time putting together a unit test that would fail as we expect it to. The only way I got the issue to happen at runtime was using a focus trap as the content of a select which has a complicated setup around it. I tried throwing a portal into the unit test, but it still worked.

Copy link
Member

Choose a reason for hiding this comment

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

I ran into the issue with a setup like

<ng-template cdkConnectedOverlay>
  <div cdkTrapFocus>...</div>
</ng-template>

Copy link
Member Author

Choose a reason for hiding this comment

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

That doesn't seem to work either. During the test the focus trap still manages to find a parent node which allows it to attach (the <div id="root0"> in particular which AFAIK is the Karma root element), whereas in the demo app it doesn't, For reference, here's what the test component looks like:

@Component({
  template: `
    <button cdkOverlayOrigin #origin="cdkOverlayOrigin">I'm the origin</button>

    <ng-template cdkConnectedOverlay [open]="isOpen" [origin]="origin">
      <div cdkTrapFocus><button>I'm trapped!</button></div>
    </ng-template>
  `
})
class FocusTrapInOverlay {
  isOpen = false;
}

Copy link
Member

Choose a reason for hiding this comment

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

The whole setup where it happened consistently was:

<ng-template
    cdkConnectedOverlay
    [cdkConnectedOverlayOrigin]="trigger"
    [cdkConnectedOverlayOpen]="isOpen">

  <div cdkTrapFocus class="color-picker"
        role="dialog" aria-label="Color picker">
      <div role="listbox" tabindex="0" aria-label="Select a color"
        (keydown)="keydownHandler($event)">
        <div *ngFor="let color of colors; index as i"
            role="option"
            [style.background]="color.hex"
            [attr.aria-label]="color.name"
            [attr.aria-selected]="color.hex == selectedColor"
            (click)="selectedColor = color.hex; isOpen = false"></div>
      </div>
    </div>
</ng-template>

(ran into it while working on my angular mix demo)

… on init

Currently the focus trap attempts to attach itself once on init (e.g. when it is projected inside of an overlay), however in some cases it might not be in the DOM yet. These changes make it so it re-tries to attach itself until it does so successfully.
@crisbeto crisbeto force-pushed the focus-trap-deferred-attach branch from 2a8943b to f01e4bb Compare April 30, 2018 03:14
@josephperrott josephperrott added the target: patch This PR is targeted for the next patch release label Jun 26, 2018
@josephperrott
Copy link
Member

@jelbourn How are we looking on this one?

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Jun 28, 2018
@josephperrott josephperrott merged commit d64f94d into angular:master Jun 29, 2018
@jelbourn
Copy link
Member

@torabian Please do not spam unrelated PRs and issues promoting a project. Further spam will lead to your account being blocked.

@angular angular deleted a comment from torabian Dec 1, 2018
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants