From bf48fc307ecadb7eb768052a54838a5ab532e059 Mon Sep 17 00:00:00 2001 From: Elizabeth Mitchell Date: Fri, 8 Sep 2023 10:12:58 -0700 Subject: [PATCH] feat(tabs): add `tabs` property to retrieve tab elements PiperOrigin-RevId: 563784477 --- tabs/harness.ts | 7 +++---- tabs/internal/tabs.ts | 32 ++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/tabs/harness.ts b/tabs/harness.ts index 0ec6f1771..26731652e 100644 --- a/tabs/harness.ts +++ b/tabs/harness.ts @@ -53,9 +53,8 @@ export class TabsHarness extends Harness { get harnessedItems() { // Test access to protected property // tslint:disable-next-line:no-dict-access-on-struct-type - return (this.element['items'] as Array>) - .map(item => { - return (item.harness ?? new TabHarness(item)) as TabHarness; - }); + return (this.element.tabs as Array>).map(item => { + return (item.harness ?? new TabHarness(item)) as TabHarness; + }); } } diff --git a/tabs/internal/tabs.ts b/tabs/internal/tabs.ts index 8d097a7b5..92f7db073 100644 --- a/tabs/internal/tabs.ts +++ b/tabs/internal/tabs.ts @@ -47,6 +47,13 @@ export class Tabs extends LitElement { setupHostAria(Tabs, {focusable: false}); } + /** + * The tabs of this tab bar. + */ + get tabs() { + return this.maybeTabItems.filter(isTab); + } + /** * Index of the selected item. */ @@ -63,9 +70,6 @@ export class Tabs extends LitElement { @queryAssignedElements({flatten: true}) private readonly maybeTabItems!: HTMLElement[]; - private get items(): Tab[] { - return this.maybeTabItems.filter(isTab); - } // this tracks if items have changed, which triggers rendering so they can // be kept in sync @@ -75,21 +79,21 @@ export class Tabs extends LitElement { * The item currently selected. */ get selectedItem() { - return this.items[this.selected]; + return this.tabs[this.selected]; } /** * The item previously selected. */ get previousSelectedItem() { - return this.items[this.previousSelected]; + return this.tabs[this.previousSelected]; } /** * The item currently focused. */ private get focusedItem() { - return this.items.find((el: HTMLElement) => el.matches(':focus-within')); + return this.tabs.find((el: HTMLElement) => el.matches(':focus-within')); } private readonly internals = polyfillElementInternalsAria( @@ -116,19 +120,19 @@ export class Tabs extends LitElement { } let indexToFocus = -1; const focused = this.focusedItem ?? this.selectedItem; - const itemCount = this.items.length; + const itemCount = this.tabs.length; const isPrevKey = key === 'ArrowLeft' || key === 'ArrowUp'; if (key === 'Home') { indexToFocus = 0; } else if (key === 'End') { indexToFocus = itemCount - 1; } else { - const focusedIndex = this.items.indexOf(focused) || 0; + const focusedIndex = this.tabs.indexOf(focused) || 0; indexToFocus = focusedIndex + (isPrevKey ? -1 : 1); indexToFocus = indexToFocus < 0 ? itemCount - 1 : indexToFocus % itemCount; } - const itemToFocus = this.items[indexToFocus]; + const itemToFocus = this.tabs[indexToFocus]; if (itemToFocus !== null && itemToFocus !== focused) { this.updateFocusableItem(itemToFocus); itemToFocus.focus(); @@ -150,7 +154,7 @@ export class Tabs extends LitElement { const nowFocused = (this.getRootNode() as unknown as DocumentOrShadowRoot).activeElement as Tab; - if (this.items.indexOf(nowFocused) === -1) { + if (this.tabs.indexOf(nowFocused) === -1) { this.updateFocusableItem(this.selectedItem); } }; @@ -209,7 +213,7 @@ export class Tabs extends LitElement { const itemsChanged = changed.has('itemsDirty'); // sync state with items. if (itemsChanged) { - this.items.forEach((item, i) => { + this.tabs.forEach((item, i) => { item.active = this.selected === i; }); } @@ -227,7 +231,7 @@ export class Tabs extends LitElement { } private updateFocusableItem(focusableItem: HTMLElement|null) { - for (const item of this.items) { + for (const item of this.tabs) { item.tabIndex = item === focusableItem ? 0 : -1; } } @@ -248,7 +252,7 @@ export class Tabs extends LitElement { return; } const item = (target as Element).closest(`${this.localName} > *`) as Tab; - const i = this.items.indexOf(item); + const i = this.tabs.indexOf(item); if (i > -1 && this.selected !== i) { this.selected = i; this.updateFocusableItem(this.selectedItem); @@ -264,7 +268,7 @@ export class Tabs extends LitElement { } private async itemsUpdateComplete() { - for (const item of this.items) { + for (const item of this.tabs) { await item.updateComplete; } return true;