Skip to content

Commit 836c0ac

Browse files
committed
Changes based on review - event properties, selectors, SPACE support, etc. + demo
1 parent 36ad2cc commit 836c0ac

File tree

10 files changed

+76
-77
lines changed

10 files changed

+76
-77
lines changed

src/cdk/stepper/step-label.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Directive, TemplateRef, ViewContainerRef} from '@angular/core';
10-
import {TemplatePortalDirective} from '../portal';
9+
import {Directive, TemplateRef} from '@angular/core';
1110

1211
@Directive({
1312
selector: '[cdk-step-label]',
1413
})
15-
export class CdkStepLabel extends TemplatePortalDirective {
16-
constructor(templateRef: TemplateRef<any>, viewContainerRef: ViewContainerRef) {
17-
super(templateRef, viewContainerRef);
18-
}
14+
export class CdkStepLabel {
15+
constructor(public template: TemplateRef<any>) { }
1916
}

src/cdk/stepper/step.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import {
1010
Component, ContentChild, Input, TemplateRef, ViewChild
1111
} from '@angular/core';
1212
import {CdkStepLabel} from './step-label';
13-
import {coerceBooleanProperty} from '../coercion/boolean-property';
1413

1514
@Component({
16-
selector: '[cdk-step]',
15+
selector: 'cdk-step',
1716
templateUrl: 'step.html',
1817
})
1918
export class CdkStep {
@@ -27,22 +26,6 @@ export class CdkStep {
2726
@Input()
2827
label: string;
2928

30-
/** Whether the step is optional or not. */
31-
@Input()
32-
get optional() { return this._optional; }
33-
set optional(value: any) {
34-
this._optional = coerceBooleanProperty(value);
35-
}
36-
private _optional: boolean = false;
37-
38-
/** Whether the step is editable or not. */
39-
@Input()
40-
get editable() { return this._editable; }
41-
set editable(value: any) {
42-
this._editable = coerceBooleanProperty(value);
43-
}
44-
private _editable: boolean = true;
45-
4629
/** Whether the step is the last one in the list. */
4730
_isLast: boolean = false;
4831
}

src/cdk/stepper/stepper.ts

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,28 @@ import {
1919
ElementRef
2020
} from '@angular/core';
2121
import {CdkStep} from './step';
22-
import {LEFT_ARROW, RIGHT_ARROW, ENTER, TAB} from '../keyboard/keycodes';
22+
import {LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE} from '../keyboard/keycodes';
2323
import {coerceNumberProperty} from '../coercion/number-property';
2424

2525
/** Used to generate unique ID for each stepper component. */
2626
let nextId = 0;
2727

2828
/** Change event emitted on selection changes. */
2929
export class CdkStepperSelectionEvent {
30-
index: number;
30+
/** The index of the step that is newly selected during this change event. */
31+
newIndex: number;
32+
33+
/** The index of the step that was previously selected. */
34+
oldIndex: number;
35+
36+
/** The step component that is selected ruing this change event. */
3137
step: CdkStep;
3238
}
3339

3440
@Directive({
35-
selector: '[cdkStepper]',
41+
selector: 'cdk-stepper',
3642
host: {
37-
'(focus)': '_setStepfocus()',
43+
'(focus)': '_setStepfocused()',
3844
'(keydown)': '_onKeydown($event)',
3945
},
4046
})
@@ -66,30 +72,31 @@ export class CdkStepper {
6672
}
6773

6874
/** Selects and focuses the provided step. */
69-
select(step: CdkStep): void {
70-
let stepsArray = this._steps.toArray();
71-
this._selectedIndex = stepsArray.indexOf(step);
72-
this.selectionChange.emit(this._createStepperSelectionEvent(this._selectedIndex));
73-
this._focusIndex = this._selectedIndex;
74-
this._setStepFocus();
75+
select(step: CdkStep | number): void {
76+
if (typeof step == 'number') {
77+
this.selectionChange.emit(this._createStepperSelectionEvent(step, this._selectedIndex));
78+
} else {
79+
let stepsArray = this._steps.toArray();
80+
this.selectionChange.emit(
81+
this._createStepperSelectionEvent(stepsArray.indexOf(step), this._selectedIndex));
82+
}
83+
this._setStepFocused(this._selectedIndex);
7584
}
7685

7786
/** Selects and focuses the next step in list. */
7887
next(): void {
7988
if (this._selectedIndex == this._steps.length - 1) { return; }
80-
this._selectedIndex++;
81-
this.selectionChange.emit(this._createStepperSelectionEvent(this._selectedIndex));
82-
this._focusIndex = this._selectedIndex;
83-
this._setStepFocus();
89+
this.selectionChange.emit(
90+
this._createStepperSelectionEvent(this._selectedIndex + 1, this._selectedIndex));
91+
this._setStepFocused(this._selectedIndex);
8492
}
8593

8694
/** Selects and focuses the previous step in list. */
8795
previous(): void {
8896
if (this._selectedIndex == 0) { return; }
89-
this._selectedIndex--;
90-
this.selectionChange.emit(this._createStepperSelectionEvent(this._selectedIndex));
91-
this._focusIndex = this._selectedIndex;
92-
this._setStepFocus();
97+
this.selectionChange.emit(
98+
this._createStepperSelectionEvent(this._selectedIndex - 1, this._selectedIndex));
99+
this._setStepFocused(this._selectedIndex);
93100
}
94101

95102
/** Returns a unique id for each step label element. */
@@ -102,9 +109,12 @@ export class CdkStepper {
102109
return `mat-step-content-${this._groupId}-${i}`;
103110
}
104111

105-
private _createStepperSelectionEvent(index: number): CdkStepperSelectionEvent {
112+
private _createStepperSelectionEvent(newIndex: number,
113+
oldIndex: number): CdkStepperSelectionEvent {
114+
this._selectedIndex = newIndex;
106115
const event = new CdkStepperSelectionEvent();
107-
event.index = index;
116+
event.newIndex = newIndex;
117+
event.oldIndex = oldIndex;
108118
event.step = this._steps.toArray()[this._selectedIndex];
109119
return event;
110120
}
@@ -113,27 +123,26 @@ export class CdkStepper {
113123
switch (event.keyCode) {
114124
case RIGHT_ARROW:
115125
if (this._focusIndex != this._steps.length - 1) {
116-
this._focusIndex++;
117-
this._setStepFocus();
126+
this._setStepFocused(this._focusIndex + 1);
118127
}
119128
break;
120129
case LEFT_ARROW:
121130
if (this._focusIndex != 0) {
122-
this._focusIndex--;
123-
this._setStepFocus();
131+
this._setStepFocused(this._focusIndex - 1);
124132
}
125133
break;
134+
case SPACE:
126135
case ENTER:
127-
this._selectedIndex = this._focusIndex;
128-
this._createStepperSelectionEvent(this._selectedIndex);
136+
this._createStepperSelectionEvent(this._focusIndex, this._selectedIndex);
129137
break;
138+
default:
139+
return;
130140
}
131-
if (event.keyCode != TAB) {
132-
event.preventDefault();
133-
}
141+
event.preventDefault();
134142
}
135143

136-
private _setStepFocus() {
144+
private _setStepFocused(index: number) {
145+
this._focusIndex = index;
137146
this._stepHeader.toArray()[this._focusIndex].nativeElement.focus();
138147
}
139148
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ export class DemoApp {
6161
{name: 'Slider', route: 'slider'},
6262
{name: 'Slide Toggle', route: 'slide-toggle'},
6363
{name: 'Snack Bar', route: 'snack-bar'},
64+
{name: 'Stepper', route: 'stepper'},
6465
{name: 'Table', route: 'table'},
6566
{name: 'Tabs', route: 'tabs'},
6667
{name: 'Toolbar', route: 'toolbar'},
6768
{name: 'Tooltip', route: 'tooltip'},
6869
{name: 'Platform', route: 'platform'},
6970
{name: 'Style', route: 'style'},
70-
{name: 'Typography', route: 'typography'},
71-
{name: 'Stepper', route: 'stepper'}
71+
{name: 'Typography', route: 'typography'}
7272
];
7373

7474
constructor(private _element: ElementRef) {
Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
11
<h2>Horizontal Stepper Demo</h2>
22
<mat-horizontal-stepper [(selectedIndex)]="horizontalActiveIndex">
3-
<mat-step *ngFor="let step of steps" [label]="step.label">
4-
<md-input-container>
5-
<input mdInput placeholder="Answer" [(ngModel)]="step.content">
6-
</md-input-container>
7-
</mat-step>
3+
<mat-step *ngFor="let step of steps" [label]="step.label">
4+
<md-input-container>
5+
<input mdInput placeholder="Answer" [(ngModel)]="step.content">
6+
</md-input-container>
7+
</mat-step>
88
</mat-horizontal-stepper>
9+
10+
<h2>Horizontal Stepper Demo with Templated Label</h2>
11+
<mat-horizontal-stepper [(selectedIndex)]="labelTemplateIndex">
12+
<mat-step *ngFor="let step of steps">
13+
<ng-template mat-step-label>{{step.label}}</ng-template>
14+
<md-input-container>
15+
<input mdInput placeholder="Answer" [(ngModel)]="step.content">
16+
</md-input-container>
17+
</mat-step>
18+
</mat-horizontal-stepper>
19+
20+
<h2>Vertical Stepper Demo</h2>
21+
<mat-vertical-stepper [(selectedIndex)]="verticalActiveIndex">
22+
<mat-step *ngFor="let step of steps" [label]="step.label">
23+
<md-input-container>
24+
<input mdInput placeholder="Answer" [(ngModel)]="step.content">
25+
</md-input-container>
26+
</mat-step>
27+
</mat-vertical-stepper>

src/lib/stepper/step-label.ts

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

9-
import {Directive, TemplateRef, ViewContainerRef} from '@angular/core';
9+
import {Directive, TemplateRef} from '@angular/core';
1010
import {CdkStepLabel} from '@angular/cdk';
1111

1212
@Directive({
1313
selector: '[md-step-label], [mat-step-label]',
1414
})
1515
export class MdStepLabel extends CdkStepLabel {
16-
constructor(templateRef: TemplateRef<any>, viewContainerRef: ViewContainerRef) {
17-
super(templateRef, viewContainerRef);
16+
constructor(public template: TemplateRef<any>) {
17+
super(template);
1818
}
1919
}

src/lib/stepper/step.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {MdStepLabel} from './step-label';
1414
moduleId: module.id,
1515
selector: 'md-step, mat-step',
1616
templateUrl: 'step.html',
17-
inputs: ['label'],
1817
})
1918
export class MdStep extends CdkStep {
2019
/** Content for the step label given by <ng-template mat-step-label>. */

src/lib/stepper/stepper-horizontal.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
<div class="mat-step-label">
1414
<!-- If there is a label template, use it. -->
1515
<ng-template [ngIf]="step.stepLabel">
16-
<ng-template [cdkPortalHost]="step.stepLabel"></ng-template>
16+
<ng-container [ngTemplateOutlet]="step.stepLabel.template"></ng-container>
1717
</ng-template>
1818
<!-- It there is no label template, fall back to the text label. -->
1919
<ng-template [ngIf]="!step.stepLabel">
2020
<div>{{step.label}}</div>
2121
</ng-template>
2222
</div>
2323

24-
</div>
24+
</ng-template>
2525
<div *ngIf="!step._isLast" class="connector-line"></div>
2626
</div>
2727
</div>

src/lib/stepper/stepper-vertical.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
[tabIndex]="_focusIndex == i ? 0 : -1"
88
(click)="select(step)"
99
(keydown)="_onKeydown($event)">
10-
<div *ngIf="step.active" class="activeStep">{{i + 1}}</div>
11-
<div *ngIf="!step.active" class="inactiveStep">{{i + 1}}</div>
10+
<div *ngIf="step.active" class="active-step">{{i + 1}}</div>
11+
<div *ngIf="!step.active" class="inactive-step">{{i + 1}}</div>
1212

1313
<div class="mat-step-label">
1414
<!-- If there is a label template, use it. -->

src/lib/stepper/stepper.scss

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
1-
.mat-step-header:focus {
2-
background: yellow;
3-
}
4-
51
.mat-stepper-horizontal[aria-expanded='false'] {
62
display:none;
73
}
84

9-
.mat-stepper-horizontal[aria-expanded='true'] {
10-
background: pink;
11-
}
12-
135
.active-step, .inactive-step {
146
display: inline-block;
157
}

0 commit comments

Comments
 (0)