Skip to content

Commit 6a0653e

Browse files
committed
Refactor md-step-header and md-step-content + optional step change
1 parent b214f70 commit 6a0653e

26 files changed

+497
-366
lines changed

src/cdk/stepper/public_api.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ import {CdkStepper, CdkStep} from './stepper';
1111
import {CommonModule} from '@angular/common';
1212
import {CdkStepLabel} from './step-label';
1313
import {CdkStepperNext, CdkStepperPrevious} from './stepper-button';
14-
import {CdkStepIcon} from './step-icon';
15-
import {CdkStepLabelContainer} from './step-label-container';
14+
import {CdkStepHeader} from './step-header';
15+
import {CdkStepContent} from './step-content';
1616

1717
@NgModule({
1818
imports: [CommonModule],
19-
exports: [CdkStep, CdkStepper, CdkStepLabel, CdkStepperNext, CdkStepperPrevious, CdkStepIcon,
20-
CdkStepLabelContainer],
21-
declarations: [CdkStep, CdkStepper, CdkStepLabel, CdkStepperNext, CdkStepperPrevious, CdkStepIcon,
22-
CdkStepLabelContainer]
19+
exports: [CdkStep, CdkStepper, CdkStepLabel, CdkStepperNext, CdkStepperPrevious, CdkStepHeader,
20+
CdkStepContent],
21+
declarations: [CdkStep, CdkStepper, CdkStepLabel, CdkStepperNext, CdkStepperPrevious,
22+
CdkStepHeader, CdkStepContent]
2323
})
2424
export class CdkStepperModule {}
2525

2626
export * from './stepper';
2727
export * from './step-label';
2828
export * from './stepper-button';
29-
export * from './step-icon';
30-
export * from './step-label-container';
29+
export * from './step-header';
30+
export * from './step-content';

