@@ -11,12 +11,15 @@ import {
11
11
AfterContentInit ,
12
12
Directive ,
13
13
ElementRef ,
14
+ forwardRef ,
14
15
HostBinding ,
15
16
NgZone ,
16
17
OnDestroy ,
17
- QueryList
18
+ QueryList ,
19
+ ViewChildren
18
20
} from '@angular/core' ;
19
21
import { RippleConfig , RippleRenderer , RippleTarget , setLines } from '@angular/material/core' ;
22
+ import { MDCListAdapter } from '@material/list' ;
20
23
import { Subscription } from 'rxjs' ;
21
24
import { startWith } from 'rxjs/operators' ;
22
25
@@ -37,6 +40,46 @@ export abstract class MatListBase {
37
40
// tslint:disable-next-line:no-host-decorator-in-concrete
38
41
@HostBinding ( 'class.mdc-list--non-interactive' )
39
42
_isNonInteractive : boolean = false ;
43
+
44
+ @ViewChildren ( forwardRef ( ( ) => MatListItemBase ) ) _items : QueryList < MatListItemBase > ;
45
+
46
+ protected adapter : MDCListAdapter = {
47
+ getListItemCount : ( ) => this . _items . length ,
48
+ listItemAtIndexHasClass :
49
+ ( index , className ) => this . _itemAtIndex ( index ) . _element . classList . contains ( className ) ,
50
+ addClassForElementIndex :
51
+ ( index , className ) => this . _itemAtIndex ( index ) . _element . classList . add ( className ) ,
52
+ removeClassForElementIndex :
53
+ ( index , className ) => this . _itemAtIndex ( index ) . _element . classList . remove ( className ) ,
54
+ getAttributeForElementIndex :
55
+ ( index , attr ) => this . _itemAtIndex ( index ) . _element . getAttribute ( attr ) ,
56
+ setAttributeForElementIndex :
57
+ ( index , attr , value ) => this . _itemAtIndex ( index ) . _element . setAttribute ( attr , value ) ,
58
+ setTabIndexForListItemChildren :
59
+ ( index , value ) => this . _itemAtIndex ( index ) . _element . tabIndex = value as unknown as number ,
60
+ getFocusedElementIndex :
61
+ ( ) => this . _items . map ( i => i . _element ) . findIndex ( e => e === this . doc ?. activeELement ) ,
62
+ isFocusInsideList : ( ) => this . element . nativeElement . contains ( this . doc ?. activeElement ) ,
63
+ isRootFocused : ( ) => this . element . nativeElement === this . doc ?. activeElement ,
64
+ focusItemAtIndex : index => this . _itemAtIndex ( index ) . _element . focus ( ) ,
65
+
66
+ // The following methods have a dummy implementation in the base class because they are only
67
+ // applicable to certain types of lists
68
+ hasCheckboxAtIndex : ( ) => false ,
69
+ hasRadioAtIndex : ( ) => false ,
70
+ setCheckedCheckboxOrRadioAtIndex : ( ) => { } ,
71
+ isCheckboxCheckedAtIndex : ( ) => false ,
72
+ notifyAction : ( ) => { } ,
73
+
74
+ // TODO(mmalerba): Determine if we need to implement this.
75
+ getPrimaryTextAtIndex : ( ) => '' ,
76
+ } ;
77
+
78
+ constructor ( protected element : ElementRef < HTMLElement > , protected doc : any ) { }
79
+
80
+ private _itemAtIndex ( index : number ) : MatListItemBase {
81
+ return this . _items . toArray ( ) [ index ] ;
82
+ }
40
83
}
41
84
42
85
@Directive ( )
@@ -49,20 +92,22 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
49
92
// TODO(mmalerba): Add @Input for disabling ripple.
50
93
rippleDisabled : boolean ;
51
94
95
+ _element : HTMLElement ;
96
+
52
97
private _subscriptions = new Subscription ( ) ;
53
98
54
99
private _rippleRenderer : RippleRenderer ;
55
100
56
- constructor ( protected _element : ElementRef , protected _ngZone : NgZone , listBase : MatListBase ,
57
- platform : Platform ) {
58
- const el = this . _element . nativeElement ;
101
+ constructor ( private _elementRef : ElementRef < HTMLElement > , protected _ngZone : NgZone ,
102
+ listBase : MatListBase , platform : Platform ) {
103
+ this . _element = this . _elementRef . nativeElement ;
59
104
this . rippleDisabled = listBase . _isNonInteractive ;
60
105
if ( ! listBase . _isNonInteractive ) {
61
- el . classList . add ( 'mat-mdc-list-item-interactive' ) ;
106
+ this . _element . classList . add ( 'mat-mdc-list-item-interactive' ) ;
62
107
}
63
108
this . _rippleRenderer =
64
- new RippleRenderer ( this , this . _ngZone , el , platform ) ;
65
- this . _rippleRenderer . setupTriggerEvents ( el ) ;
109
+ new RippleRenderer ( this , this . _ngZone , this . _element , platform ) ;
110
+ this . _rippleRenderer . setupTriggerEvents ( this . _element ) ;
66
111
}
67
112
68
113
ngAfterContentInit ( ) {
@@ -77,14 +122,14 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
77
122
this . _ngZone . runOutsideAngular ( ( ) => {
78
123
this . _subscriptions . add ( this . lines . changes . pipe ( startWith ( this . lines ) )
79
124
. subscribe ( ( lines : QueryList < ElementRef < Element > > ) => {
80
- this . _element . nativeElement . classList
125
+ this . _element . classList
81
126
. toggle ( 'mat-mdc-list-item-single-line' , lines . length <= 1 ) ;
82
127
lines . forEach ( ( line : ElementRef < Element > , index : number ) => {
83
128
toggleClass ( line . nativeElement ,
84
129
'mdc-list-item__primary-text' , index === 0 && lines . length > 1 ) ;
85
130
toggleClass ( line . nativeElement , 'mdc-list-item__secondary-text' , index !== 0 ) ;
86
131
} ) ;
87
- setLines ( lines , this . _element , 'mat-mdc' ) ;
132
+ setLines ( lines , this . _elementRef , 'mat-mdc' ) ;
88
133
} ) ) ;
89
134
} ) ;
90
135
}
0 commit comments