Skip to content

Commit 0752958

Browse files
committed
refactor: export component animations for reuse
Exports all of the component animations so they can be reused by consumers. Fixes #8904.
1 parent 2436acd commit 0752958

35 files changed

+574
-315
lines changed

src/lib/dialog/dialog-animations.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {
9+
animate,
10+
state,
11+
style,
12+
transition,
13+
trigger,
14+
AnimationTriggerMetadata,
15+
} from '@angular/animations';
16+
17+
/**
18+
* Animations used by MatDialog.
19+
*/
20+
export const matDialogAnimations: {
21+
readonly slideDialog: AnimationTriggerMetadata;
22+
} = {
23+
/**
24+
* Animation that slides the dialog in and out of view and fades the opacity.
25+
*/
26+
slideDialog: trigger('slideDialog', [
27+
// Note: The `enter` animation doesn't transition to something like `translate3d(0, 0, 0)
28+
// scale(1)`, because for some reason specifying the transform explicitly, causes IE both
29+
// to blur the dialog content and decimate the animation performance. Leaving it as `none`
30+
// solves both issues.
31+
state('enter', style({ transform: 'none', opacity: 1 })),
32+
state('void', style({ transform: 'translate3d(0, 25%, 0) scale(0.9)', opacity: 0 })),
33+
state('exit', style({ transform: 'translate3d(0, 25%, 0)', opacity: 0 })),
34+
transition('* => *', animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
35+
])
36+
};

src/lib/dialog/dialog-container.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import {
1919
ViewEncapsulation,
2020
ChangeDetectionStrategy,
2121
} from '@angular/core';
22-
import {animate, AnimationEvent, state, style, transition, trigger} from '@angular/animations';
2322
import {DOCUMENT} from '@angular/common';
23+
import {AnimationEvent} from '@angular/animations';
24+
import {matDialogAnimations} from './dialog-animations';
2425
import {
2526
BasePortalOutlet,
2627
ComponentPortal,
@@ -55,18 +56,7 @@ export function throwMatDialogContentAlreadyAttachedError() {
5556
// Using OnPush for dialogs caused some G3 sync issues. Disabled until we can track them down.
5657
// tslint:disable-next-line:validate-decorators
5758
changeDetection: ChangeDetectionStrategy.Default,
58-
animations: [
59-
trigger('slideDialog', [
60-
// Note: The `enter` animation doesn't transition to something like `translate3d(0, 0, 0)
61-
// scale(1)`, because for some reason specifying the transform explicitly, causes IE both
62-
// to blur the dialog content and decimate the animation performance. Leaving it as `none`
63-
// solves both issues.
64-
state('enter', style({ transform: 'none', opacity: 1 })),
65-
state('void', style({ transform: 'translate3d(0, 25%, 0) scale(0.9)', opacity: 0 })),
66-
state('exit', style({ transform: 'translate3d(0, 25%, 0)', opacity: 0 })),
67-
transition('* => *', animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
68-
])
69-
],
59+
animations: [matDialogAnimations.slideDialog],
7060
host: {
7161
'class': 'mat-dialog-container',
7262
'tabindex': '-1',

src/lib/dialog/public-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ export * from './dialog-container';
1212
export * from './dialog-content-directives';
1313
export * from './dialog-config';
1414
export * from './dialog-ref';
15-
15+
export * from './dialog-animations';
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {
9+
animate,
10+
state,
11+
style,
12+
transition,
13+
trigger,
14+
AnimationTriggerMetadata,
15+
} from '@angular/animations';
16+
17+
/** Time and timing curve for expansion panel animations. */
18+
export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)';
19+
20+
/**
21+
* Animations used by the Material expansion panel.
22+
*/
23+
export const matExpansionAnimations: {
24+
readonly indicatorRotate: AnimationTriggerMetadata;
25+
readonly expansionHeaderHeight: AnimationTriggerMetadata;
26+
readonly bodyExpansion: AnimationTriggerMetadata;
27+
} = {
28+
/**
29+
* Animation that rotates the indicator arrow.
30+
*/
31+
indicatorRotate: trigger('indicatorRotate', [
32+
state('collapsed', style({transform: 'rotate(0deg)'})),
33+
state('expanded', style({transform: 'rotate(180deg)'})),
34+
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
35+
]),
36+
37+
/**
38+
* Animation that expands and collapses the panel header height.
39+
*/
40+
expansionHeaderHeight: trigger('expansionHeight', [
41+
state('collapsed', style({
42+
height: '{{collapsedHeight}}',
43+
}), {
44+
params: {collapsedHeight: '48px'},
45+
}),
46+
state('expanded', style({
47+
height: '{{expandedHeight}}'
48+
}), {
49+
params: {expandedHeight: '64px'}
50+
}),
51+
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
52+
]),
53+
54+
/**
55+
* Animation that expands and collapses the panel content.
56+
*/
57+
bodyExpansion: trigger('bodyExpansion', [
58+
state('collapsed', style({height: '0px', visibility: 'hidden'})),
59+
state('expanded', style({height: '*', visibility: 'visible'})),
60+
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
61+
])
62+
};

src/lib/expansion/expansion-panel-header.ts

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {animate, state, style, transition, trigger} from '@angular/animations';
109
import {FocusMonitor} from '@angular/cdk/a11y';
1110
import {ENTER, SPACE} from '@angular/cdk/keycodes';
1211
import {filter} from 'rxjs/operators/filter';
@@ -23,7 +22,8 @@ import {
2322
} from '@angular/core';
2423
import {merge} from 'rxjs/observable/merge';
2524
import {Subscription} from 'rxjs/Subscription';
26-
import {EXPANSION_PANEL_ANIMATION_TIMING, MatExpansionPanel} from './expansion-panel';
25+
import {MatExpansionPanel} from './expansion-panel';
26+
import {matExpansionAnimations} from './expansion-animations';
2727

2828

2929
/**
@@ -41,6 +41,10 @@ import {EXPANSION_PANEL_ANIMATION_TIMING, MatExpansionPanel} from './expansion-p
4141
encapsulation: ViewEncapsulation.None,
4242
preserveWhitespaces: false,
4343
changeDetection: ChangeDetectionStrategy.OnPush,
44+
animations: [
45+
matExpansionAnimations.indicatorRotate,
46+
matExpansionAnimations.expansionHeaderHeight
47+
],
4448
host: {
4549
'class': 'mat-expansion-panel-header',
4650
'role': 'button',
@@ -59,26 +63,6 @@ import {EXPANSION_PANEL_ANIMATION_TIMING, MatExpansionPanel} from './expansion-p
5963
}
6064
}`,
6165
},
62-
animations: [
63-
trigger('indicatorRotate', [
64-
state('collapsed', style({transform: 'rotate(0deg)'})),
65-
state('expanded', style({transform: 'rotate(180deg)'})),
66-
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
67-
]),
68-
trigger('expansionHeight', [
69-
state('collapsed', style({
70-
height: '{{collapsedHeight}}',
71-
}), {
72-
params: {collapsedHeight: '48px'},
73-
}),
74-
state('expanded', style({
75-
height: '{{expandedHeight}}'
76-
}), {
77-
params: {expandedHeight: '64px'}
78-
}),
79-
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
80-
]),
81-
],
8266
})
8367
export class MatExpansionPanelHeader implements OnDestroy {
8468
private _parentChangeSubscription = Subscription.EMPTY;

src/lib/expansion/expansion-panel.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {animate, state, style, transition, trigger} from '@angular/animations';
109
import {
1110
ChangeDetectionStrategy,
1211
ChangeDetectorRef,
@@ -35,9 +34,7 @@ import {startWith} from 'rxjs/operators/startWith';
3534
import {MatAccordion} from './accordion';
3635
import {coerceBooleanProperty} from '@angular/cdk/coercion';
3736
import {MatExpansionPanelContent} from './expansion-panel-content';
38-
39-
/** Time and timing curve for expansion panel animations. */
40-
export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)';
37+
import {matExpansionAnimations} from './expansion-animations';
4138

4239
// Boilerplate for applying mixins to MatExpansionPanel.
4340
/** @docs-private */
@@ -79,6 +76,7 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
7976
changeDetection: ChangeDetectionStrategy.OnPush,
8077
inputs: ['disabled', 'expanded'],
8178
outputs: ['opened', 'closed'],
79+
animations: [matExpansionAnimations.bodyExpansion],
8280
host: {
8381
'class': 'mat-expansion-panel',
8482
'[class.mat-expanded]': 'expanded',
@@ -87,13 +85,6 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
8785
providers: [
8886
{provide: _MatExpansionPanelMixinBase, useExisting: forwardRef(() => MatExpansionPanel)}
8987
],
90-
animations: [
91-
trigger('bodyExpansion', [
92-
state('collapsed', style({height: '0px', visibility: 'hidden'})),
93-
state('expanded', style({height: '*', visibility: 'visible'})),
94-
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
95-
]),
96-
],
9788
})
9889
export class MatExpansionPanel extends _MatExpansionPanelMixinBase
9990
implements CanDisable, AfterContentInit, OnChanges, OnDestroy {

src/lib/expansion/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ export * from './accordion';
1111
export * from './expansion-panel';
1212
export * from './expansion-panel-header';
1313
export * from './expansion-panel-content';
14+
export * from './expansion-animations';
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {
9+
animate,
10+
state,
11+
style,
12+
transition,
13+
trigger,
14+
AnimationTriggerMetadata,
15+
} from '@angular/animations';
16+
17+
/**
18+
* Animations used by the MatFormField.
19+
*/
20+
export const matFormFieldAnimations: {
21+
readonly transitionMessages: AnimationTriggerMetadata
22+
} = {
23+
/**
24+
* Animation that transitions the form field's error and hint messages.
25+
*/
26+
transitionMessages: trigger('transitionMessages', [
27+
// TODO(mmalerba): Use angular animations for label animation as well.
28+
state('enter', style({ opacity: 1, transform: 'translateY(0%)' })),
29+
transition('void => enter', [
30+
style({ opacity: 0, transform: 'translateY(-100%)' }),
31+
animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)'),
32+
]),
33+
])
34+
};

src/lib/form-field/form-field.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {animate, state, style, transition, trigger} from '@angular/animations';
109
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1110
import {take} from 'rxjs/operators/take';
1211
import {startWith} from 'rxjs/operators/startWith';
@@ -41,6 +40,7 @@ import {MatPlaceholder} from './placeholder';
4140
import {MatLabel} from './label';
4241
import {MatPrefix} from './prefix';
4342
import {MatSuffix} from './suffix';
43+
import {matFormFieldAnimations} from './form-field-animations';
4444

4545

4646
let nextUniqueId = 0;
@@ -57,16 +57,7 @@ let nextUniqueId = 0;
5757
// The MatInput styles are fairly minimal so it shouldn't be a big deal for people who
5858
// aren't using MatInput.
5959
styleUrls: ['form-field.css', '../input/input.css'],
60-
animations: [
61-
// TODO(mmalerba): Use angular animations for label animation as well.
62-
trigger('transitionMessages', [
63-
state('enter', style({ opacity: 1, transform: 'translateY(0%)' })),
64-
transition('void => enter', [
65-
style({ opacity: 0, transform: 'translateY(-100%)' }),
66-
animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)'),
67-
]),
68-
]),
69-
],
60+
animations: [matFormFieldAnimations.transitionMessages],
7061
host: {
7162
'class': 'mat-input-container mat-form-field',
7263
'[class.mat-input-invalid]': '_control.errorState',

src/lib/form-field/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export * from './placeholder';
1616
export * from './prefix';
1717
export * from './suffix';
1818
export * from './label';
19+
export * from './form-field-animations';

0 commit comments

Comments
 (0)