@@ -95,6 +95,7 @@ export const MAT_EXPANSION_PANEL_DEFAULT_OPTIONS =
9595 '[class.mat-expanded]' : 'expanded' ,
9696 '[class._mat-animation-noopable]' : '_animationMode === "NoopAnimations"' ,
9797 '[class.mat-expansion-panel-spacing]' : '_hasSpacing()' ,
98+ '[@.disabled]' : '_animationsDisabled' ,
9899 } ,
99100} )
100101export class MatExpansionPanel
@@ -150,6 +151,12 @@ export class MatExpansionPanel
150151 /** Stream of body animation done events. */
151152 readonly _bodyAnimationDone = new Subject < AnimationEvent > ( ) ;
152153
154+ /** Whether Angular animations in the panel body should be disabled. */
155+ _animationsDisabled = false ;
156+
157+ /** Whether panel body should be hidden. */
158+ _panelHidden = false ;
159+
153160 constructor (
154161 @Optional ( ) @SkipSelf ( ) @Inject ( MAT_ACCORDION ) accordion : MatAccordionBase ,
155162 _changeDetectorRef : ChangeDetectorRef ,
@@ -218,6 +225,9 @@ export class MatExpansionPanel
218225
219226 ngAfterContentInit ( ) {
220227 if ( this . _lazyContent && this . _lazyContent . _expansionPanel === this ) {
228+ this . _panelHidden = ! this . expanded ;
229+ this . _animationsDisabled = ! this . expanded ;
230+
221231 // Render the content as soon as the panel becomes open.
222232 this . opened
223233 . pipe (
@@ -227,6 +237,7 @@ export class MatExpansionPanel
227237 )
228238 . subscribe ( ( ) => {
229239 this . _portal = new TemplatePortal ( this . _lazyContent . _template , this . _viewContainerRef ) ;
240+ this . _hidePanel ( ) ;
230241 } ) ;
231242 }
232243 }
@@ -251,6 +262,31 @@ export class MatExpansionPanel
251262
252263 return false ;
253264 }
265+
266+ _animationStarted ( ) {
267+ // Currently the `bodyExpansion` animation has a `void => collapsed` transition which is
268+ // there to work around a bug in Angular (see #13088), however this introduces a different
269+ // issue. The new transition will cause to flicker in certain situations (see #22715), if the
270+ // consumer has set a inner lazy-loaded expansion panel's header height that is different from the
271+ // default one.
272+ // Part of work around is to disable animations on the body and re-enabling them after the first animation has run.
273+ // Ideally this wouldn't be necessary if we remove the `void => collapsed` transition, but we have
274+ // to wait for https://github.com/angular/angular/issues/18847 to be resolved.
275+ this . _animationsDisabled = false ;
276+ }
277+
278+ private _hidePanel ( ) : void {
279+ // Currently the `bodyExpansion` animation has a `void => collapsed` transition which is
280+ // there to work around a bug in Angular (see #13088), however this introduces a different
281+ // issue. The new transition will cause to flicker in certain situations (see #22715), if the
282+ // consumer has set a inner lazy-loaded expansion panel's header height that is different from the
283+ // default one.
284+ // Part of work around is to set non-expanded panel's height to 0px with class on init
285+ // so that outer expansion panel can calculate height of its body properly.
286+ // Ideally this wouldn't be necessary if we remove the `void => collapsed` transition, but we have
287+ // to wait for https://github.com/angular/angular/issues/18847 to be resolved.
288+ this . _panelHidden = false ;
289+ }
254290}
255291
256292/**
0 commit comments