Skip to content

Commit

Permalink
feat(stepper): Add animation to stepper (angular#6361)
Browse files Browse the repository at this point in the history
* Add animation

* Implement Angular animation

* Clean up unnecessary code

* Generalize animation so that vertical and horizontal steppers can use the same function
  • Loading branch information
jwshinjwshin committed Aug 22, 2017
1 parent 5b2522b commit eaad08a
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 28 deletions.
24 changes: 21 additions & 3 deletions src/cdk/stepper/stepper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ import {AbstractControl} from '@angular/forms';
/** Used to generate unique ID for each stepper component. */
let nextId = 0;

/**
* Position state of the content of each step in stepper that is used for transitioning
* the content into correct position upon step selection change.
*/
export type StepContentPositionState = 'previous' | 'current' | 'next';

/** Change event emitted on selection changes. */
export class CdkStepperSelectionEvent {
export class StepperSelectionEvent {
/** Index of the step now selected. */
selectedIndex: number;

Expand Down Expand Up @@ -119,7 +125,7 @@ export class CdkStepper {
}

/** Event emitted when the selected step has changed. */
@Output() selectionChange = new EventEmitter<CdkStepperSelectionEvent>();
@Output() selectionChange = new EventEmitter<StepperSelectionEvent>();

/** The index of the step that the focus can be set. */
_focusIndex: number = 0;
Expand All @@ -146,11 +152,23 @@ export class CdkStepper {
return `mat-step-label-${this._groupId}-${i}`;
}

/** Returns nique id for each step content element. */
/** Returns unique id for each step content element. */
_getStepContentId(i: number): string {
return `mat-step-content-${this._groupId}-${i}`;
}

/** Returns position state of the step with the given index. */
_getAnimationDirection(index: number): StepContentPositionState {
const position = index - this._selectedIndex;
if (position < 0) {
return 'previous';
} else if (position > 0) {
return 'next';
} else {
return 'current';
}
}

private _emitStepperSelectionEvent(newIndex: number): void {
const stepsArray = this._steps.toArray();
this.selectionChange.emit({
Expand Down
4 changes: 2 additions & 2 deletions src/lib/stepper/_stepper-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
background-color: mat-color($background, card);
}

.vertical-content-container {
.mat-vertical-content-container {
border-left-color: mat-color($foreground, divider);
}

.connector-line {
.mat-connector-line {
border-top-color: mat-color($foreground, divider);
}
}
18 changes: 10 additions & 8 deletions src/lib/stepper/stepper-horizontal.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@
</div>
</div>

<div *ngIf="!isLast" class="connector-line"></div>
<div *ngIf="!isLast" class="mat-connector-line"></div>
</ng-container>
</div>

<div *ngFor="let step of _steps; let i = index"
class="mat-horizontal-stepper-content" role="tabpanel"
[id]="_getStepContentId(i)"
[attr.aria-labelledby]="_getStepLabelId(i)"
[attr.aria-expanded]="selectedIndex == i">
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
<div class="mat-horizontal-content-container">
<div *ngFor="let step of _steps; let i = index"
class="mat-horizontal-stepper-content" role="tabpanel"
[@stepTransition]="_getAnimationDirection(i)"
[id]="_getStepContentId(i)"
[attr.aria-labelledby]="_getStepLabelId(i)"
[attr.aria-expanded]="selectedIndex == i">
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
</div>
</div>
10 changes: 10 additions & 0 deletions src/lib/stepper/stepper-horizontal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import {Component} from '@angular/core';
import {MdStepper} from './stepper';
import {animate, state, style, transition, trigger} from '@angular/animations';

@Component({
moduleId: module.id,
Expand All @@ -19,6 +20,15 @@ import {MdStepper} from './stepper';
'class': 'mat-stepper-horizontal',
'role': 'tablist',
},
animations: [
trigger('stepTransition', [
state('previous', style({transform: 'translate3d(-100%, 0, 0)', visibility: 'hidden'})),
state('current', style({transform: 'translate3d(0%, 0, 0)', visibility: 'visible'})),
state('next', style({transform: 'translate3d(100%, 0, 0)', visibility: 'hidden'})),
transition('* => *',
animate('500ms cubic-bezier(0.35, 0, 0.25, 1)'))
])
],
providers: [{provide: MdStepper, useExisting: MdHorizontalStepper}]
})
export class MdHorizontalStepper extends MdStepper { }
7 changes: 5 additions & 2 deletions src/lib/stepper/stepper-vertical.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
</div>

</div>
<div class="vertical-content-container">
<div class="mat-vertical-content-container">
<div class="mat-vertical-stepper-content" role="tabpanel"
[@stepTransition]="_getAnimationDirection(i)"
[id]="_getStepContentId(i)"
[attr.aria-labelledby]="_getStepLabelId(i)"
[attr.aria-expanded]="selectedIndex == i">
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
<div class="mat-vertical-content">
<ng-container[ngTemplateOutlet]="step.content"></ng-container>
</div>
</div>
</div>
</div>
9 changes: 9 additions & 0 deletions src/lib/stepper/stepper-vertical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import {Component} from '@angular/core';
import {MdStepper} from './stepper';
import {animate, state, style, transition, trigger} from '@angular/animations';

@Component({
moduleId: module.id,
Expand All @@ -19,6 +20,14 @@ import {MdStepper} from './stepper';
'class': 'mat-stepper-vertical',
'role': 'tablist',
},
animations: [
trigger('stepTransition', [
state('previous', style({height: '0px', visibility: 'hidden'})),
state('next', style({height: '0px', visibility: 'hidden'})),
state('current', style({height: '*', visibility: 'visible'})),
transition('* <=> current', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)'))
])
],
providers: [{provide: MdStepper, useExisting: MdVerticalStepper}]
})
export class MdVerticalStepper extends MdStepper { }
35 changes: 22 additions & 13 deletions src/lib/stepper/stepper.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
@import '../core/style/variables';

$mat-horizontal-stepper-header-height: 72px !default;
$mat-label-header-height: 24px !default;
$mat-stepper-label-min-width: 50px !default;
$mat-stepper-side-gap: 24px !default;
$mat-vertical-stepper-content-margin: 12px !default;
$mat-vertical-stepper-content-padding: 16px 0 32px $mat-stepper-side-gap !default;
$mat-vertical-content-padding-bottom: 32px !default;
$mat-vertical-content-container-padding: 8px !default;
$mat-connector-line-width: 1px !default;
$mat-connector-line-gap: 8px !default;
Expand Down Expand Up @@ -43,6 +45,7 @@ $mat-vertical-stepper-margin-top: $mat-stepper-side-gap - $mat-connector-line-ga
line-height: $mat-horizontal-stepper-header-height;
overflow: hidden;
align-items: center;
outline: none;

.mat-stepper-index {
margin-right: $mat-connector-line-gap;
Expand All @@ -55,13 +58,14 @@ $mat-vertical-stepper-margin-top: $mat-stepper-side-gap - $mat-connector-line-ga
display: flex;
align-items: center;
margin: $mat-connector-line-gap 0;
outline: none;

.mat-stepper-index {
margin-right: $mat-vertical-stepper-content-margin;
}
}

.connector-line {
.mat-connector-line {
border-top-width: $mat-connector-line-width;
border-top-style: solid;
width: $mat-horizontal-connector-line-size;
Expand All @@ -70,11 +74,19 @@ $mat-vertical-stepper-margin-top: $mat-stepper-side-gap - $mat-connector-line-ga
height: 0;
}

.mat-horizontal-stepper-content[aria-expanded='false'] {
display: none;
.mat-horizontal-stepper-content {
overflow: hidden;

&[aria-expanded='false'] {
height: 0;
}
}

.mat-horizontal-content-container {
overflow: hidden;
}

.vertical-content-container {
.mat-vertical-content-container {
border-left-width: $mat-connector-line-width;
border-left-style: solid;
margin-left: $mat-vertical-stepper-content-margin;
Expand All @@ -83,21 +95,18 @@ $mat-vertical-stepper-margin-top: $mat-stepper-side-gap - $mat-connector-line-ga

.mat-vertical-stepper-content {
padding-left: $mat-stepper-side-gap;
overflow: hidden;
}

&[aria-expanded='false'] {
display: none;
}

&[aria-expanded='true'] {
padding: $mat-vertical-stepper-content-padding;
}
.mat-vertical-content {
padding-bottom: $mat-vertical-content-padding-bottom;
}

.mat-step {
margin-top: $mat-connector-line-gap;

&:last-child {
.vertical-content-container {
.mat-vertical-content-container {
border: none;
}
}
Expand Down

0 comments on commit eaad08a

Please sign in to comment.