mirror of
https://github.com/material-components/material-web.git
synced 2024-08-17 09:30:27 +03:00
feat(tabs): add tabs
property to retrieve tab elements
PiperOrigin-RevId: 563784477
This commit is contained in:
parent
23b291b2dd
commit
bf48fc307e
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user