2

I have an angular animation that will expand/collapse elements vertically. This looks & works great in Chrome & Firefox. However, for other browsers that don't support WebAnimations will use the CSSAnimation that Angular generates, and the overflow-y property doesn't translate there and it looks bad.

So, as a workaround I made an alternate animation for these browsers by switching out the animation depending on support for WebAnimations.

Everything looked & worked great... until we went to build this in the prod environment with AOT compilation turned on, and AOT will compile away calls to window.* since it normally requires this to be @Inject()ed.

I can't @Inject inside an animation, so what do I do?

Here's my dual-animation that works fine with the JIT compiler

const animForWebAnimations: AnimationMetadata[] = [
    state('*', style({
        height: '*',
    })),
    state('void', style({
        height: '0',
        'overflow-y': 'hidden',
    })),
    //Same transition duration/easing when entering or leaving
    transition('* => *', animate(`300ms`))
];

const animForCssAnimations: AnimationMetadata[] = [
    state('*', style({
        height: '*',
        'transform-origin': 'center 0',
        transform: 'scaleY(1)'
    })),
    state('void', style({
        height: '0px',
        'transform-origin': 'center 0',
        transform: 'scaleY(0)'
    })),
    transition('* => *', animate(`300ms`))
];

const expandCollapseAnimationMetadata = 'animate' in document.documentElement ? animForWebAnimations : animForCssAnimations;
export const expandCollapseAnimation = trigger('expandCollapse', expandCollapseAnimationMetadata);

I'm my app.module I have a factory that will provide the value (since useValue produced errors in AOT compilation), like this:

export function getWindowFactory(): Window {
    return window;
}

...

@NgModule({
    declarations: [ AppComponent ],
    imports: [ ... ],
    providers: [
        {provide: 'Window', useFactory: getWindowFactory},
        ...
    ],
    bootstrap: [ AppComponent ]
})
export class AppModule { }

i tried importing the getWindowFactory function into my animation, but that produced this error:

ERROR in src\app\components\my.component.ts(16,18): Error during template compile of 'MyComponent'

Function calls are not supported in decorators but 'getWindowFactory' was called in 'expandCollapseAnimation'

'expandCollapseAnimation' calls 'getWindowFactory' at src\app\animations\expand-collapse.animation.ts(38,13).

Right now it seems like there's no way to have a conditional animation, unless I'm missing something here. is this possible?

Community
  • 1
  • 1
Chris Barr
  • 29,851
  • 23
  • 95
  • 135

0 Answers0