Skip to content

Commit 48f4f15

Browse files
committed
address feedback
1 parent 7b1d4f4 commit 48f4f15

File tree

1 file changed

+42
-25
lines changed

1 file changed

+42
-25
lines changed

src/material-experimental/mdc-list/list-base.ts

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,19 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
4747
// TODO(mmalerba): Add @Input for disabling ripple.
4848
rippleDisabled: boolean;
4949

50-
_element: HTMLElement;
51-
5250
private _subscriptions = new Subscription();
5351

5452
private _rippleRenderer: RippleRenderer;
5553

56-
protected constructor(private _elementRef: ElementRef<HTMLElement>, protected _ngZone: NgZone,
54+
protected constructor(public _elementRef: ElementRef<HTMLElement>, protected _ngZone: NgZone,
5755
listBase: MatListBase, platform: Platform) {
58-
this._element = this._elementRef.nativeElement;
5956
this.rippleDisabled = listBase._isNonInteractive;
6057
if (!listBase._isNonInteractive) {
61-
this._element.classList.add('mat-mdc-list-item-interactive');
58+
this._elementRef.nativeElement.classList.add('mat-mdc-list-item-interactive');
6259
}
6360
this._rippleRenderer =
64-
new RippleRenderer(this, this._ngZone, this._element, platform);
65-
this._rippleRenderer.setupTriggerEvents(this._element);
61+
new RippleRenderer(this, this._ngZone, this._elementRef.nativeElement, platform);
62+
this._rippleRenderer.setupTriggerEvents(this._elementRef.nativeElement);
6663
}
6764

6865
ngAfterContentInit() {
@@ -74,8 +71,15 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
7471
this._rippleRenderer._removeTriggerEvents();
7572
}
7673

74+
/**
75+
* Changes the tabindex of all button and anchor children of this item.
76+
*
77+
* This method is used by the `MatInteractiveBaseList` to implement the
78+
* `setTabIndexForListItemChildren` method on the `MDCListAdapter`
79+
*/
7780
_setTabIndexForChildren(value: number) {
78-
this._element.querySelectorAll('a, button').forEach(el => (el as HTMLElement).tabIndex = value);
81+
this._elementRef.nativeElement.querySelectorAll<HTMLElement>('a, button')
82+
.forEach(el => el.tabIndex = value);
7983
}
8084

8185
/**
@@ -86,7 +90,7 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
8690
this._ngZone.runOutsideAngular(() => {
8791
this._subscriptions.add(this.lines.changes.pipe(startWith(this.lines))
8892
.subscribe((lines: QueryList<ElementRef<Element>>) => {
89-
this._element.classList
93+
this._elementRef.nativeElement.classList
9094
.toggle('mat-mdc-list-item-single-line', lines.length <= 1);
9195
lines.forEach((line: ElementRef<Element>, index: number) => {
9296
toggleClass(line.nativeElement,
@@ -113,7 +117,7 @@ export abstract class MatInteractiveListBase extends MatListBase
113117
_handleKeydown(event: KeyboardEvent) {
114118
const index = this._indexForElement(event.target as HTMLElement);
115119
this._foundation.handleKeydown(
116-
event, this._itemAtIndex(index)._element === event.target, index);
120+
event, this._elementAtIndex(index) === event.target, index);
117121
}
118122

119123
@HostListener('click', ['$event'])
@@ -136,21 +140,20 @@ export abstract class MatInteractiveListBase extends MatListBase
136140
protected _adapter: MDCListAdapter = {
137141
getListItemCount: () => this._items.length,
138142
listItemAtIndexHasClass:
139-
(index, className) => this._itemAtIndex(index)._element.classList.contains(className),
143+
(index, className) => this._elementAtIndex(index).classList.contains(className),
140144
addClassForElementIndex:
141-
(index, className) => this._itemAtIndex(index)._element.classList.add(className),
145+
(index, className) => this._elementAtIndex(index).classList.add(className),
142146
removeClassForElementIndex:
143-
(index, className) => this._itemAtIndex(index)._element.classList.remove(className),
144-
getAttributeForElementIndex:
145-
(index, attr) => this._itemAtIndex(index)._element.getAttribute(attr),
147+
(index, className) => this._elementAtIndex(index).classList.remove(className),
148+
getAttributeForElementIndex: (index, attr) => this._elementAtIndex(index).getAttribute(attr),
146149
setAttributeForElementIndex:
147-
(index, attr, value) => this._itemAtIndex(index)._element.setAttribute(attr, value),
150+
(index, attr, value) => this._elementAtIndex(index).setAttribute(attr, value),
148151
setTabIndexForListItemChildren:
149152
(index, value) => this._itemAtIndex(index)._setTabIndexForChildren(Number(value)),
150-
getFocusedElementIndex: () => this._indexForElement(this._document?.activeELement),
153+
getFocusedElementIndex: () => this._indexForElement(this._document?.activeElement),
151154
isFocusInsideList: () => this._element.nativeElement.contains(this._document?.activeElement),
152155
isRootFocused: () => this._element.nativeElement === this._document?.activeElement,
153-
focusItemAtIndex: index => this._itemAtIndex(index)._element.focus(),
156+
focusItemAtIndex: index => this._elementAtIndex(index).focus(),
154157

155158
// The following methods have a dummy implementation in the base class because they are only
156159
// applicable to certain types of lists. They should be implemented for the concrete classes
@@ -167,32 +170,46 @@ export abstract class MatInteractiveListBase extends MatListBase
167170

168171
protected _foundation: MDCListFoundation;
169172

170-
constructor(protected _element: ElementRef<HTMLElement>,
171-
@Inject(DOCUMENT) protected _document: any) {
173+
protected _document: Document;
174+
175+
private _itemsArr: MatListItemBase[] = [];
176+
177+
private _subscriptions = new Subscription();
178+
179+
constructor(protected _element: ElementRef<HTMLElement>, @Inject(DOCUMENT) document: any) {
172180
super();
181+
this._document = document;
173182
this._isNonInteractive = false;
174183
this._foundation = new MDCListFoundation(this._adapter);
175184
}
176185

177186
ngAfterViewInit() {
178187
this._foundation.init();
179-
const first = this._items.toArray()[0]?._element;
188+
const first = this._itemAtIndex(0);
180189
if (first) {
181-
first.tabIndex = 0;
190+
first._elementRef.nativeElement.tabIndex = 0;
182191
}
183192
this._foundation.layout();
193+
this._subscriptions.add(
194+
this._items.changes.subscribe(() => this._itemsArr = this._items.toArray()));
184195
}
185196

186197
ngOnDestroy() {
187198
this._foundation.destroy();
199+
this._subscriptions.unsubscribe();
188200
}
189201

190202
private _itemAtIndex(index: number): MatListItemBase {
191-
return this._items.toArray()[index];
203+
return this._itemsArr[index];
204+
}
205+
206+
private _elementAtIndex(index: number): HTMLElement {
207+
return this._itemAtIndex(index)._elementRef.nativeElement;
192208
}
193209

194-
private _indexForElement(element: HTMLElement | null) {
195-
return element ? this._items.toArray().findIndex(i => i._element.contains(element)) : -1;
210+
private _indexForElement(element: Element | null) {
211+
return element ?
212+
this._itemsArr.findIndex(i => i._elementRef.nativeElement.contains(element)) : -1;
196213
}
197214
}
198215

0 commit comments

Comments
 (0)