Skip to content

Commit ed77ec9

Browse files
authored
feat(material-experimental/mdc-form-field): support for disabl… (#18397)
By leveraging the animations feature target, we can add support for disabling animations of the form-field. Unlike in non experimental Material components, the class for toggling the animations is now scoped to the component. This gives more fine-grained control and makes it public. The class doesn't need to be denoted as private, as it can be useful for implementers of custom form-field controls. Also fixes that the line-ripple styles are not included.
1 parent fc91061 commit ed77ec9

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

src/material-experimental/mdc-form-field/form-field.scss

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
@import 'mdc-text-field-structure-overrides';
88

99
// Base styles for MDC notched-outline, MDC floating label and MDC text-field.
10-
@include mdc-notched-outline-core-styles($query: $mat-base-styles-query);
11-
@include mdc-floating-label-core-styles($query: $mat-base-styles-query);
12-
@include mdc-text-field-core-styles($query: $mat-base-styles-query);
10+
@include mdc-notched-outline-core-styles($query: $mat-base-styles-without-animation-query);
11+
@include mdc-floating-label-core-styles($query: $mat-base-styles-without-animation-query);
12+
@include mdc-text-field-core-styles($query: $mat-base-styles-without-animation-query);
13+
@include mdc-line-ripple-core-styles($query: $mat-base-styles-without-animation-query);
1314

1415
// MDC text-field overwrites.
1516
@include _mat-mdc-text-field-textarea-overrides();
@@ -52,3 +53,12 @@
5253
min-height: $mdc-text-field-height;
5354
box-sizing: border-box;
5455
}
56+
57+
// In order to make it possible for developers to disable animations for form-fields,
58+
// we only activate the animation styles if animations are not explicitly disabled.
59+
.mat-mdc-form-field:not(.mat-form-field-no-animations) {
60+
@include mdc-notched-outline-core-styles($query: animation);
61+
@include mdc-floating-label-core-styles($query: animation);
62+
@include mdc-text-field-core-styles($query: animation);
63+
@include mdc-line-ripple-core-styles($query: animation);
64+
}

src/material-experimental/mdc-form-field/form-field.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ const FLOATING_LABEL_DEFAULT_DOCKED_TRANSFORM = `translateY(-50%)`;
104104
'[class.mat-form-field-invalid]': '_control.errorState',
105105
'[class.mat-form-field-disabled]': '_control.disabled',
106106
'[class.mat-form-field-autofilled]': '_control.autofilled',
107+
'[class.mat-form-field-no-animations]': '_animationMode === "NoopAnimations"',
107108
'[class.mat-focused]': '_control.focused',
108109
'[class.mat-accent]': 'color == "accent"',
109110
'[class.mat-warn]': 'color == "warn"',
@@ -114,7 +115,6 @@ const FLOATING_LABEL_DEFAULT_DOCKED_TRANSFORM = `translateY(-50%)`;
114115
'[class.ng-valid]': '_shouldForward("valid")',
115116
'[class.ng-invalid]': '_shouldForward("invalid")',
116117
'[class.ng-pending]': '_shouldForward("pending")',
117-
'[class._mat-animation-noopable]': '!_animationsEnabled',
118118
},
119119
encapsulation: ViewEncapsulation.None,
120120
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -194,9 +194,6 @@ export class MatFormField implements AfterViewInit, OnDestroy, AfterContentCheck
194194
// Unique id for the internal form field label.
195195
_labelId = `mat-form-field-label-${nextUniqueId++}`;
196196

197-
/** Whether the Angular animations are enabled. */
198-
_animationsEnabled: boolean;
199-
200197
/** State of the mat-hint and mat-error animations. */
201198
_subscriptAnimationState: string = '';
202199

@@ -283,9 +280,7 @@ export class MatFormField implements AfterViewInit, OnDestroy, AfterContentCheck
283280
@Optional() @Inject(MAT_FORM_FIELD_DEFAULT_OPTIONS)
284281
private _defaults?: MatFormFieldDefaultOptions,
285282
@Optional() @Inject(MAT_LABEL_GLOBAL_OPTIONS) private _labelOptions?: LabelOptions,
286-
@Optional() @Inject(ANIMATION_MODULE_TYPE) _animationMode?: string) {
287-
this._animationsEnabled = _animationMode !== 'NoopAnimations';
288-
283+
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) {
289284
if (_defaults && _defaults.appearance) {
290285
this.appearance = _defaults.appearance;
291286
} else if (_defaults && _defaults.hideRequiredMarker) {

src/material-experimental/mdc-input/input.spec.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import {
3333
ShowOnDirtyErrorStateMatcher,
3434
} from '@angular/material/core';
3535
import {By} from '@angular/platform-browser';
36-
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
36+
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
3737
import {MAT_INPUT_VALUE_ACCESSOR, MatInput, MatInputModule} from './index';
3838

3939
describe('MatMdcInput without forms', () => {
@@ -400,6 +400,15 @@ describe('MatMdcInput without forms', () => {
400400
expect(selectEl.disabled).toBe(true);
401401
}));
402402

403+
it('should add a class to the form-field if animations are disabled', () => {
404+
configureTestingModule(MatInputWithId, {animations: false});
405+
const fixture = TestBed.createComponent(MatInputWithId);
406+
fixture.detectChanges();
407+
408+
const formFieldEl = fixture.nativeElement.querySelector('.mat-mdc-form-field');
409+
expect(formFieldEl.classList).toContain('mat-form-field-no-animations');
410+
});
411+
403412
it('should add a class to the form field if it has a native select', fakeAsync(() => {
404413
const fixture = createComponent(MatInputSelect);
405414
fixture.detectChanges();
@@ -1139,16 +1148,15 @@ describe('MatFormField default options', () => {
11391148

11401149
});
11411150

1142-
function createComponent<T>(component: Type<T>,
1143-
providers: Provider[] = [],
1144-
imports: any[] = [],
1145-
declarations: any[] = []): ComponentFixture<T> {
1151+
function configureTestingModule(component: Type<any>, options:
1152+
{providers?: Provider[], imports?: any[], declarations?: any[], animations?: boolean} = {}) {
1153+
const {providers = [], imports = [], declarations = [], animations = true} = options;
11461154
TestBed.configureTestingModule({
11471155
imports: [
11481156
FormsModule,
11491157
MatFormFieldModule,
11501158
MatInputModule,
1151-
BrowserAnimationsModule,
1159+
animations ? BrowserAnimationsModule : NoopAnimationsModule,
11521160
PlatformModule,
11531161
ReactiveFormsModule,
11541162
...imports
@@ -1163,7 +1171,13 @@ function createComponent<T>(component: Type<T>,
11631171
...providers
11641172
],
11651173
}).compileComponents();
1174+
}
11661175

1176+
function createComponent<T>(component: Type<T>,
1177+
providers: Provider[] = [],
1178+
imports: any[] = [],
1179+
declarations: any[] = []): ComponentFixture<T> {
1180+
configureTestingModule(component, {providers, imports, declarations});
11671181
return TestBed.createComponent<T>(component);
11681182
}
11691183

0 commit comments

Comments
 (0)