Skip to content

Commit

Permalink
feat(tabs): add tabs property to retrieve tab elements
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 563784477
  • Loading branch information
asyncLiz authored and copybara-github committed Sep 8, 2023
1 parent 23b291b commit bf48fc3
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 18 deletions.
7 changes: 3 additions & 4 deletions tabs/harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ export class TabsHarness extends Harness<Tabs> {
get harnessedItems() {
// Test access to protected property
// tslint:disable-next-line:no-dict-access-on-struct-type
return (this.element['items'] as Array<ElementWithHarness<Tab>>)
.map(item => {
return (item.harness ?? new TabHarness(item)) as TabHarness;
});
return (this.element.tabs as Array<ElementWithHarness<Tab>>).map(item => {
return (item.harness ?? new TabHarness(item)) as TabHarness;
});
}
}
32 changes: 18 additions & 14 deletions tabs/internal/tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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
Expand All @@ -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(
Expand All @@ -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();
Expand All @@ -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);
}
};
Expand Down Expand Up @@ -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;
});
}
Expand All @@ -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;
}
}
Expand All @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit bf48fc3

Please sign in to comment.