mirror of
https://github.com/material-components/material-web.git
synced 2024-09-11 13:46:10 +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() {
|
get harnessedItems() {
|
||||||
// Test access to protected property
|
// Test access to protected property
|
||||||
// tslint:disable-next-line:no-dict-access-on-struct-type
|
// tslint:disable-next-line:no-dict-access-on-struct-type
|
||||||
return (this.element['items'] as Array<ElementWithHarness<Tab>>)
|
return (this.element.tabs as Array<ElementWithHarness<Tab>>).map(item => {
|
||||||
.map(item => {
|
return (item.harness ?? new TabHarness(item)) as TabHarness;
|
||||||
return (item.harness ?? new TabHarness(item)) as TabHarness;
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,13 @@ export class Tabs extends LitElement {
|
|||||||
setupHostAria(Tabs, {focusable: false});
|
setupHostAria(Tabs, {focusable: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tabs of this tab bar.
|
||||||
|
*/
|
||||||
|
get tabs() {
|
||||||
|
return this.maybeTabItems.filter(isTab);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index of the selected item.
|
* Index of the selected item.
|
||||||
*/
|
*/
|
||||||
@ -63,9 +70,6 @@ export class Tabs extends LitElement {
|
|||||||
|
|
||||||
@queryAssignedElements({flatten: true})
|
@queryAssignedElements({flatten: true})
|
||||||
private readonly maybeTabItems!: HTMLElement[];
|
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
|
// this tracks if items have changed, which triggers rendering so they can
|
||||||
// be kept in sync
|
// be kept in sync
|
||||||
@ -75,21 +79,21 @@ export class Tabs extends LitElement {
|
|||||||
* The item currently selected.
|
* The item currently selected.
|
||||||
*/
|
*/
|
||||||
get selectedItem() {
|
get selectedItem() {
|
||||||
return this.items[this.selected];
|
return this.tabs[this.selected];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item previously selected.
|
* The item previously selected.
|
||||||
*/
|
*/
|
||||||
get previousSelectedItem() {
|
get previousSelectedItem() {
|
||||||
return this.items[this.previousSelected];
|
return this.tabs[this.previousSelected];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item currently focused.
|
* The item currently focused.
|
||||||
*/
|
*/
|
||||||
private get focusedItem() {
|
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(
|
private readonly internals = polyfillElementInternalsAria(
|
||||||
@ -116,19 +120,19 @@ export class Tabs extends LitElement {
|
|||||||
}
|
}
|
||||||
let indexToFocus = -1;
|
let indexToFocus = -1;
|
||||||
const focused = this.focusedItem ?? this.selectedItem;
|
const focused = this.focusedItem ?? this.selectedItem;
|
||||||
const itemCount = this.items.length;
|
const itemCount = this.tabs.length;
|
||||||
const isPrevKey = key === 'ArrowLeft' || key === 'ArrowUp';
|
const isPrevKey = key === 'ArrowLeft' || key === 'ArrowUp';
|
||||||
if (key === 'Home') {
|
if (key === 'Home') {
|
||||||
indexToFocus = 0;
|
indexToFocus = 0;
|
||||||
} else if (key === 'End') {
|
} else if (key === 'End') {
|
||||||
indexToFocus = itemCount - 1;
|
indexToFocus = itemCount - 1;
|
||||||
} else {
|
} else {
|
||||||
const focusedIndex = this.items.indexOf(focused) || 0;
|
const focusedIndex = this.tabs.indexOf(focused) || 0;
|
||||||
indexToFocus = focusedIndex + (isPrevKey ? -1 : 1);
|
indexToFocus = focusedIndex + (isPrevKey ? -1 : 1);
|
||||||
indexToFocus =
|
indexToFocus =
|
||||||
indexToFocus < 0 ? itemCount - 1 : indexToFocus % itemCount;
|
indexToFocus < 0 ? itemCount - 1 : indexToFocus % itemCount;
|
||||||
}
|
}
|
||||||
const itemToFocus = this.items[indexToFocus];
|
const itemToFocus = this.tabs[indexToFocus];
|
||||||
if (itemToFocus !== null && itemToFocus !== focused) {
|
if (itemToFocus !== null && itemToFocus !== focused) {
|
||||||
this.updateFocusableItem(itemToFocus);
|
this.updateFocusableItem(itemToFocus);
|
||||||
itemToFocus.focus();
|
itemToFocus.focus();
|
||||||
@ -150,7 +154,7 @@ export class Tabs extends LitElement {
|
|||||||
const nowFocused =
|
const nowFocused =
|
||||||
(this.getRootNode() as unknown as DocumentOrShadowRoot).activeElement as
|
(this.getRootNode() as unknown as DocumentOrShadowRoot).activeElement as
|
||||||
Tab;
|
Tab;
|
||||||
if (this.items.indexOf(nowFocused) === -1) {
|
if (this.tabs.indexOf(nowFocused) === -1) {
|
||||||
this.updateFocusableItem(this.selectedItem);
|
this.updateFocusableItem(this.selectedItem);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -209,7 +213,7 @@ export class Tabs extends LitElement {
|
|||||||
const itemsChanged = changed.has('itemsDirty');
|
const itemsChanged = changed.has('itemsDirty');
|
||||||
// sync state with items.
|
// sync state with items.
|
||||||
if (itemsChanged) {
|
if (itemsChanged) {
|
||||||
this.items.forEach((item, i) => {
|
this.tabs.forEach((item, i) => {
|
||||||
item.active = this.selected === i;
|
item.active = this.selected === i;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -227,7 +231,7 @@ export class Tabs extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateFocusableItem(focusableItem: HTMLElement|null) {
|
private updateFocusableItem(focusableItem: HTMLElement|null) {
|
||||||
for (const item of this.items) {
|
for (const item of this.tabs) {
|
||||||
item.tabIndex = item === focusableItem ? 0 : -1;
|
item.tabIndex = item === focusableItem ? 0 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,7 +252,7 @@ export class Tabs extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const item = (target as Element).closest(`${this.localName} > *`) as Tab;
|
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) {
|
if (i > -1 && this.selected !== i) {
|
||||||
this.selected = i;
|
this.selected = i;
|
||||||
this.updateFocusableItem(this.selectedItem);
|
this.updateFocusableItem(this.selectedItem);
|
||||||
@ -264,7 +268,7 @@ export class Tabs extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async itemsUpdateComplete() {
|
private async itemsUpdateComplete() {
|
||||||
for (const item of this.items) {
|
for (const item of this.tabs) {
|
||||||
await item.updateComplete;
|
await item.updateComplete;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user