diff --git a/list/lib/list.ts b/list/lib/list.ts index 82dc48a6d2..d625003608 100644 --- a/list/lib/list.ts +++ b/list/lib/list.ts @@ -5,15 +5,27 @@ */ import {ARIARole} from '@material/web/types/aria'; -import {html, LitElement, TemplateResult} from 'lit'; +import {html, LitElement, PropertyValues, TemplateResult} from 'lit'; +import {queryAssignedElements} from 'lit/decorators'; import {ListItemInteractionEvent} from './listitem/constants'; +import {ListItem} from './listitem/list-item'; /** @soyCompatible */ export class List extends LitElement { static override shadowRootOptions: ShadowRootInit = {mode: 'open', delegatesFocus: true}; + items: ListItem[] = []; + + @queryAssignedElements() protected assignedElements!: HTMLElement[]|null; + + override firstUpdated(changedProperties: PropertyValues) { + super.firstUpdated(changedProperties); + + this.updateItems(); + } + /** @soyTemplate */ protected getAriaRole(): ARIARole { return 'list'; @@ -31,10 +43,24 @@ export class List extends LitElement { `; } - handleItemInteraction(event: ListItemInteractionEvent) { if (event.detail.state.isSelected) { // TODO: manage selection state. } } + + /** Updates `this.items` based on slot elements in the DOM. */ + protected updateItems() { + const elements = this.assignedElements || []; + this.items = elements.filter(this.isListItem, this); + } + + protected getListItemTagName() { + return 'md-list-item'; + } + + /** @return Whether the given element is an element. */ + private isListItem(element: Element): element is ListItem { + return element.tagName.toLowerCase() === this.getListItemTagName(); + } } diff --git a/list/list_test.ts b/list/list_test.ts new file mode 100644 index 0000000000..f169c5010d --- /dev/null +++ b/list/list_test.ts @@ -0,0 +1,32 @@ +/** + * @license + * Copyright 2022 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import './list'; +import './list-item'; + +import {Environment} from '@material/web/testing/environment'; +import {html} from 'lit'; + +import {MdList} from './list'; + +const LIST_TEMPLATE = html` + + One + Two + Three + +`; + +describe('list tests', () => { + const env = new Environment(); + + it('`items` property returns correct items', async () => { + const element = env.render(LIST_TEMPLATE).querySelector('md-list')!; + await env.waitForStability(); + + expect(element.items.length).toBe(3); + }); +});