|
6 | 6 | */
|
7 | 7 |
|
8 | 8 | import { CSSResult, html, TemplateResult } from 'lit';
|
9 |
| -import { property } from 'lit/decorators.js'; |
| 9 | +import { property, state } from 'lit/decorators.js'; |
10 | 10 | import { classMap } from 'lit/directives/class-map.js';
|
11 | 11 | import {
|
12 | 12 | Providers,
|
@@ -186,6 +186,8 @@ export class MgtLogin extends MgtTemplatedComponent {
|
186 | 186 | */
|
187 | 187 | private _userDetailsKey = '-userDetails';
|
188 | 188 |
|
| 189 | + @state() private _arrowKeyLocation = -1; |
| 190 | + |
189 | 191 | constructor() {
|
190 | 192 | super();
|
191 | 193 | this._isFlyoutOpen = false;
|
@@ -546,34 +548,77 @@ export class MgtLogin extends MgtTemplatedComponent {
|
546 | 548 |
|
547 | 549 | if (accounts?.length > 1) {
|
548 | 550 | return html`
|
549 |
| - <div id="accounts"> |
550 |
| - <fluent-listbox class="accounts" name="Account list"> |
551 |
| - ${accounts.map(account => { |
552 |
| - if (account.id !== provider.getActiveAccount().id) { |
| 551 | + <div id="accounts"> |
| 552 | + <ul |
| 553 | + tabindex="0" |
| 554 | + class="account-list" |
| 555 | + part="account-list" |
| 556 | + aria-label="${this.ariaLabel}" |
| 557 | + @keydown=${this.handleAccountListKeyDown} |
| 558 | + > |
| 559 | + ${accounts |
| 560 | + .filter(a => a.id !== provider.getActiveAccount().id) |
| 561 | + .map(account => { |
553 | 562 | const details = localStorage.getItem(account.id + this._userDetailsKey);
|
554 | 563 | return mgtHtml`
|
555 |
| - <fluent-option class="account-option" value="${account.name}" role="option"> |
| 564 | + <li |
| 565 | + tabindex="-1" |
| 566 | + part="account-item" |
| 567 | + class="account-item" |
| 568 | + @click=${() => this.setActiveAccount(account)} |
| 569 | + @keyup=${(e: KeyboardEvent) => { |
| 570 | + if (e.key === 'Enter') this.setActiveAccount(account); |
| 571 | + }} |
| 572 | + > |
556 | 573 | <mgt-person
|
557 |
| - @click=${() => this.setActiveAccount(account)} |
558 |
| - @keyup=${(e: KeyboardEvent) => { |
559 |
| - if (e.key === 'Enter') { |
560 |
| - this.setActiveAccount(account); |
561 |
| - } |
562 |
| - }} |
563 | 574 | .personDetails=${details ? JSON.parse(details) : null}
|
564 | 575 | .fallbackDetails=${{ displayName: account.name, mail: account.mail }}
|
565 | 576 | .view=${PersonViewType.twolines}
|
566 |
| - class="account"/> |
567 |
| - </fluent-option>`; |
568 |
| - } |
569 |
| - })} |
570 |
| - </fluent-listbox> |
571 |
| - </div> |
| 577 | + class="account" |
| 578 | + ></mgt-person> |
| 579 | + </li>`; |
| 580 | + })} |
| 581 | + </ul> |
| 582 | + </div> |
572 | 583 | `;
|
573 | 584 | }
|
574 | 585 | }
|
575 | 586 | }
|
576 | 587 |
|
| 588 | + private handleAccountListKeyDown = (event: KeyboardEvent) => { |
| 589 | + const list: HTMLUListElement = this.renderRoot.querySelector('ul.account-list'); |
| 590 | + let item: HTMLLIElement; |
| 591 | + const listItems: HTMLCollection = list?.children; |
| 592 | + // Default all tabindex values in li nodes to -1 |
| 593 | + for (const element of listItems) { |
| 594 | + const el = element as HTMLLIElement; |
| 595 | + el.setAttribute('tabindex', '-1'); |
| 596 | + el.blur(); |
| 597 | + } |
| 598 | + |
| 599 | + const childElementCount = list.childElementCount; |
| 600 | + const keyName = event.key; |
| 601 | + if (keyName === 'ArrowDown') { |
| 602 | + this._arrowKeyLocation = (this._arrowKeyLocation + 1 + childElementCount) % childElementCount; |
| 603 | + } else if (keyName === 'ArrowUp') { |
| 604 | + this._arrowKeyLocation = (this._arrowKeyLocation - 1 + childElementCount) % childElementCount; |
| 605 | + } else if (keyName === 'Tab' || keyName === 'Escape') { |
| 606 | + this._arrowKeyLocation = -1; |
| 607 | + list.blur(); |
| 608 | + if (keyName === 'Escape') { |
| 609 | + event.preventDefault(); |
| 610 | + event.stopPropagation(); |
| 611 | + } |
| 612 | + return; |
| 613 | + } |
| 614 | + |
| 615 | + if (this._arrowKeyLocation > -1) { |
| 616 | + item = listItems[this._arrowKeyLocation] as HTMLLIElement; |
| 617 | + item.setAttribute('tabindex', '1'); |
| 618 | + item.focus(); |
| 619 | + } |
| 620 | + }; |
| 621 | + |
577 | 622 | /**
|
578 | 623 | * Set one of the non-active accounts as the active account
|
579 | 624 | *
|
|
0 commit comments