0
votes

Noticed some weird behavior when using Material Stepper combined with container animations.

if you click a step, while the mat-stepper is animating, the content of the step goes invisible.

HTML:

<strong> reload - while the stepper is fading in - spam click step 2 </strong>.

<mat-horizontal-stepper [@fadeAnimation]>
    <mat-step>
        <p>STEP ONE CONTENT</p>
    </mat-step>
    <mat-step>
        <p>STEP TWO CONTENT</p>
    </mat-step>
    <mat-step>
        <p>STEP THREE CONTENT</p>
    </mat-step>
</mat-horizontal-stepper>

Animation:

function fadeAnimation() {
  return trigger('fadeAnimation', [
    state('void', style({})),
    state('*', style({})),
    transition(':enter', [
      style({ opacity: 0 }),
      animate('1s ease-in-out', style({ opacity: 1 }))
    ]),
    transition(':leave', [
      style({ opacity: 1 }),
      animate('1s ease-in-out', style({ opacity: 0 }))
    ])
  ]);
}

Stackblitz Example

is there a possible workaround for this ? (other than [@.disabled] of course, the animation is still wanted.)

1
For which browser you are getting issue ? Chrome I am able to see content on all 3 steps. - webmatrix
chrome. reload the demo and WHILE it fades in, spam click step 2. you will see it vanishes. I increased animation time to 2s, should make it more obvious. - Stavm
Some issue with visibility:visible. If you look at computed styles tab in chrome . It will show you visibility:hidden, Though it should compute it as visibility:visible after completion of animation. - webmatrix
Use visibility style also with opacity - Awais

1 Answers

3
votes

I made it work. At least for me. Please try if it fits your needs. See Stackblitz.

Basically I gave the fadeAnimation a trigger with the specific states: visible and hidden.

The default value is hidden. Then the trigger is set to visible only when the stepTransition from mat-stepper is done. There is a (animationDone) event we can listen on.

This was the only way how I could sequence these two animations, which before clearly messed up the visibility state. For me it only worked if the fadingAnimation was triggered after the stepTransition animation from Angular Material. I tried to use query and stagger but it did not work quite correct.

@Component({
  selector: 'stepper-overview-example',
  templateUrl: 'stepper-overview-example.html',
  styleUrls: ['stepper-overview-example.css'],
  animations: [fadeAnimation()]
})
export class StepperOverviewExample implements OnInit {

  constructor() {}

  fadeTrigger = 'hidden';

  ngOnInit() {

  }

  stepperDone() {
    console.log('stepper is done now');
    this.fadeTrigger = 'visible';
  }
}

function fadeAnimation() {
  return trigger('fadeAnimation', [
    state('hidden', style({ opacity: 0 })),
    state('visible', style({ opacity: 1 })),

    transition('* => visible', [
      animate('2s ease-in-out'),
    ]),
    transition('visible => *', [
      animate('1s ease-in-out')
    ])
  ]);
}

HTML

<mat-horizontal-stepper [@fadeAnimation]="fadeTrigger" (animationDone)="stepperDone()">
    <mat-step>
        <p>STEP ONE CONTENT</p>
    </mat-step>
    <mat-step>
        <p>STEP TWO CONTENT</p>
    </mat-step>
    <mat-step>
        <p>STEP THREE CONTENT</p>
    </mat-step>
</mat-horizontal-stepper>

Link to source ofMatStepper animation.

Link to source of Stepper.