8
8
9
9
import { BooleanInput , coerceBooleanProperty } from '@angular/cdk/coercion' ;
10
10
import { SelectionModel } from '@angular/cdk/collections' ;
11
- import { Platform } from '@angular/cdk/platform' ;
12
11
import {
12
+ ANIMATION_MODULE_TYPE ,
13
13
ChangeDetectionStrategy ,
14
14
ChangeDetectorRef ,
15
15
Component ,
@@ -33,10 +33,10 @@ import {
33
33
RippleGlobalOptions ,
34
34
ThemePalette ,
35
35
} from '@angular/material-experimental/mdc-core' ;
36
- import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations' ;
37
36
import { MatListBase , MatListItemBase } from './list-base' ;
38
37
import { LIST_OPTION , ListOption , MatListOptionCheckboxPosition } from './list-option-types' ;
39
38
import { MatListItemLine , MatListItemTitle } from './list-item-sections' ;
39
+ import { Platform } from '@angular/cdk/platform' ;
40
40
41
41
/**
42
42
* Injection token that can be used to reference instances of an `SelectionList`. It serves
@@ -56,8 +56,9 @@ export interface SelectionList extends MatListBase {
56
56
selectedOptions : SelectionModel < MatListOption > ;
57
57
compareWith : ( o1 : any , o2 : any ) => boolean ;
58
58
_value : string [ ] | null ;
59
- _reportValueChange : ( ) => void ;
60
- _onTouched : ( ) => void ;
59
+ _reportValueChange ( ) : void ;
60
+ _emitChangeEvent ( options : MatListOption [ ] ) : void ;
61
+ _onTouched ( ) : void ;
61
62
}
62
63
63
64
@Component ( {
@@ -83,7 +84,9 @@ export interface SelectionList extends MatListBase {
83
84
'[class.mat-accent]' : 'color !== "primary" && color !== "warn"' ,
84
85
'[class.mat-warn]' : 'color === "warn"' ,
85
86
'[class._mat-animation-noopable]' : '_noopAnimations' ,
87
+ '[attr.aria-selected]' : 'selected' ,
86
88
'(blur)' : '_handleBlur()' ,
89
+ '(click)' : '_toggleOnInteraction()' ,
87
90
} ,
88
91
templateUrl : 'list-option.html' ,
89
92
encapsulation : ViewEncapsulation . None ,
@@ -97,7 +100,6 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
97
100
@ContentChildren ( MatListItemLine , { descendants : true } ) _lines : QueryList < MatListItemLine > ;
98
101
@ContentChildren ( MatListItemTitle , { descendants : true } ) _titles : QueryList < MatListItemTitle > ;
99
102
@ViewChild ( 'unscopedContent' ) _unscopedContent : ElementRef < HTMLSpanElement > ;
100
- @ViewChild ( 'text' ) _itemText : ElementRef < HTMLElement > ;
101
103
102
104
/**
103
105
* Emits when the selected state of the option has changed.
@@ -159,21 +161,17 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
159
161
private _inputsInitialized = false ;
160
162
161
163
constructor (
162
- element : ElementRef ,
164
+ elementRef : ElementRef < HTMLElement > ,
163
165
ngZone : NgZone ,
166
+ @Inject ( SELECTION_LIST ) private _selectionList : SelectionList ,
164
167
platform : Platform ,
165
- @Inject ( SELECTION_LIST ) public _selectionList : SelectionList ,
166
168
private _changeDetectorRef : ChangeDetectorRef ,
167
- @Optional ( ) @Inject ( MAT_RIPPLE_GLOBAL_OPTIONS ) globalRippleOptions ?: RippleGlobalOptions ,
169
+ @Optional ( )
170
+ @Inject ( MAT_RIPPLE_GLOBAL_OPTIONS )
171
+ globalRippleOptions ?: RippleGlobalOptions ,
168
172
@Optional ( ) @Inject ( ANIMATION_MODULE_TYPE ) animationMode ?: string ,
169
173
) {
170
- super ( element , ngZone , _selectionList , platform , globalRippleOptions , animationMode ) ;
171
-
172
- // By default, we mark all options as unselected. The MDC list foundation will
173
- // automatically update the attribute based on selection. Note that we need to
174
- // initially set this because MDC does not set the default attributes for list
175
- // items but expects items to be set up properly in the static markup.
176
- element . nativeElement . setAttribute ( 'aria-selected' , 'false' ) ;
174
+ super ( elementRef , ngZone , _selectionList , platform , globalRippleOptions , animationMode ) ;
177
175
}
178
176
179
177
ngOnInit ( ) {
@@ -221,6 +219,15 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
221
219
this . _hostElement . focus ( ) ;
222
220
}
223
221
222
+ /** Gets the text label of the list option. Used for the typeahead functionality in the list. */
223
+ getLabel ( ) {
224
+ const titleElement = this . _titles ?. get ( 0 ) ?. _elementRef . nativeElement ;
225
+ // If there is no explicit title element, the unscoped text content
226
+ // is treated as the list item title.
227
+ const labelEl = titleElement || this . _unscopedContent ?. nativeElement ;
228
+ return labelEl ?. textContent || '' ;
229
+ }
230
+
224
231
/** Whether a checkbox is shown at the given position. */
225
232
_hasCheckboxAt ( position : MatListOptionCheckboxPosition ) : boolean {
226
233
return this . _selectionList . multiple && this . _getCheckboxPosition ( ) === position ;
@@ -280,4 +287,22 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
280
287
_markForCheck ( ) {
281
288
this . _changeDetectorRef . markForCheck ( ) ;
282
289
}
290
+
291
+ /** Toggles the option's value based on a user interacion. */
292
+ _toggleOnInteraction ( ) {
293
+ if ( ! this . disabled ) {
294
+ if ( this . _selectionList . multiple ) {
295
+ this . selected = ! this . selected ;
296
+ this . _selectionList . _emitChangeEvent ( [ this ] ) ;
297
+ } else if ( ! this . selected ) {
298
+ this . selected = true ;
299
+ this . _selectionList . _emitChangeEvent ( [ this ] ) ;
300
+ }
301
+ }
302
+ }
303
+
304
+ /** Sets the tabindex of the list option. */
305
+ _setTabindex ( value : number ) {
306
+ this . _hostElement . setAttribute ( 'tabindex' , value + '' ) ;
307
+ }
283
308
}
0 commit comments