Skip to content

Commit e884f48

Browse files
matskochuckjaz
authored andcommitted
feat(animations): provide aliases for :enter and :leave transitions (#11991)
1 parent df1822f commit e884f48

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

modules/@angular/compiler/src/animation/animation_parser.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,25 @@ function _parseAnimationStateTransition(
132132
return new AnimationStateTransitionAst(transitionExprs, stepsAst);
133133
}
134134

135+
function _parseAnimationAlias(alias: string, errors: AnimationParseError[]): string {
136+
switch (alias) {
137+
case ':enter':
138+
return 'void => *';
139+
case ':leave':
140+
return '* => void';
141+
default:
142+
errors.push(
143+
new AnimationParseError(`the transition alias value "${alias}" is not supported`));
144+
return '* => *';
145+
}
146+
}
147+
135148
function _parseAnimationTransitionExpr(
136149
eventStr: string, errors: AnimationParseError[]): AnimationStateTransitionExpression[] {
137-
var expressions: any[] /** TODO #9100 */ = [];
150+
var expressions: AnimationStateTransitionExpression[] = [];
151+
if (eventStr[0] == ':') {
152+
eventStr = _parseAnimationAlias(eventStr, errors);
153+
}
138154
var match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
139155
if (!isPresent(match) || match.length < 4) {
140156
errors.push(new AnimationParseError(`the provided ${eventStr} is not of a supported format`));

modules/@angular/core/test/animation/animation_integration_spec.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,87 @@ function declareTests({useJit}: {useJit: boolean}) {
146146
expect(kf[1]).toEqual([1, {'background': 'blue'}]);
147147
}));
148148

149+
describe('animation aliases', () => {
150+
it('should animate the ":enter" animation alias as "void => *"', fakeAsync(() => {
151+
TestBed.overrideComponent(DummyIfCmp, {
152+
set: {
153+
template: `
154+
<div *ngIf="exp" [@myAnimation]="exp"></div>
155+
`,
156+
animations: [trigger(
157+
'myAnimation',
158+
[transition(
159+
':enter',
160+
[style({'opacity': 0}), animate('500ms', style({opacity: 1}))])])]
161+
}
162+
});
163+
164+
const driver = TestBed.get(AnimationDriver) as MockAnimationDriver;
165+
let fixture = TestBed.createComponent(DummyIfCmp);
166+
var cmp = fixture.componentInstance;
167+
cmp.exp = true;
168+
fixture.detectChanges();
169+
170+
expect(driver.log.length).toEqual(1);
171+
172+
var animation = driver.log[0];
173+
expect(animation['duration']).toEqual(500);
174+
}));
175+
176+
it('should animate the ":leave" animation alias as "* => void"', fakeAsync(() => {
177+
TestBed.overrideComponent(DummyIfCmp, {
178+
set: {
179+
template: `
180+
<div *ngIf="exp" [@myAnimation]="exp"></div>
181+
`,
182+
animations: [trigger(
183+
'myAnimation',
184+
[transition(':leave', [animate('999ms', style({opacity: 0}))])])]
185+
}
186+
});
187+
188+
const driver = TestBed.get(AnimationDriver) as MockAnimationDriver;
189+
let fixture = TestBed.createComponent(DummyIfCmp);
190+
var cmp = fixture.componentInstance;
191+
cmp.exp = true;
192+
fixture.detectChanges();
193+
194+
expect(driver.log.length).toEqual(0);
195+
196+
cmp.exp = false;
197+
fixture.detectChanges();
198+
199+
expect(driver.log.length).toEqual(1);
200+
201+
var animation = driver.log[0];
202+
expect(animation['duration']).toEqual(999);
203+
}));
204+
205+
it('should throw an error when an unsupported alias is detected which is prefixed a colon value',
206+
fakeAsync(() => {
207+
TestBed.overrideComponent(DummyIfCmp, {
208+
set: {
209+
template: `
210+
<div *ngIf="exp" [@myAnimation]="exp"></div>
211+
`,
212+
animations: [trigger(
213+
'myAnimation',
214+
[transition(':dont_leave_me', [animate('444ms', style({opacity: 0}))])])]
215+
}
216+
});
217+
218+
var message = '';
219+
try {
220+
let fixture = TestBed.createComponent(DummyIfCmp);
221+
} catch (e) {
222+
message = e.message;
223+
}
224+
225+
expect(message).toMatch(
226+
/the transition alias value ":dont_leave_me" is not supported/);
227+
}));
228+
});
229+
149230
it('should animate between * and void and back even when no expression is assigned',
150231
fakeAsync(() => {
151232
TestBed.overrideComponent(DummyIfCmp, {

0 commit comments

Comments
 (0)