@@ -69,9 +69,18 @@ export type SubscriptSizing = 'fixed' | 'dynamic';
69
69
* using the `MAT_FORM_FIELD_DEFAULT_OPTIONS` injection token.
70
70
*/
71
71
export interface MatFormFieldDefaultOptions {
72
+ /** Default form field appearance style. */
72
73
appearance ?: MatFormFieldAppearance ;
74
+ /** Default color of the form field. */
75
+ color ?: ThemePalette ;
76
+ /** Whether the required marker should be hidden by default. */
73
77
hideRequiredMarker ?: boolean ;
78
+ /**
79
+ * Whether the label for form fields should by default float `always`,
80
+ * `never`, or `auto` (only when necessary).
81
+ */
74
82
floatLabel ?: FloatLabelType ;
83
+ /** Whether the form field should reserve space for one line by default. */
75
84
subscriptSizing ?: SubscriptSizing ;
76
85
}
77
86
@@ -85,10 +94,13 @@ export const MAT_FORM_FIELD_DEFAULT_OPTIONS = new InjectionToken<MatFormFieldDef
85
94
86
95
let nextUniqueId = 0 ;
87
96
88
- /** Default appearance used by the form- field. */
97
+ /** Default appearance used by the form field. */
89
98
const DEFAULT_APPEARANCE : MatFormFieldAppearance = 'fill' ;
90
99
91
- /** Default appearance used by the form-field. */
100
+ /**
101
+ * Whether the label for form fields should by default float `always`,
102
+ * `never`, or `auto`.
103
+ */
92
104
const DEFAULT_FLOAT_LABEL : FloatLabelType = 'auto' ;
93
105
94
106
/** Default way that the subscript element height is set. */
@@ -147,7 +159,7 @@ const WRAPPER_HORIZONTAL_PADDING = 16;
147
159
providers : [ { provide : MAT_FORM_FIELD , useExisting : MatFormField } ] ,
148
160
} )
149
161
export class MatFormField
150
- implements AfterViewInit , OnDestroy , AfterContentChecked , AfterContentInit
162
+ implements AfterContentInit , AfterContentChecked , AfterViewInit , OnDestroy
151
163
{
152
164
@ViewChild ( 'textField' ) _textField : ElementRef < HTMLElement > ;
153
165
@ViewChild ( 'iconPrefixContainer' ) _iconPrefixContainer : ElementRef < HTMLElement > ;
@@ -172,10 +184,17 @@ export class MatFormField
172
184
set hideRequiredMarker ( value : BooleanInput ) {
173
185
this . _hideRequiredMarker = coerceBooleanProperty ( value ) ;
174
186
}
175
- private _hideRequiredMarker : boolean ;
187
+ private _hideRequiredMarker = false ;
176
188
177
- /** The color palette for the form-field. */
178
- @Input ( ) color : ThemePalette = 'primary' ;
189
+ /** The color palette for the form field. */
190
+ @Input ( )
191
+ get color ( ) : ThemePalette {
192
+ return this . _color ;
193
+ }
194
+ set color ( value : ThemePalette ) {
195
+ this . _color = value || this . _defaults ?. color || 'primary' ;
196
+ }
197
+ private _color : ThemePalette = 'primary' ;
179
198
180
199
/** Whether the label should always float or float as the user types. */
181
200
@Input ( )
@@ -185,23 +204,23 @@ export class MatFormField
185
204
set floatLabel ( value : FloatLabelType ) {
186
205
if ( value !== this . _floatLabel ) {
187
206
this . _floatLabel = value ;
188
- // For backwards compatibility. Custom form- field controls or directives might set
189
- // the "floatLabel" input and expect the form- field view to be updated automatically.
207
+ // For backwards compatibility. Custom form field controls or directives might set
208
+ // the "floatLabel" input and expect the form field view to be updated automatically.
190
209
// e.g. autocomplete trigger. Ideally we'd get rid of this and the consumers would just
191
210
// emit the "stateChanges" observable. TODO(devversion): consider removing.
192
211
this . _changeDetectorRef . markForCheck ( ) ;
193
212
}
194
213
}
195
214
private _floatLabel : FloatLabelType ;
196
215
197
- /** The form- field appearance style. */
216
+ /** The form field appearance style. */
198
217
@Input ( )
199
218
get appearance ( ) : MatFormFieldAppearance {
200
219
return this . _appearance ;
201
220
}
202
221
set appearance ( value : MatFormFieldAppearance ) {
203
222
const oldValue = this . _appearance ;
204
- this . _appearance = value || ( this . _defaults && this . _defaults . appearance ) || DEFAULT_APPEARANCE ;
223
+ this . _appearance = value || this . _defaults ?. appearance || DEFAULT_APPEARANCE ;
205
224
if ( this . _appearance === 'outline' && this . _appearance !== oldValue ) {
206
225
this . _refreshOutlineNotchWidth ( ) ;
207
226
@@ -280,7 +299,7 @@ export class MatFormField
280
299
// MDC text-field will call this method on focus, blur and value change. It expects us
281
300
// to update the floating label state accordingly. Though we make this a noop because we
282
301
// want to react to floating label state changes through change detection. Relying on this
283
- // adapter method would mean that the label would not update if the custom form- field control
302
+ // adapter method would mean that the label would not update if the custom form field control
284
303
// sets "shouldLabelFloat" to true, or if the "floatLabel" input binding changes to "always".
285
304
floatLabel : ( ) => { } ,
286
305
@@ -294,7 +313,7 @@ export class MatFormField
294
313
// closed. This works fine in the standard MDC text-field, but not in Angular where the
295
314
// floating label could change through interpolation. We want to be able to update the
296
315
// notched outline whenever the label content changes. Additionally, relying on focus or
297
- // blur to open and close the notch does not work for us since abstract form- field controls
316
+ // blur to open and close the notch does not work for us since abstract form field controls
298
317
// have the ability to control the floating label state (i.e. `shouldLabelFloat`), and we
299
318
// want to update the notch whenever the `_shouldLabelFloat()` value changes.
300
319
getLabelWidth : ( ) => 0 ,
@@ -312,28 +331,28 @@ export class MatFormField
312
331
313
332
// The foundation tries to register events on the input. This is not matching
314
333
// our concept of abstract form field controls. We handle each event manually
315
- // in "stateChanges" based on the form- field control state. The following events
334
+ // in "stateChanges" based on the form field control state. The following events
316
335
// need to be handled: focus, blur. We do not handle the "input" event since
317
336
// that one is only needed for the text-field character count, which we do
318
- // not implement as part of the form- field, but should be implemented manually
337
+ // not implement as part of the form field, but should be implemented manually
319
338
// by consumers using template bindings.
320
339
registerInputInteractionHandler : ( ) => { } ,
321
340
deregisterInputInteractionHandler : ( ) => { } ,
322
341
323
342
// We do not have a reference to the native input since we work with abstract form field
324
343
// controls. MDC needs a reference to the native input optionally to handle character
325
344
// counting and value updating. These are both things we do not handle from within the
326
- // form- field, so we can just return null.
345
+ // form field, so we can just return null.
327
346
getNativeInput : ( ) => null ,
328
347
329
348
// This method will never be called since we do not have the ability to add event listeners
330
349
// to the native input. This is because the form control is not necessarily an input, and
331
350
// the form field deals with abstract form controls of any type.
332
351
setLineRippleTransformOrigin : ( ) => { } ,
333
352
334
- // The foundation tries to register click and keyboard events on the form- field to figure out
353
+ // The foundation tries to register click and keyboard events on the form field to figure out
335
354
// if the input value changes through user interaction. Based on that, the foundation tries
336
- // to focus the input. Since we do not handle the input value as part of the form- field, nor
355
+ // to focus the input. Since we do not handle the input value as part of the form field, nor
337
356
// it's guaranteed to be an input (see adapter methods above), this is a noop.
338
357
deregisterTextFieldInteractionHandler : ( ) => { } ,
339
358
registerTextFieldInteractionHandler : ( ) => { } ,
@@ -363,19 +382,20 @@ export class MatFormField
363
382
@Optional ( ) @Inject ( ANIMATION_MODULE_TYPE ) public _animationMode ?: string ,
364
383
@Inject ( DOCUMENT ) private _document ?: any ,
365
384
) {
366
- if ( _defaults && _defaults . appearance ) {
367
- this . appearance = _defaults . appearance ;
385
+ if ( _defaults ) {
386
+ if ( _defaults . appearance ) {
387
+ this . appearance = _defaults . appearance ;
388
+ }
389
+ this . _hideRequiredMarker = Boolean ( _defaults ?. hideRequiredMarker ) ;
368
390
}
369
-
370
- this . _hideRequiredMarker = _defaults ?. hideRequiredMarker ?? false ;
371
391
}
372
392
373
393
ngAfterViewInit ( ) {
374
394
this . _foundation = new MDCTextFieldFoundation ( this . _adapter ) ;
375
395
376
396
// MDC uses the "shouldFloat" getter to know whether the label is currently floating. This
377
397
// does not match our implementation of when the label floats because we support more cases.
378
- // For example, consumers can set "@Input floatLabel" to always, or the custom form- field
398
+ // For example, consumers can set "@Input floatLabel" to always, or the custom form field
379
399
// control can set "MatFormFieldControl#shouldLabelFloat" to true. To ensure that MDC knows
380
400
// when the label is floating, we overwrite the property to be based on the method we use to
381
401
// determine the current state of the floating label.
@@ -386,11 +406,11 @@ export class MatFormField
386
406
// By default, the foundation determines the validity of the text-field from the
387
407
// specified native input. Since we don't pass a native input to the foundation because
388
408
// abstract form controls are not necessarily consisting of an input, we handle the
389
- // text-field validity through the abstract form- field control state.
409
+ // text-field validity through the abstract form field control state.
390
410
this . _foundation . isValid = ( ) => ! this . _control . errorState ;
391
411
392
412
// Initial focus state sync. This happens rarely, but we want to account for
393
- // it in case the form- field control has "focused" set to true on init.
413
+ // it in case the form field control has "focused" set to true on init.
394
414
this . _updateFocusState ( ) ;
395
415
// Initial notch width update. This is needed in case the text-field label floats
396
416
// on initialization, and renders inside of the notched outline.
@@ -442,7 +462,7 @@ export class MatFormField
442
462
}
443
463
444
464
/**
445
- * Gets an ElementRef for the element that a overlay attached to the form- field
465
+ * Gets an ElementRef for the element that a overlay attached to the form field
446
466
* should be positioned relative to.
447
467
*/
448
468
getConnectedOverlayOrigin ( ) : ElementRef {
@@ -451,20 +471,20 @@ export class MatFormField
451
471
452
472
/** Animates the placeholder up and locks it in position. */
453
473
_animateAndLockLabel ( ) : void {
454
- // This is for backwards compatibility only. Consumers of the form- field might use
474
+ // This is for backwards compatibility only. Consumers of the form field might use
455
475
// this method. e.g. the autocomplete trigger. This method has been added to the non-MDC
456
- // form- field because setting "floatLabel" to "always" caused the label to float without
476
+ // form field because setting "floatLabel" to "always" caused the label to float without
457
477
// animation. This is different in MDC where the label always animates, so this method
458
478
// is no longer necessary. There doesn't seem any benefit in adding logic to allow changing
459
479
// the floating label state without animations. The non-MDC implementation was inconsistent
460
480
// because it always animates if "floatLabel" is set away from "always".
461
- // TODO(devversion): consider removing this method when releasing the MDC form- field.
481
+ // TODO(devversion): consider removing this method when releasing the MDC form field.
462
482
if ( this . _hasFloatingLabel ( ) ) {
463
483
this . floatLabel = 'always' ;
464
484
}
465
485
}
466
486
467
- /** Initializes the registered form- field control. */
487
+ /** Initializes the registered form field control. */
468
488
private _initializeControl ( ) {
469
489
const control = this . _control ;
470
490
@@ -499,7 +519,7 @@ export class MatFormField
499
519
/** Initializes the prefix and suffix containers. */
500
520
private _initializePrefixAndSuffix ( ) {
501
521
this . _checkPrefixAndSuffixTypes ( ) ;
502
- // Mark the form- field as dirty whenever the prefix or suffix children change. This
522
+ // Mark the form field as dirty whenever the prefix or suffix children change. This
503
523
// is necessary because we conditionally display the prefix/suffix containers based
504
524
// on whether there is projected content.
505
525
merge ( this . _prefixChildren . changes , this . _suffixChildren . changes ) . subscribe ( ( ) => {
@@ -510,7 +530,7 @@ export class MatFormField
510
530
511
531
/**
512
532
* Initializes the subscript by validating hints and synchronizing "aria-describedby" ids
513
- * with the custom form- field control. Also subscribes to hint and error changes in order
533
+ * with the custom form field control. Also subscribes to hint and error changes in order
514
534
* to be able to validate and synchronize ids on change.
515
535
*/
516
536
private _initializeSubscript ( ) {
@@ -541,9 +561,9 @@ export class MatFormField
541
561
private _updateFocusState ( ) {
542
562
// Usually the MDC foundation would call "activateFocus" and "deactivateFocus" whenever
543
563
// certain DOM events are emitted. This is not possible in our implementation of the
544
- // form- field because we support abstract form field controls which are not necessarily
545
- // of type input, nor do we have a reference to a native form- field control element. Instead
546
- // we handle the focus by checking if the abstract form- field control focused state changes.
564
+ // form field because we support abstract form field controls which are not necessarily
565
+ // of type input, nor do we have a reference to a native form field control element. Instead
566
+ // we handle the focus by checking if the abstract form field control focused state changes.
547
567
if ( this . _control . focused && ! this . _isFocused ) {
548
568
this . _isFocused = true ;
549
569
this . _foundation . activateFocus ( ) ;
@@ -556,7 +576,7 @@ export class MatFormField
556
576
/**
557
577
* The floating label in the docked state needs to account for prefixes. The horizontal offset
558
578
* is calculated whenever the appearance changes to `outline`, the prefixes change, or when the
559
- * form- field is added to the DOM. This method sets up all subscriptions which are needed to
579
+ * form field is added to the DOM. This method sets up all subscriptions which are needed to
560
580
* trigger the label offset update. In general, we want to avoid performing measurements often,
561
581
* so we rely on the `NgZone` as indicator when the offset should be recalculated, instead of
562
582
* checking every change detection cycle.
@@ -595,7 +615,7 @@ export class MatFormField
595
615
/**
596
616
* Whether the label should display in the infix. Labels in the outline appearance are
597
617
* displayed as part of the notched-outline and are horizontally offset to account for
598
- * form- field prefix content. This won't work in server side rendering since we cannot
618
+ * form field prefix content. This won't work in server side rendering since we cannot
599
619
* measure the width of the prefix container. To make the docked label appear as if the
600
620
* right offset has been calculated, we forcibly render the label inside the infix. Since
601
621
* the label is part of the infix, the label cannot overflow the prefix content.
@@ -729,7 +749,7 @@ export class MatFormField
729
749
floatingLabel . style . transform = '' ;
730
750
return ;
731
751
}
732
- // If the form- field is not attached to the DOM yet (e.g. in a tab), we defer
752
+ // If the form field is not attached to the DOM yet (e.g. in a tab), we defer
733
753
// the label offset update until the zone stabilizes.
734
754
if ( ! this . _isAttachedToDom ( ) ) {
735
755
this . _needsOutlineLabelOffsetUpdateOnStable = true ;
0 commit comments