Skip to content

Commit 26f73f9

Browse files
committed
API change based on review
1 parent 78c9eb5 commit 26f73f9

File tree

9 files changed

+106
-122
lines changed

9 files changed

+106
-122
lines changed

src/cdk/stepper/stepper.ts

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ import {
1717
// This import is only used to define a generic type. The current TypeScript version incorrectly
1818
// considers such imports as unused (https://github.com/Microsoft/TypeScript/issues/14953)
1919
// tslint:disable-next-line:no-unused-variable
20-
ElementRef, Component, ContentChild, ViewChild, TemplateRef
20+
ElementRef,
21+
Component,
22+
ContentChild,
23+
ViewChild,
24+
TemplateRef
2125
} from '@angular/core';
2226
import {LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE} from '../keyboard/keycodes';
23-
import {coerceNumberProperty} from '../coercion/number-property';
2427
import {CdkStepLabel} from './step-label';
2528

2629
/** Used to generate unique ID for each stepper component. */
@@ -60,12 +63,12 @@ export class CdkStep {
6063

6164
/** Selects this step component. */
6265
select(): void {
63-
this._stepper.select(this);
66+
this._stepper.selected = this;
6467
}
6568
}
6669

6770
@Directive({
68-
selector: 'cdkStepper',
71+
selector: 'cdk-stepper',
6972
host: {
7073
'(focus)': '_setStepfocused()',
7174
'(keydown)': '_onKeydown($event)',
@@ -78,13 +81,22 @@ export class CdkStepper {
7881
/** The list of step headers of the steps in the stepper. */
7982
@ViewChildren('stepHeader') _stepHeader: QueryList<ElementRef>;
8083

81-
/** The index of the currently selected step. */
82-
@Input()
84+
/** The index of the selected step. */
8385
get selectedIndex() { return this._selectedIndex; }
84-
set selectedIndex(value: any) {
85-
this._selectedIndex = coerceNumberProperty(value);
86+
set selectedIndex(index: number) {
87+
if (this._selectedIndex == index) { return; }
88+
this._emitStepperSelectionEvent(index);
89+
this._setStepFocused(this._selectedIndex);
90+
}
91+
private _selectedIndex: number = 0;
92+
93+
/** Returns the step that is selected. */
94+
get selected() { return this._steps[this.selectedIndex]; }
95+
/** Sets selectedIndex as the index of the provided step. */
96+
set selected(step: CdkStep) {
97+
let index = this._steps.toArray().indexOf(step);
98+
this.selectedIndex = index;
8699
}
87-
private _selectedIndex: number;
88100

89101
/** Event emitted when the selected step has changed. */
90102
@Output() selectionChange = new EventEmitter<CdkStepperSelectionEvent>();
@@ -99,29 +111,16 @@ export class CdkStepper {
99111
this._groupId = nextId++;
100112
}
101113

102-
/** Selects and focuses the provided step. */
103-
select(step: CdkStep | number): void {
104-
if (typeof step == 'number') {
105-
this._emitStepperSelectionEvent(step, this._selectedIndex);
106-
} else {
107-
let stepsArray = this._steps.toArray();
108-
this._emitStepperSelectionEvent(stepsArray.indexOf(step), this._selectedIndex);
109-
}
110-
this._setStepFocused(this._selectedIndex);
111-
}
112-
113114
/** Selects and focuses the next step in list. */
114115
next(): void {
115116
if (this._selectedIndex == this._steps.length - 1) { return; }
116-
this._emitStepperSelectionEvent(this._selectedIndex + 1, this._selectedIndex);
117-
this._setStepFocused(this._selectedIndex);
117+
this.selectedIndex++;
118118
}
119119

120120
/** Selects and focuses the previous step in list. */
121121
previous(): void {
122122
if (this._selectedIndex == 0) { return; }
123-
this._emitStepperSelectionEvent(this._selectedIndex - 1, this._selectedIndex);
124-
this._setStepFocused(this._selectedIndex);
123+
this.selectedIndex--;
125124
}
126125

127126
/** Returns a unique id for each step label element. */
@@ -134,38 +133,31 @@ export class CdkStepper {
134133
return `mat-step-content-${this._groupId}-${i}`;
135134
}
136135

137-
private _emitStepperSelectionEvent(newIndex: number,
138-
oldIndex: number): void {
139-
this._selectedIndex = newIndex;
136+
private _emitStepperSelectionEvent(newIndex: number): void {
140137
const event = new CdkStepperSelectionEvent();
138+
event.oldIndex = this._selectedIndex;
141139
event.newIndex = newIndex;
142-
event.oldIndex = oldIndex;
143-
event.oldStep = this._steps.toArray()[oldIndex];
144-
event.newStep = this._steps.toArray()[this._selectedIndex];
140+
let stepsArray = this._steps.toArray();
141+
event.oldStep = stepsArray[this._selectedIndex];
142+
event.newStep = stepsArray[newIndex];
143+
this._selectedIndex = newIndex;
145144
this.selectionChange.emit(event);
146145
}
147146

148147
_onKeydown(event: KeyboardEvent) {
149148
switch (event.keyCode) {
150149
case RIGHT_ARROW:
151-
if (this._focusIndex != this._steps.length - 1) {
152-
this._setStepFocused(this._focusIndex + 1);
153-
} else {
154-
this._setStepFocused(0);
155-
}
150+
this._setStepFocused((this._focusIndex + 1) % this._steps.length);
156151
break;
157152
case LEFT_ARROW:
158-
if (this._focusIndex != 0) {
159-
this._setStepFocused(this._focusIndex - 1);
160-
} else {
161-
this._setStepFocused(this._steps.length - 1);
162-
}
153+
this._setStepFocused((this._focusIndex + this._steps.length - 1) % this._steps.length);
163154
break;
164155
case SPACE:
165156
case ENTER:
166-
this._emitStepperSelectionEvent(this._focusIndex, this._selectedIndex);
157+
this._emitStepperSelectionEvent(this._focusIndex);
167158
break;
168159
default:
160+
// Return to avoid calling preventDefault on keys that are not explicitly handled.
169161
return;
170162
}
171163
event.preventDefault();

src/demo-app/stepper/stepper-demo.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<h2>Horizontal Stepper Demo</h2>
2-
<mat-horizontal-stepper [(selectedIndex)]="horizontalActiveIndex">
2+
<mat-horizontal-stepper>
33
<mat-step *ngFor="let step of steps" [label]="step.label">
44
<md-input-container>
55
<input mdInput placeholder="Answer" [(ngModel)]="step.content">
@@ -8,7 +8,7 @@ <h2>Horizontal Stepper Demo</h2>
88
</mat-horizontal-stepper>
99

1010
<h2>Horizontal Stepper Demo with Templated Label</h2>
11-
<mat-horizontal-stepper [(selectedIndex)]="labelTemplateIndex">
11+
<mat-horizontal-stepper>
1212
<mat-step *ngFor="let step of steps">
1313
<ng-template mat-step-label>{{step.label}}</ng-template>
1414
<md-input-container>
@@ -18,7 +18,7 @@ <h2>Horizontal Stepper Demo with Templated Label</h2>
1818
</mat-horizontal-stepper>
1919

2020
<h2>Vertical Stepper Demo</h2>
21-
<mat-vertical-stepper [(selectedIndex)]="verticalActiveIndex">
21+
<mat-vertical-stepper>
2222
<mat-step *ngFor="let step of steps" [label]="step.label">
2323
<md-input-container>
2424
<input mdInput placeholder="Answer" [(ngModel)]="step.content">

src/demo-app/stepper/stepper-demo.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import {Component} from '@angular/core';
77
styleUrls: ['stepper-demo.scss'],
88
})
99
export class StepperDemo {
10-
verticalActiveIndex = 0;
11-
horizontalActiveIndex = 0;
12-
labelTemplateIndex = 0;
1310
steps = [
1411
{label: 'Confirm your name', content: 'Last name, First name.'},
1512
{label: 'Confirm your contact information', content: '123-456-7890'},

src/lib/stepper/step.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Component, ContentChild, TemplateRef, ViewChild} from '@angular/core';
9+
import {Component, ContentChild} from '@angular/core';
1010
import {CdkStep} from '@angular/cdk';
1111
import {MdStepLabel} from './step-label';
1212
import {MdStepper} from './stepper';
@@ -20,9 +20,6 @@ export class MdStep extends CdkStep {
2020
/** Content for the step label given by <ng-template mat-step-label>. */
2121
@ContentChild(MdStepLabel) stepLabel: MdStepLabel;
2222

23-
/** Template inside the MdStep view that contains an <ng-content>. */
24-
@ViewChild(TemplateRef) content: TemplateRef<any>;
25-
2623
constructor(mdStepper: MdStepper) {
2724
super(mdStepper);
2825
}
Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,35 @@
1-
<div class="mat-stepper-container">
2-
<div *ngFor="let step of _steps; let i = index; let isLast = last"
3-
class="mat-step" role="tablist">
4-
<div #stepHeader class="mat-step-header" role="tab"
5-
[id]="_getStepLabelId(i)"
6-
[attr.aria-controls]="_getStepContentId(i)"
7-
[attr.aria-selected]="selectedIndex == i"
8-
[tabIndex]="_focusIndex == i ? 0 : -1"
9-
(click)="step.select()"
10-
(keydown)="_onKeydown($event)">
11-
<div [ngClass]="{'active-step' : step.active, 'inactive-step' : !step.active}">
12-
{{i + 1}}
13-
</div>
14-
15-
<div class="mat-step-label">
16-
<!-- If there is a label template, use it. -->
17-
<ng-container *ngIf="step.stepLabel"[ngTemplateOutlet]="step.stepLabel.template">
18-
</ng-container>
19-
<!-- It there is no label template, fall back to the text label. -->
20-
<div *ngIf="!step.stepLabel">{{step.label}}</div>
21-
</div>
1+
<div *ngFor="let step of _steps; let i = index; let isLast = last">
2+
<div #stepHeader class="mat-stepper-header" role="tab"
3+
[id]="_getStepLabelId(i)"
4+
[attr.aria-controls]="_getStepContentId(i)"
5+
[attr.aria-selected]="selectedIndex == i"
6+
[tabIndex]="_focusIndex == i ? 0 : -1"
7+
(click)="step.select()"
8+
(keydown)="_onKeydown($event)">
9+
<div class="mat-stepper-index">
10+
{{i + 1}}
11+
</div>
2212

23-
</ng-template>
24-
<div *ngIf="!isLast" class="connector-line"></div>
13+
<div class="mat-stepper-label">
14+
<!-- If there is a label template, use it. -->
15+
<ng-container *ngIf="step.stepLabel"[ngTemplateOutlet]="step.stepLabel.template">
16+
</ng-container>
17+
<!-- It there is no label template, fall back to the text label. -->
18+
<div *ngIf="!step.stepLabel">{{step.label}}</div>
2519
</div>
20+
21+
</ng-template>
22+
<div *ngIf="!isLast" class="connector-line"></div>
2623
</div>
27-
<div *ngFor="let step of _steps; let i = index"
28-
class="mat-stepper-horizontal" role="tabpanel"
29-
[id]="_getStepContentId(i)"
30-
[attr.aria-labelledby]="_getStepLabelId(i)"
31-
[attr.aria-expanded]="selectedIndex == i">
32-
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
33-
</div>
34-
<div>
35-
<button md-button (click)="previous()">Back</button>
36-
<button md-button (click)="next()">Next</button>
37-
</div>
24+
</div>
25+
<div *ngFor="let step of _steps; let i = index"
26+
class="mat-stepper-content" role="tabpanel"
27+
[id]="_getStepContentId(i)"
28+
[attr.aria-labelledby]="_getStepLabelId(i)"
29+
[attr.aria-expanded]="selectedIndex == i">
30+
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
31+
</div>
32+
<div>
33+
<button md-button (click)="previous()">Back</button>
34+
<button md-button (click)="next()">Next</button>
3835
</div>

src/lib/stepper/stepper-horizontal.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import {MdStepper} from './stepper';
1616
templateUrl: 'stepper-horizontal.html',
1717
styleUrls: ['stepper.scss'],
1818
inputs: ['selectedIndex'],
19+
host: {
20+
'class': 'mat-stepper-horizontal',
21+
'role': 'tablist',
22+
},
1923
providers: [{ provide: MdStepper, useExisting: forwardRef(() => MdHorizontalStepper) }]
2024
})
2125
export class MdHorizontalStepper extends MdStepper {

src/lib/stepper/stepper-vertical.html

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
1-
<div class="mat-stepper-container">
2-
<div *ngFor="let step of _steps; let i = index; let isLast = last"
3-
class="mat-step" role="tablist">
4-
<div #stepHeader class="mat-step-header" role="tab"
5-
[id]="_getStepLabelId(i)"
6-
[attr.aria-controls]="_getStepContentId(i)"
7-
[attr.aria-selected]="selectedIndex == i"
8-
[tabIndex]="_focusIndex == i ? 0 : -1"
9-
(click)="step.select()"
10-
(keydown)="_onKeydown($event)">
11-
<div [ngClass]="{'active-step' : step.active, 'inactive-step' : !step.active}">
12-
{{i + 1}}
13-
</div>
14-
15-
<div class="mat-step-label">
16-
<!-- If there is a label template, use it. -->
17-
<ng-container *ngIf="step.stepLabel"[ngTemplateOutlet]="step.stepLabel.template">
18-
</ng-container>
19-
<!-- It there is no label template, fall back to the text label. -->
20-
<div *ngIf="!step.stepLabel">{{step.label}}</div>
21-
</div>
1+
<div *ngFor="let step of _steps; let i = index; let isLast = last">
2+
<div #stepHeader class="mat-stepper-header" role="tab"
3+
[id]="_getStepLabelId(i)"
4+
[attr.aria-controls]="_getStepContentId(i)"
5+
[attr.aria-selected]="selectedIndex == i"
6+
[tabIndex]="_focusIndex == i ? 0 : -1"
7+
(click)="step.select()"
8+
(keydown)="_onKeydown($event)">
9+
<div class="mat-stepper-index">
10+
{{i + 1}}
11+
</div>
2212

13+
<div class="mat-stepper-label">
14+
<!-- If there is a label template, use it. -->
15+
<ng-container *ngIf="step.stepLabel"[ngTemplateOutlet]="step.stepLabel.template">
16+
</ng-container>
17+
<!-- It there is no label template, fall back to the text label. -->
18+
<div *ngIf="!step.stepLabel">{{step.label}}</div>
2319
</div>
24-
<div *ngIf="!isLast" class="connector-line"></div>
25-
<div *ngIf="i == selectedIndex" role="tabpanel"
26-
[id]="_getStepContentId(i)"
27-
[attr.aria-labelledby]="_getStepLabelId(i)"
28-
[attr.aria-expanded]="selectedIndex == i">
29-
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
30-
<div>
31-
<button md-button (click)="previous()">Back</button>
32-
<button md-button (click)="next()">Next</button>
33-
</div>
20+
21+
</div>
22+
<div *ngIf="!isLast" class="connector-line"></div>
23+
<div class="mat-stepper-content" role="tabpanel"
24+
[id]="_getStepContentId(i)"
25+
[attr.aria-labelledby]="_getStepLabelId(i)"
26+
[attr.aria-expanded]="selectedIndex == i">
27+
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
28+
<div>
29+
<button md-button (click)="previous()">Back</button>
30+
<button md-button (click)="next()">Next</button>
3431
</div>
3532
</div>
3633
</div>

src/lib/stepper/stepper-vertical.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import {MdStepper} from './stepper';
1616
templateUrl: 'stepper-vertical.html',
1717
styleUrls: ['stepper.scss'],
1818
inputs: ['selectedIndex'],
19+
host: {
20+
'class': 'mat-stepper-vertical',
21+
'role': 'tablist',
22+
},
1923
providers: [{ provide: MdStepper, useExisting: forwardRef(() => MdVerticalStepper) }]
2024
})
2125
export class MdVerticalStepper extends MdStepper {

src/lib/stepper/stepper.scss

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
.mat-stepper-horizontal[aria-expanded='false'] {
1+
.mat-stepper-content[aria-expanded='false'] {
22
display:none;
33
}
44

5-
.active-step, .inactive-step {
6-
display: inline-block;
7-
}
8-
9-
.mat-step-label {
5+
.mat-stepper-index, .mat-stepper-label {
106
display: inline-block;
117
}

0 commit comments

Comments
 (0)