feat(animations): provide aliases for :enter and :leave transitions (#11991)
This commit is contained in:
parent
df1822fc2a
commit
e884f4854d
|
@ -132,9 +132,25 @@ function _parseAnimationStateTransition(
|
||||||
return new AnimationStateTransitionAst(transitionExprs, stepsAst);
|
return new AnimationStateTransitionAst(transitionExprs, stepsAst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _parseAnimationAlias(alias: string, errors: AnimationParseError[]): string {
|
||||||
|
switch (alias) {
|
||||||
|
case ':enter':
|
||||||
|
return 'void => *';
|
||||||
|
case ':leave':
|
||||||
|
return '* => void';
|
||||||
|
default:
|
||||||
|
errors.push(
|
||||||
|
new AnimationParseError(`the transition alias value "${alias}" is not supported`));
|
||||||
|
return '* => *';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function _parseAnimationTransitionExpr(
|
function _parseAnimationTransitionExpr(
|
||||||
eventStr: string, errors: AnimationParseError[]): AnimationStateTransitionExpression[] {
|
eventStr: string, errors: AnimationParseError[]): AnimationStateTransitionExpression[] {
|
||||||
var expressions: any[] /** TODO #9100 */ = [];
|
var expressions: AnimationStateTransitionExpression[] = [];
|
||||||
|
if (eventStr[0] == ':') {
|
||||||
|
eventStr = _parseAnimationAlias(eventStr, errors);
|
||||||
|
}
|
||||||
var match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
|
var match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
|
||||||
if (!isPresent(match) || match.length < 4) {
|
if (!isPresent(match) || match.length < 4) {
|
||||||
errors.push(new AnimationParseError(`the provided ${eventStr} is not of a supported format`));
|
errors.push(new AnimationParseError(`the provided ${eventStr} is not of a supported format`));
|
||||||
|
|
|
@ -146,6 +146,87 @@ function declareTests({useJit}: {useJit: boolean}) {
|
||||||
expect(kf[1]).toEqual([1, {'background': 'blue'}]);
|
expect(kf[1]).toEqual([1, {'background': 'blue'}]);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
describe('animation aliases', () => {
|
||||||
|
it('should animate the ":enter" animation alias as "void => *"', fakeAsync(() => {
|
||||||
|
TestBed.overrideComponent(DummyIfCmp, {
|
||||||
|
set: {
|
||||||
|
template: `
|
||||||
|
<div *ngIf="exp" [@myAnimation]="exp"></div>
|
||||||
|
`,
|
||||||
|
animations: [trigger(
|
||||||
|
'myAnimation',
|
||||||
|
[transition(
|
||||||
|
':enter',
|
||||||
|
[style({'opacity': 0}), animate('500ms', style({opacity: 1}))])])]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const driver = TestBed.get(AnimationDriver) as MockAnimationDriver;
|
||||||
|
let fixture = TestBed.createComponent(DummyIfCmp);
|
||||||
|
var cmp = fixture.componentInstance;
|
||||||
|
cmp.exp = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(driver.log.length).toEqual(1);
|
||||||
|
|
||||||
|
var animation = driver.log[0];
|
||||||
|
expect(animation['duration']).toEqual(500);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should animate the ":leave" animation alias as "* => void"', fakeAsync(() => {
|
||||||
|
TestBed.overrideComponent(DummyIfCmp, {
|
||||||
|
set: {
|
||||||
|
template: `
|
||||||
|
<div *ngIf="exp" [@myAnimation]="exp"></div>
|
||||||
|
`,
|
||||||
|
animations: [trigger(
|
||||||
|
'myAnimation',
|
||||||
|
[transition(':leave', [animate('999ms', style({opacity: 0}))])])]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const driver = TestBed.get(AnimationDriver) as MockAnimationDriver;
|
||||||
|
let fixture = TestBed.createComponent(DummyIfCmp);
|
||||||
|
var cmp = fixture.componentInstance;
|
||||||
|
cmp.exp = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(driver.log.length).toEqual(0);
|
||||||
|
|
||||||
|
cmp.exp = false;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(driver.log.length).toEqual(1);
|
||||||
|
|
||||||
|
var animation = driver.log[0];
|
||||||
|
expect(animation['duration']).toEqual(999);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should throw an error when an unsupported alias is detected which is prefixed a colon value',
|
||||||
|
fakeAsync(() => {
|
||||||
|
TestBed.overrideComponent(DummyIfCmp, {
|
||||||
|
set: {
|
||||||
|
template: `
|
||||||
|
<div *ngIf="exp" [@myAnimation]="exp"></div>
|
||||||
|
`,
|
||||||
|
animations: [trigger(
|
||||||
|
'myAnimation',
|
||||||
|
[transition(':dont_leave_me', [animate('444ms', style({opacity: 0}))])])]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var message = '';
|
||||||
|
try {
|
||||||
|
let fixture = TestBed.createComponent(DummyIfCmp);
|
||||||
|
} catch (e) {
|
||||||
|
message = e.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(message).toMatch(
|
||||||
|
/the transition alias value ":dont_leave_me" is not supported/);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
it('should animate between * and void and back even when no expression is assigned',
|
it('should animate between * and void and back even when no expression is assigned',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
TestBed.overrideComponent(DummyIfCmp, {
|
TestBed.overrideComponent(DummyIfCmp, {
|
||||||
|
|
Loading…
Reference in New Issue