@@ -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,9 +184,9 @@ 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. */
189
+ /** The color palette for the form field. */
178
190
@Input ( ) color : ThemePalette = 'primary' ;
179
191
180
192
/** Whether the label should always float or float as the user types. */
@@ -185,23 +197,23 @@ export class MatFormField
185
197
set floatLabel ( value : FloatLabelType ) {
186
198
if ( value !== this . _floatLabel ) {
187
199
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.
200
+ // For backwards compatibility. Custom form field controls or directives might set
201
+ // the "floatLabel" input and expect the form field view to be updated automatically.
190
202
// e.g. autocomplete trigger. Ideally we'd get rid of this and the consumers would just
191
203
// emit the "stateChanges" observable. TODO(devversion): consider removing.
192
204
this . _changeDetectorRef . markForCheck ( ) ;
193
205
}
194
206
}
195
207
private _floatLabel : FloatLabelType ;
196
208
197
- /** The form- field appearance style. */
209
+ /** The form field appearance style. */
198
210
@Input ( )
199
211
get appearance ( ) : MatFormFieldAppearance {
200
212
return this . _appearance ;
201
213
}
202
214
set appearance ( value : MatFormFieldAppearance ) {
203
215
const oldValue = this . _appearance ;
204
- this . _appearance = value || ( this . _defaults && this . _defaults . appearance ) || DEFAULT_APPEARANCE ;
216
+ this . _appearance = value || this . _defaults ?. appearance || DEFAULT_APPEARANCE ;
205
217
if ( this . _appearance === 'outline' && this . _appearance !== oldValue ) {
206
218
this . _refreshOutlineNotchWidth ( ) ;
207
219
@@ -280,7 +292,7 @@ export class MatFormField
280
292
// MDC text-field will call this method on focus, blur and value change. It expects us
281
293
// to update the floating label state accordingly. Though we make this a noop because we
282
294
// 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
295
+ // adapter method would mean that the label would not update if the custom form field control
284
296
// sets "shouldLabelFloat" to true, or if the "floatLabel" input binding changes to "always".
285
297
floatLabel : ( ) => { } ,
286
298
@@ -294,7 +306,7 @@ export class MatFormField
294
306
// closed. This works fine in the standard MDC text-field, but not in Angular where the
295
307
// floating label could change through interpolation. We want to be able to update the
296
308
// 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
309
+ // blur to open and close the notch does not work for us since abstract form field controls
298
310
// have the ability to control the floating label state (i.e. `shouldLabelFloat`), and we
299
311
// want to update the notch whenever the `_shouldLabelFloat()` value changes.
300
312
getLabelWidth : ( ) => 0 ,
@@ -312,28 +324,28 @@ export class MatFormField
312
324
313
325
// The foundation tries to register events on the input. This is not matching
314
326
// 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
327
+ // in "stateChanges" based on the form field control state. The following events
316
328
// need to be handled: focus, blur. We do not handle the "input" event since
317
329
// 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
330
+ // not implement as part of the form field, but should be implemented manually
319
331
// by consumers using template bindings.
320
332
registerInputInteractionHandler : ( ) => { } ,
321
333
deregisterInputInteractionHandler : ( ) => { } ,
322
334
323
335
// We do not have a reference to the native input since we work with abstract form field
324
336
// controls. MDC needs a reference to the native input optionally to handle character
325
337
// counting and value updating. These are both things we do not handle from within the
326
- // form- field, so we can just return null.
338
+ // form field, so we can just return null.
327
339
getNativeInput : ( ) => null ,
328
340
329
341
// This method will never be called since we do not have the ability to add event listeners
330
342
// to the native input. This is because the form control is not necessarily an input, and
331
343
// the form field deals with abstract form controls of any type.
332
344
setLineRippleTransformOrigin : ( ) => { } ,
333
345
334
- // The foundation tries to register click and keyboard events on the form- field to figure out
346
+ // The foundation tries to register click and keyboard events on the form field to figure out
335
347
// 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
348
+ // to focus the input. Since we do not handle the input value as part of the form field, nor
337
349
// it's guaranteed to be an input (see adapter methods above), this is a noop.
338
350
deregisterTextFieldInteractionHandler : ( ) => { } ,
339
351
registerTextFieldInteractionHandler : ( ) => { } ,
@@ -363,19 +375,23 @@ export class MatFormField
363
375
@Optional ( ) @Inject ( ANIMATION_MODULE_TYPE ) public _animationMode ?: string ,
364
376
@Inject ( DOCUMENT ) private _document ?: any ,
365
377
) {
366
- if ( _defaults && _defaults . appearance ) {
367
- this . appearance = _defaults . appearance ;
378
+ if ( _defaults ) {
379
+ if ( _defaults . appearance ) {
380
+ this . appearance = _defaults . appearance ;
381
+ }
382
+ this . _hideRequiredMarker = Boolean ( _defaults ?. hideRequiredMarker ) ;
383
+ if ( _defaults . color ) {
384
+ this . color = _defaults . color ;
385
+ }
368
386
}
369
-
370
- this . _hideRequiredMarker = _defaults ?. hideRequiredMarker ?? false ;
371
387
}
372
388
373
389
ngAfterViewInit ( ) {
374
390
this . _foundation = new MDCTextFieldFoundation ( this . _adapter ) ;
375
391
376
392
// MDC uses the "shouldFloat" getter to know whether the label is currently floating. This
377
393
// 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
394
+ // For example, consumers can set "@Input floatLabel" to always, or the custom form field
379
395
// control can set "MatFormFieldControl#shouldLabelFloat" to true. To ensure that MDC knows
380
396
// when the label is floating, we overwrite the property to be based on the method we use to
381
397
// determine the current state of the floating label.
@@ -386,11 +402,11 @@ export class MatFormField
386
402
// By default, the foundation determines the validity of the text-field from the
387
403
// specified native input. Since we don't pass a native input to the foundation because
388
404
// abstract form controls are not necessarily consisting of an input, we handle the
389
- // text-field validity through the abstract form- field control state.
405
+ // text-field validity through the abstract form field control state.
390
406
this . _foundation . isValid = ( ) => ! this . _control . errorState ;
391
407
392
408
// 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.
409
+ // it in case the form field control has "focused" set to true on init.
394
410
this . _updateFocusState ( ) ;
395
411
// Initial notch width update. This is needed in case the text-field label floats
396
412
// on initialization, and renders inside of the notched outline.
@@ -442,7 +458,7 @@ export class MatFormField
442
458
}
443
459
444
460
/**
445
- * Gets an ElementRef for the element that a overlay attached to the form- field
461
+ * Gets an ElementRef for the element that a overlay attached to the form field
446
462
* should be positioned relative to.
447
463
*/
448
464
getConnectedOverlayOrigin ( ) : ElementRef {
@@ -451,20 +467,20 @@ export class MatFormField
451
467
452
468
/** Animates the placeholder up and locks it in position. */
453
469
_animateAndLockLabel ( ) : void {
454
- // This is for backwards compatibility only. Consumers of the form- field might use
470
+ // This is for backwards compatibility only. Consumers of the form field might use
455
471
// 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
472
+ // form field because setting "floatLabel" to "always" caused the label to float without
457
473
// animation. This is different in MDC where the label always animates, so this method
458
474
// is no longer necessary. There doesn't seem any benefit in adding logic to allow changing
459
475
// the floating label state without animations. The non-MDC implementation was inconsistent
460
476
// because it always animates if "floatLabel" is set away from "always".
461
- // TODO(devversion): consider removing this method when releasing the MDC form- field.
477
+ // TODO(devversion): consider removing this method when releasing the MDC form field.
462
478
if ( this . _hasFloatingLabel ( ) ) {
463
479
this . floatLabel = 'always' ;
464
480
}
465
481
}
466
482
467
- /** Initializes the registered form- field control. */
483
+ /** Initializes the registered form field control. */
468
484
private _initializeControl ( ) {
469
485
const control = this . _control ;
470
486
@@ -499,7 +515,7 @@ export class MatFormField
499
515
/** Initializes the prefix and suffix containers. */
500
516
private _initializePrefixAndSuffix ( ) {
501
517
this . _checkPrefixAndSuffixTypes ( ) ;
502
- // Mark the form- field as dirty whenever the prefix or suffix children change. This
518
+ // Mark the form field as dirty whenever the prefix or suffix children change. This
503
519
// is necessary because we conditionally display the prefix/suffix containers based
504
520
// on whether there is projected content.
505
521
merge ( this . _prefixChildren . changes , this . _suffixChildren . changes ) . subscribe ( ( ) => {
@@ -510,7 +526,7 @@ export class MatFormField
510
526
511
527
/**
512
528
* 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
529
+ * with the custom form field control. Also subscribes to hint and error changes in order
514
530
* to be able to validate and synchronize ids on change.
515
531
*/
516
532
private _initializeSubscript ( ) {
@@ -541,9 +557,9 @@ export class MatFormField
541
557
private _updateFocusState ( ) {
542
558
// Usually the MDC foundation would call "activateFocus" and "deactivateFocus" whenever
543
559
// 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.
560
+ // form field because we support abstract form field controls which are not necessarily
561
+ // of type input, nor do we have a reference to a native form field control element. Instead
562
+ // we handle the focus by checking if the abstract form field control focused state changes.
547
563
if ( this . _control . focused && ! this . _isFocused ) {
548
564
this . _isFocused = true ;
549
565
this . _foundation . activateFocus ( ) ;
@@ -556,7 +572,7 @@ export class MatFormField
556
572
/**
557
573
* The floating label in the docked state needs to account for prefixes. The horizontal offset
558
574
* 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
575
+ * form field is added to the DOM. This method sets up all subscriptions which are needed to
560
576
* trigger the label offset update. In general, we want to avoid performing measurements often,
561
577
* so we rely on the `NgZone` as indicator when the offset should be recalculated, instead of
562
578
* checking every change detection cycle.
@@ -595,7 +611,7 @@ export class MatFormField
595
611
/**
596
612
* Whether the label should display in the infix. Labels in the outline appearance are
597
613
* 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
614
+ * form field prefix content. This won't work in server side rendering since we cannot
599
615
* measure the width of the prefix container. To make the docked label appear as if the
600
616
* right offset has been calculated, we forcibly render the label inside the infix. Since
601
617
* the label is part of the infix, the label cannot overflow the prefix content.
@@ -729,7 +745,7 @@ export class MatFormField
729
745
floatingLabel . style . transform = '' ;
730
746
return ;
731
747
}
732
- // If the form- field is not attached to the DOM yet (e.g. in a tab), we defer
748
+ // If the form field is not attached to the DOM yet (e.g. in a tab), we defer
733
749
// the label offset update until the zone stabilizes.
734
750
if ( ! this . _isAttachedToDom ( ) ) {
735
751
this . _needsOutlineLabelOffsetUpdateOnStable = true ;
0 commit comments