src/cdk/stepper/step-content.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Directive, Input} from '@angular/core';
10+
import {CdkStep, CdkStepper} from './stepper';
11+
import {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion';
12+
13+
@Directive({
14+
selector: 'cdkStepContent',
15+
host: {
16+
'role': 'tabpanel',
17+
'[attr.id]': 'contentId',
18+
'[attr.aria-labelledby]': 'labelId',
19+
'[attr.aria-expanded]': 'selectedIndex == index',
20+
}
21+
})
22+
export class CdkStepContent {
23+
/** Whether the orientation of stepper is horizontal. */
24+
@Input()
25+
get horizontal() { return this._horizontal; }
26+
set horizontal(value: any) {
27+
this._horizontal = coerceBooleanProperty(value);
28+
}
29+
private _horizontal: boolean;
30+
31+
/** Unique label ID of step header. */
32+
@Input()
33+
labelId: string;
34+
35+
/** Unique content ID of step content. */
36+
@Input()
37+
contentId: string;
38+
39+
/** Index of the given step. */
40+
@Input()
41+
get index() { return this._index; }
42+
set index(value: any) {
43+
this._index = coerceNumberProperty(value);
44+
}
45+
private _index: number;
46+
47+
/** Index of selected step in stepper. */
48+
@Input()
49+
get selectedIndex() { return this._selectedIndex; }
50+
set selectedIndex(value: any) {
51+
this._selectedIndex = coerceNumberProperty(value);
52+
}
53+
private _selectedIndex: number;
54+
55+
/** Returns the step at the index position in stepper. */
56+
get step(): CdkStep {
57+
return this._stepper._steps.toArray()[this._index];
58+
}
59+
60+
constructor(private _stepper: CdkStepper) { }
61+
}

src/cdk/stepper/step-header.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Directive, ElementRef, Input} from '@angular/core';
10+
import {CdkStep, CdkStepper} from './stepper';
11+
import {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion';
12+
13+
@Directive({
14+
selector: 'cdkStepHeader',
15+
host: {
16+
'role': 'tab',
17+
'[attr.id]': 'labelId',
18+
'[attr.aria-controls]': 'contentId',
19+
'[attr.aria-selected]': 'selected',
20+
// '[attr.tabindex]': 'tabIndex'
21+
}
22+
})
23+
export class CdkStepHeader {
24+
/** Whether the orientation of stepper is horizontal. */
25+
@Input()
26+
get horizontal() { return this._horizontal; }
27+
set horizontal(value: any) {
28+
this._horizontal = coerceBooleanProperty(value);
29+
}
30+
private _horizontal: boolean;
31+
32+
/** Unique label ID of step header. */
33+
@Input()
34+
labelId: string;
35+
36+
/** Unique content ID of step content. */
37+
@Input()
38+
contentId: string;
39+
40+
/** Index of the given step. */
41+
@Input()
42+
get index() { return this._index; }
43+
set index(value: any) {
44+
this._index = coerceNumberProperty(value);
45+
}
46+
private _index: number;
47+
48+
/** Whether the given step is selected. */
49+
@Input()
50+
get selected() { return this._selected; }
51+
set selected(value: any) {
52+
this._selected = coerceBooleanProperty(value);
53+
}
54+
private _selected: boolean;
55+
56+
// /** Tab index of the header of the given step. */
57+
// @Input()
58+
// get tabIndex() { return this._tabIndex; }
59+
// set tabIndex(value: any) {
60+
// this._tabIndex = coerceNumberProperty(value);
61+
// }
62+
// private _tabIndex: number;
63+
64+
/** Returns the step at the index position in stepper. */
65+
get step(): CdkStep {
66+
return this._stepper._steps.toArray()[this._index];
67+
}
68+
69+
constructor(private _stepper: CdkStepper, private _elementRef: ElementRef) { }
70+
71+
/** Returns the type of icon to be displayed. */
72+
_getIndicatorType(): 'number' | 'edit' | 'done' {
73+
if (!this.step.completed || this.selected) {
74+
return 'number';
75+
} else {
76+
return this.step.editable ? 'edit' : 'done';
77+
}
78+
}
79+
80+
/** Blurs the step header. */
81+
_blur() {
82+
this._elementRef.nativeElement.blur();
83+
}
84+
85+
/** Focuses the step header. */
86+
_focus() {
87+
this._elementRef.nativeElement.focus();
88+
}
89+
}

src/cdk/stepper/step-icon.ts

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/cdk/stepper/step-label-container.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/cdk/stepper/stepper.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
import {
1010
ContentChildren,
11+
// This import is only used to define a generic type. The current TypeScript version incorrectly
12+
// considers such imports as unused (https://github.com/Microsoft/TypeScript/issues/14953)
13+
// tslint:disable-next-line:no-unused-variable
14+
ElementRef,
1115
EventEmitter,
1216
Input,
1317
Output,
1418
QueryList,
1519
Directive,
16-
// This import is only used to define a generic type. The current TypeScript version incorrectly
17-
// considers such imports as unused (https://github.com/Microsoft/TypeScript/issues/14953)
18-
// tslint:disable-next-line:no-unused-variable
19-
ElementRef,
2020
Component,
2121
ContentChild,
2222
ViewChild,
@@ -164,7 +164,7 @@ export class CdkStepper {
164164
_focusIndex: number = 0;
165165

166166
/** Used to track unique ID for each stepper component. */
167-
private _groupId: number;
167+
_groupId: number;
168168

169169
constructor() {
170170
this._groupId = nextId++;
@@ -241,7 +241,7 @@ export class CdkStepper {
241241
const stepsArray = this._steps.toArray();
242242
stepsArray[this._selectedIndex].interacted = true;
243243
if (this._linear) {
244-
return stepsArray.slice(0, index).some(step => step.stepControl.invalid && !step.optional);
244+
return stepsArray.slice(0, index).some(step => step.stepControl.invalid);
245245
}
246246
return false;
247247
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ <h3>Linear Vertical Stepper Demo using a single form</h3>
2121

2222
<md-step formGroupName="1" [stepControl]="formArray.get([1])" optional>
2323
<ng-template mdStepLabel>
24-
<div>Fill out your phone number</div>
24+
<div>Fill out your email address</div>
2525
</ng-template>
2626
<md-input-container>
27-
<input mdInput placeholder="Phone number" formControlName="phoneFormCtrl" required>
28-
<md-error>This field is required</md-error>
27+
<input mdInput placeholder="Email address" formControlName="emailFormCtrl">
28+
<md-error>The input is invalid.</md-error>
2929
</md-input-container>
3030
<div>
3131
<button md-button mdStepperPrevious type="button">Back</button>
@@ -62,12 +62,12 @@ <h3>Linear Horizontal Stepper Demo using a different form for each step</h3>
6262
</form>
6363
</md-step>
6464

65-
<md-step [stepControl]="phoneFormGroup" optional>
66-
<form [formGroup]="phoneFormGroup">
65+
<md-step [stepControl]="emailFormGroup" optional>
66+
<form [formGroup]="emailFormGroup">
6767
<ng-template mdStepLabel>Fill out your phone number</ng-template>
6868
<md-form-field>
69-
<input mdInput placeholder="Phone number" formControlName="phoneCtrl" required>
70-
<md-error>This field is required</md-error>
69+
<input mdInput placeholder="Email address" formControlName="emailCtrl">
70+
<md-error>The input is invalid</md-error>
7171
</md-form-field>
7272
<div>
7373
<button md-button mdStepperPrevious>Back</button>

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {Component} from '@angular/core';
22
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
33

4+
const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
5+
46
@Component({
57
moduleId: module.id,
68
selector: 'stepper-demo',
@@ -13,7 +15,7 @@ export class StepperDemo {
1315
isNonEditable = false;
1416

1517
nameFormGroup: FormGroup;
16-
phoneFormGroup: FormGroup;
18+
emailFormGroup: FormGroup;
1719

1820
steps = [
1921
{label: 'Confirm your name', content: 'Last name, First name.'},
@@ -35,8 +37,8 @@ export class StepperDemo {
3537
lastNameFormCtrl: ['', Validators.required],
3638
}),
3739
this._formBuilder.group({
38-
phoneFormCtrl: ['', Validators.required],
39-
})
40+
emailFormCtrl: ['', Validators.pattern(EMAIL_REGEX)]
41+
}),
4042
])
4143
});
4244

@@ -45,8 +47,8 @@ export class StepperDemo {
4547
lastNameCtrl: ['', Validators.required],
4648
});
4749

48-
this.phoneFormGroup = this._formBuilder.group({
49-
phoneCtrl: ['', Validators.required]
50+
this.emailFormGroup = this._formBuilder.group({
51+
emailCtrl: ['', Validators.pattern(EMAIL_REGEX)]
5052
});
5153
}
5254
}

0 commit comments

Comments
 (0)