9
9
import {
10
10
AfterViewInit ,
11
11
Attribute ,
12
+ booleanAttribute ,
12
13
ChangeDetectionStrategy ,
13
14
ChangeDetectorRef ,
14
15
Component ,
@@ -18,26 +19,16 @@ import {
18
19
Inject ,
19
20
Input ,
20
21
NgZone ,
22
+ numberAttribute ,
21
23
Optional ,
22
24
Output ,
23
25
ViewChild ,
24
26
ViewEncapsulation ,
25
27
} from '@angular/core' ;
26
28
import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ;
27
- import {
28
- CanColor ,
29
- CanDisable ,
30
- CanDisableRipple ,
31
- HasTabIndex ,
32
- MatRipple ,
33
- mixinColor ,
34
- mixinDisabled ,
35
- mixinDisableRipple ,
36
- mixinTabIndex ,
37
- } from '@angular/material/core' ;
29
+ import { MatRipple } from '@angular/material/core' ;
38
30
import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations' ;
39
31
import { FocusableOption } from '@angular/cdk/a11y' ;
40
- import { BooleanInput , coerceBooleanProperty } from '@angular/cdk/coercion' ;
41
32
import {
42
33
MAT_CHECKBOX_DEFAULT_OPTIONS ,
43
34
MAT_CHECKBOX_DEFAULT_OPTIONS_FACTORY ,
@@ -79,20 +70,6 @@ let nextUniqueId = 0;
79
70
// Default checkbox configuration.
80
71
const defaults = MAT_CHECKBOX_DEFAULT_OPTIONS_FACTORY ( ) ;
81
72
82
- // Boilerplate for applying mixins to MatCheckbox.
83
- /** @docs -private */
84
- const _MatCheckboxMixinBase = mixinTabIndex (
85
- mixinColor (
86
- mixinDisableRipple (
87
- mixinDisabled (
88
- class {
89
- constructor ( public _elementRef : ElementRef ) { }
90
- } ,
91
- ) ,
92
- ) ,
93
- ) ,
94
- ) ;
95
-
96
73
@Component ( {
97
74
selector : 'mat-checkbox' ,
98
75
templateUrl : 'checkbox.html' ,
@@ -108,24 +85,14 @@ const _MatCheckboxMixinBase = mixinTabIndex(
108
85
// Add classes that users can use to more easily target disabled or checked checkboxes.
109
86
'[class.mat-mdc-checkbox-disabled]' : 'disabled' ,
110
87
'[class.mat-mdc-checkbox-checked]' : 'checked' ,
88
+ '[class]' : 'color ? "mat-" + color : "mat-accent"' ,
111
89
} ,
112
90
providers : [ MAT_CHECKBOX_CONTROL_VALUE_ACCESSOR ] ,
113
- inputs : [ 'disableRipple' , 'color' , 'tabIndex' ] ,
114
91
exportAs : 'matCheckbox' ,
115
92
encapsulation : ViewEncapsulation . None ,
116
93
changeDetection : ChangeDetectionStrategy . OnPush ,
117
94
} )
118
- export class MatCheckbox
119
- extends _MatCheckboxMixinBase
120
- implements
121
- AfterViewInit ,
122
- ControlValueAccessor ,
123
- CanColor ,
124
- CanDisable ,
125
- HasTabIndex ,
126
- CanDisableRipple ,
127
- FocusableOption
128
- {
95
+ export class MatCheckbox implements AfterViewInit , ControlValueAccessor , FocusableOption {
129
96
/** Focuses the checkbox. */
130
97
focus ( ) {
131
98
this . _inputElement . nativeElement . focus ( ) ;
@@ -179,14 +146,7 @@ export class MatCheckbox
179
146
}
180
147
181
148
/** Whether the checkbox is required. */
182
- @Input ( )
183
- get required ( ) : boolean {
184
- return this . _required ;
185
- }
186
- set required ( value : BooleanInput ) {
187
- this . _required = coerceBooleanProperty ( value ) ;
188
- }
189
- private _required : boolean ;
149
+ @Input ( { transform : booleanAttribute } ) required : boolean ;
190
150
191
151
/** Whether the label should appear after or before the checkbox. Defaults to 'after' */
192
152
@Input ( ) labelPosition : 'before' | 'after' = 'after' ;
@@ -203,12 +163,24 @@ export class MatCheckbox
203
163
/** The value attribute of the native input element */
204
164
@Input ( ) value : string ;
205
165
166
+ /** Whether the checkbox has a ripple. */
167
+ @Input ( { transform : booleanAttribute } ) disableRipple : boolean ;
168
+
206
169
/** The native `<input type="checkbox">` element */
207
170
@ViewChild ( 'input' ) _inputElement : ElementRef < HTMLInputElement > ;
208
171
209
172
/** The native `<label>` element */
210
173
@ViewChild ( 'label' ) _labelElement : ElementRef < HTMLInputElement > ;
211
174
175
+ /** Tabindex for the checkbox. */
176
+ @Input ( { transform : ( value : unknown ) => ( value == null ? undefined : numberAttribute ( value ) ) } )
177
+ tabIndex : number ;
178
+
179
+ // TODO(crisbeto): this should be a ThemePalette, but some internal apps were abusing
180
+ // the lack of type checking previously and assigning random strings.
181
+ /** Palette color of the checkbox. */
182
+ @Input ( ) color : string | undefined ;
183
+
212
184
/**
213
185
* Reference to the MatRipple instance of the checkbox.
214
186
* @deprecated Considered an implementation detail. To be removed.
@@ -229,16 +201,15 @@ export class MatCheckbox
229
201
private _controlValueAccessorChangeFn : ( value : any ) => void = ( ) => { } ;
230
202
231
203
constructor (
232
- elementRef : ElementRef < HTMLElement > ,
204
+ public _elementRef : ElementRef < HTMLElement > ,
233
205
private _changeDetectorRef : ChangeDetectorRef ,
234
206
private _ngZone : NgZone ,
235
207
@Attribute ( 'tabindex' ) tabIndex : string ,
236
208
@Optional ( ) @Inject ( ANIMATION_MODULE_TYPE ) public _animationMode ?: string ,
237
209
@Optional ( ) @Inject ( MAT_CHECKBOX_DEFAULT_OPTIONS ) private _options ?: MatCheckboxDefaultOptions ,
238
210
) {
239
- super ( elementRef ) ;
240
211
this . _options = this . _options || defaults ;
241
- this . color = this . defaultColor = this . _options . color || defaults . color ;
212
+ this . color = this . _options . color || defaults . color ;
242
213
this . tabIndex = parseInt ( tabIndex ) || 0 ;
243
214
this . id = this . _uniqueId = `mat-mdc-checkbox-${ ++ nextUniqueId } ` ;
244
215
}
@@ -248,33 +219,26 @@ export class MatCheckbox
248
219
}
249
220
250
221
/** Whether the checkbox is checked. */
251
- @Input ( )
222
+ @Input ( { transform : booleanAttribute } )
252
223
get checked ( ) : boolean {
253
224
return this . _checked ;
254
225
}
255
- set checked ( value : BooleanInput ) {
256
- const checked = coerceBooleanProperty ( value ) ;
257
-
258
- if ( checked != this . checked ) {
259
- this . _checked = checked ;
226
+ set checked ( value : boolean ) {
227
+ if ( value != this . checked ) {
228
+ this . _checked = value ;
260
229
this . _changeDetectorRef . markForCheck ( ) ;
261
230
}
262
231
}
263
232
private _checked : boolean = false ;
264
233
265
- /**
266
- * Whether the checkbox is disabled. This fully overrides the implementation provided by
267
- * mixinDisabled, but the mixin is still required because mixinTabIndex requires it.
268
- */
269
- @Input ( )
270
- override get disabled ( ) : boolean {
234
+ /** Whether the checkbox is disabled. */
235
+ @Input ( { transform : booleanAttribute } )
236
+ get disabled ( ) : boolean {
271
237
return this . _disabled ;
272
238
}
273
- override set disabled ( value : BooleanInput ) {
274
- const newValue = coerceBooleanProperty ( value ) ;
275
-
276
- if ( newValue !== this . disabled ) {
277
- this . _disabled = newValue ;
239
+ set disabled ( value : boolean ) {
240
+ if ( value !== this . disabled ) {
241
+ this . _disabled = value ;
278
242
this . _changeDetectorRef . markForCheck ( ) ;
279
243
}
280
244
}
@@ -286,13 +250,13 @@ export class MatCheckbox
286
250
* checkable items. Note that whenever checkbox is manually clicked, indeterminate is immediately
287
251
* set to false.
288
252
*/
289
- @Input ( )
253
+ @Input ( { transform : booleanAttribute } )
290
254
get indeterminate ( ) : boolean {
291
255
return this . _indeterminate ;
292
256
}
293
- set indeterminate ( value : BooleanInput ) {
257
+ set indeterminate ( value : boolean ) {
294
258
const changed = value != this . _indeterminate ;
295
- this . _indeterminate = coerceBooleanProperty ( value ) ;
259
+ this . _indeterminate = value ;
296
260
297
261
if ( changed ) {
298
262
if ( this . _indeterminate ) {
0 commit comments