Skip to content

Commit

Permalink
fix: dismiss login flyout when moving out of the popup (#2637)
Browse files Browse the repository at this point in the history
use a focus trap to fix menu dismiss issues with shift+tab
return focus to login button when closing flyout
rewrite implementation to handle shift+tab natively
add shift+tab case while at fluent-card

---------

Co-authored-by: Gavin Barron <gavinbarron@microsoft.com>
  • Loading branch information
Mnickii and gavinbarron committed Aug 17, 2023
1 parent 48ea18b commit 263f36f
Showing 1 changed file with 43 additions and 5 deletions.
48 changes: 43 additions & 5 deletions packages/mgt-components/src/components/mgt-login/mgt-login.ts
Expand Up @@ -320,6 +320,7 @@ export class MgtLogin extends MgtTemplatedComponent {
const expandedState: boolean | undefined = showSignedInState ? this._isFlyoutOpen : undefined;
return html`
<fluent-button
id="login-button"
aria-expanded="${ifDefined(expandedState)}"
appearance=${appearance}
aria-label="${ifDefined(isSignedIn ? undefined : this.strings.signInLinkSubtitle)}"
Expand Down Expand Up @@ -351,14 +352,49 @@ export class MgtLogin extends MgtTemplatedComponent {
light-dismiss
@opened=${this.flyoutOpened}
@closed=${this.flyoutClosed}>
<div slot="flyout">
<fluent-card class="flyout-card">
${this.renderFlyoutContent()}
</fluent-card>
</div>
<fluent-card
slot="flyout"
tabindex="0"
class="flyout-card"
@keydown=${this.onUserKeyDown}
>
${this.renderFlyoutContent()}
</fluent-card>
</mgt-flyout>`;
}

/**
* Tracks tabbing through the flyout (keydown)
*/
private readonly onUserKeyDown = (e: KeyboardEvent): void => {
if (!this.flyout.isOpen) {
return;
}

const el = this.renderRoot.querySelector('.popup-content');
const focusableEls = el.querySelectorAll('ul, fluent-button');
const firstFocusableEl = el.querySelector('#signout-button') || focusableEls[0];
const lastFocusableEl =
el.querySelector('#signin-different-account-button') || focusableEls[focusableEls.length - 1];

if (e.key === 'Tab' && e.shiftKey && firstFocusableEl === e.target) {
e.preventDefault();
(lastFocusableEl as HTMLElement)?.focus();
}
if (e.key === 'Tab' && !e.shiftKey && lastFocusableEl === e.target) {
e.preventDefault();
(firstFocusableEl as HTMLElement)?.focus();
}
if (e.key === 'Escape') {
const loginButton = this.renderRoot.querySelector('#login-button');
(loginButton as HTMLElement)?.focus();
}
const fluentCardEl = this.renderRoot.querySelector('fluent-card');
if (e.shiftKey && e.key === 'Tab' && e.target === fluentCardEl) {
this.hideFlyout();
}
};

/**
* Render the flyout menu content.
*
Expand Down Expand Up @@ -435,6 +471,7 @@ export class MgtLogin extends MgtTemplatedComponent {
template ||
html`
<fluent-button
id="signout-button"
appearance="stealth"
size="medium"
class="flyout-command"
Expand Down Expand Up @@ -472,6 +509,7 @@ export class MgtLogin extends MgtTemplatedComponent {
return html`
<div class="add-account">
<fluent-button
id="signin-different-account-button"
appearance="stealth"
aria-label="${this.strings.signInWithADifferentAccount}"
@click=${() => void this.login()}>
Expand Down

0 comments on commit 263f36f

Please sign in to comment.