Skip to content

Commit c7d715b

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 2fb4d61 commit c7d715b

36 files changed

+565
-311
lines changed

src/lib/dialog/dialog-animations.ts

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 MatDialog.
19+
*/
20+
export namespace MatDialogAnimations {
21+
/**
22+
* Animation that slides the dialog in and out of view and fades the opacity.
23+
*/
24+
export const slideDialog: AnimationTriggerMetadata = trigger('slideDialog', [
25+
// Note: The `enter` animation doesn't transition to something like `translate3d(0, 0, 0)
26+
// scale(1)`, because for some reason specifying the transform explicitly, causes IE both
27+
// to blur the dialog content and decimate the animation performance. Leaving it as `none`
28+
// solves both issues.
29+
state('enter', style({ transform: 'none', opacity: 1 })),
30+
state('void', style({ transform: 'translate3d(0, 25%, 0) scale(0.9)', opacity: 0 })),
31+
state('exit', style({ transform: 'translate3d(0, 25%, 0)', opacity: 0 })),
32+
transition('* => *', animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
33+
]);
34+
}

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: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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 Material expansion panel.
19+
*/
20+
export namespace MatExpansionAnimations {
21+
/** Time and timing curve for expansion panel animations. */
22+
export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)';
23+
24+
/**
25+
* Animation that rotates the indicator arrow.
26+
*/
27+
export const indicatorRotate: AnimationTriggerMetadata = trigger('indicatorRotate', [
28+
state('collapsed', style({transform: 'rotate(0deg)'})),
29+
state('expanded', style({transform: 'rotate(180deg)'})),
30+
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
31+
]);
32+
33+
/**
34+
* Animation that expands and collapses the panel header height.
35+
*/
36+
export const expansionHeaderHeight: AnimationTriggerMetadata = trigger('expansionHeight', [
37+
state('collapsed', style({
38+
height: '{{collapsedHeight}}',
39+
}), {
40+
params: {collapsedHeight: '48px'},
41+
}),
42+
state('expanded', style({
43+
height: '{{expandedHeight}}'
44+
}), {
45+
params: {expandedHeight: '64px'}
46+
}),
47+
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
48+
]);
49+
50+
/**
51+
* Animation that expands and collapses the panel content.
52+
*/
53+
export const bodyExpansion: AnimationTriggerMetadata = trigger('bodyExpansion', [
54+
state('collapsed', style({height: '0px', visibility: 'hidden'})),
55+
state('expanded', style({height: '*', visibility: 'visible'})),
56+
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
57+
]);
58+
}

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,
@@ -27,9 +26,7 @@ import {CanDisable, mixinDisabled} from '@angular/material/core';
2726
import {Subject} from 'rxjs/Subject';
2827
import {MatAccordion} from './accordion';
2928
import {coerceBooleanProperty} from '@angular/cdk/coercion';
30-
31-
/** Time and timing curve for expansion panel animations. */
32-
export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)';
29+
import {MatExpansionAnimations} from './expansion-animations';
3330

3431
// Boilerplate for applying mixins to MatExpansionPanel.
3532
/** @docs-private */
@@ -71,6 +68,7 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
7168
changeDetection: ChangeDetectionStrategy.OnPush,
7269
inputs: ['disabled', 'expanded'],
7370
outputs: ['opened', 'closed'],
71+
animations: [MatExpansionAnimations.bodyExpansion],
7472
host: {
7573
'class': 'mat-expansion-panel',
7674
'[class.mat-expanded]': 'expanded',
@@ -79,13 +77,6 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
7977
providers: [
8078
{provide: _MatExpansionPanelMixinBase, useExisting: forwardRef(() => MatExpansionPanel)}
8179
],
82-
animations: [
83-
trigger('bodyExpansion', [
84-
state('collapsed', style({height: '0px', visibility: 'hidden'})),
85-
state('expanded', style({height: '*', visibility: 'visible'})),
86-
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
87-
]),
88-
],
8980
})
9081
export class MatExpansionPanel extends _MatExpansionPanelMixinBase
9182
implements CanDisable, OnChanges, OnDestroy {

src/lib/expansion/public-api.ts

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

9+
import {MatExpansionAnimations} from './expansion-animations';
10+
911
export * from './expansion-module';
1012
export * from './accordion';
1113
export * from './expansion-panel';
1214
export * from './expansion-panel-header';
15+
export * from './expansion-animations';
1316

14-
17+
/** @deprecated */
18+
export const EXPANSION_PANEL_ANIMATION_TIMING =
19+
MatExpansionAnimations.EXPANSION_PANEL_ANIMATION_TIMING;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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 namespace MatFormFieldAnimations {
21+
/**
22+
* Animation that transitions the form field's error and hint messages.
23+
*/
24+
export const transitionMessages: AnimationTriggerMetadata = trigger('transitionMessages', [
25+
// TODO(mmalerba): Use angular animations for label animation as well.
26+
state('enter', style({ opacity: 1, transform: 'translateY(0%)' })),
27+
transition('void => enter', [
28+
style({ opacity: 0, transform: 'translateY(-100%)' }),
29+
animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)'),
30+
]),
31+
]);
32+
}

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)