forked from angular/components
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stepper): Merge initial prototype of stepper into the upstream s…
…tepper branch. (angular#5742) * Prototyping * Further work * Further prototyping * Further prototyping * Further work * Adding event emitters * Adding "selectedIndex" attribute to stepper and working on TemplateOulet. * Prototyping * Further work * Further prototyping * Further prototyping * Further work * Adding event emitters * Template rendering and selectIndex control done. * Work in progress for accessibility * Added functionalities based on the tentative API doc. * Refactor code for cdk-stepper and cdk-step * Add support for templated label * Added support for keyboard events and focus changes for accessibility. * Updated vertical stepper + added comments * Fix package-lock.json * Fix indention * Changes made based on the review * Changes based on review - event properties, selectors, SPACE support, etc. + demo * Add select() for step component + refactor to avoid circular dependency + support cycling using arrow keys * API change based on review * Minor code clean up based on review. * Several name changes, etc based on review * Add to compatibility mode list and refactor to avoid circular dependency
- Loading branch information
1 parent
7f0e58e
commit a9d56a8
Showing
21 changed files
with
486 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {NgModule} from '@angular/core'; | ||
import {CdkStepper, CdkStep} from './stepper'; | ||
import {CommonModule} from '@angular/common'; | ||
import {CdkStepLabel} from './step-label'; | ||
|
||
@NgModule({ | ||
imports: [CommonModule], | ||
exports: [CdkStep, CdkStepper, CdkStepLabel], | ||
declarations: [CdkStep, CdkStepper, CdkStepLabel] | ||
}) | ||
export class CdkStepperModule {} | ||
|
||
export * from './stepper'; | ||
export * from './step-label'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {Directive, TemplateRef} from '@angular/core'; | ||
|
||
@Directive({ | ||
selector: '[cdkStepLabel]', | ||
}) | ||
export class CdkStepLabel { | ||
constructor(public template: TemplateRef<any>) { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<ng-template><ng-content></ng-content></ng-template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import { | ||
ContentChildren, | ||
EventEmitter, | ||
Input, | ||
Output, | ||
QueryList, | ||
Directive, | ||
// This import is only used to define a generic type. The current TypeScript version incorrectly | ||
// considers such imports as unused (https://github.com/Microsoft/TypeScript/issues/14953) | ||
// tslint:disable-next-line:no-unused-variable | ||
ElementRef, | ||
Component, | ||
ContentChild, | ||
ViewChild, | ||
TemplateRef | ||
} from '@angular/core'; | ||
import {LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE} from '../keyboard/keycodes'; | ||
import {CdkStepLabel} from './step-label'; | ||
|
||
/** Used to generate unique ID for each stepper component. */ | ||
let nextId = 0; | ||
|
||
/** Change event emitted on selection changes. */ | ||
export class CdkStepperSelectionEvent { | ||
/** Index of the step now selected. */ | ||
selectedIndex: number; | ||
|
||
/** Index of the step previously selected. */ | ||
previouslySelectedIndex: number; | ||
|
||
/** The step instance now selected. */ | ||
selectedStep: CdkStep; | ||
|
||
/** The step instance previously selected. */ | ||
previouslySelectedStep: CdkStep; | ||
} | ||
|
||
@Component({ | ||
selector: 'cdk-step', | ||
templateUrl: 'step.html', | ||
}) | ||
export class CdkStep { | ||
/** Template for step label if it exists. */ | ||
@ContentChild(CdkStepLabel) stepLabel: CdkStepLabel; | ||
|
||
/** Template for step content. */ | ||
@ViewChild(TemplateRef) content: TemplateRef<any>; | ||
|
||
/** Label of the step. */ | ||
@Input() | ||
label: string; | ||
|
||
constructor(private _stepper: CdkStepper) { } | ||
|
||
/** Selects this step component. */ | ||
select(): void { | ||
this._stepper.selected = this; | ||
} | ||
} | ||
|
||
@Directive({ | ||
selector: 'cdk-stepper', | ||
host: { | ||
'(focus)': '_focusStep()', | ||
'(keydown)': '_onKeydown($event)', | ||
}, | ||
}) | ||
export class CdkStepper { | ||
/** The list of step components that the stepper is holding. */ | ||
@ContentChildren(CdkStep) _steps: QueryList<CdkStep>; | ||
|
||
/** The list of step headers of the steps in the stepper. */ | ||
_stepHeader: QueryList<ElementRef>; | ||
|
||
/** The index of the selected step. */ | ||
@Input() | ||
get selectedIndex() { return this._selectedIndex; } | ||
set selectedIndex(index: number) { | ||
if (this._selectedIndex != index) { | ||
this._emitStepperSelectionEvent(index); | ||
this._focusStep(this._selectedIndex); | ||
} | ||
} | ||
private _selectedIndex: number = 0; | ||
|
||
/** The step that is selected. */ | ||
@Input() | ||
get selected() { return this._steps[this.selectedIndex]; } | ||
set selected(step: CdkStep) { | ||
let index = this._steps.toArray().indexOf(step); | ||
this.selectedIndex = index; | ||
} | ||
|
||
/** Event emitted when the selected step has changed. */ | ||
@Output() selectionChange = new EventEmitter<CdkStepperSelectionEvent>(); | ||
|
||
/** The index of the step that the focus can be set. */ | ||
_focusIndex: number = 0; | ||
|
||
/** Used to track unique ID for each stepper component. */ | ||
private _groupId: number; | ||
|
||
constructor() { | ||
this._groupId = nextId++; | ||
} | ||
|
||
/** Selects and focuses the next step in list. */ | ||
next(): void { | ||
this.selectedIndex = Math.min(this._selectedIndex + 1, this._steps.length - 1); | ||
} | ||
|
||
/** Selects and focuses the previous step in list. */ | ||
previous(): void { | ||
this.selectedIndex = Math.max(this._selectedIndex - 1, 0); | ||
} | ||
|
||
/** Returns a unique id for each step label element. */ | ||
_getStepLabelId(i: number): string { | ||
return `mat-step-label-${this._groupId}-${i}`; | ||
} | ||
|
||
/** Returns nique id for each step content element. */ | ||
_getStepContentId(i: number): string { | ||
return `mat-step-content-${this._groupId}-${i}`; | ||
} | ||
|
||
private _emitStepperSelectionEvent(newIndex: number): void { | ||
const stepsArray = this._steps.toArray(); | ||
this.selectionChange.emit({ | ||
selectedIndex: newIndex, | ||
previouslySelectedIndex: this._selectedIndex, | ||
selectedStep: stepsArray[newIndex], | ||
previouslySelectedStep: stepsArray[this._selectedIndex], | ||
}); | ||
this._selectedIndex = newIndex; | ||
} | ||
|
||
_onKeydown(event: KeyboardEvent) { | ||
switch (event.keyCode) { | ||
case RIGHT_ARROW: | ||
this._focusStep((this._focusIndex + 1) % this._steps.length); | ||
break; | ||
case LEFT_ARROW: | ||
this._focusStep((this._focusIndex + this._steps.length - 1) % this._steps.length); | ||
break; | ||
case SPACE: | ||
case ENTER: | ||
this._emitStepperSelectionEvent(this._focusIndex); | ||
break; | ||
default: | ||
// Return to avoid calling preventDefault on keys that are not explicitly handled. | ||
return; | ||
} | ||
event.preventDefault(); | ||
} | ||
|
||
private _focusStep(index: number) { | ||
this._focusIndex = index; | ||
this._stepHeader.toArray()[this._focusIndex].nativeElement.focus(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<h2>Horizontal Stepper Demo</h2> | ||
<md-horizontal-stepper> | ||
<md-step *ngFor="let step of steps" [label]="step.label"> | ||
<md-input-container> | ||
<input mdInput placeholder="Answer" [(ngModel)]="step.content"> | ||
</md-input-container> | ||
</md-step> | ||
</md-horizontal-stepper> | ||
|
||
<h2>Horizontal Stepper Demo with Templated Label</h2> | ||
<md-horizontal-stepper> | ||
<md-step *ngFor="let step of steps"> | ||
<ng-template mdStepLabel>{{step.label}}</ng-template> | ||
<md-input-container> | ||
<input mdInput placeholder="Answer" [(ngModel)]="step.content"> | ||
</md-input-container> | ||
</md-step> | ||
</md-horizontal-stepper> | ||
|
||
<h2>Vertical Stepper Demo</h2> | ||
<md-vertical-stepper> | ||
<md-step *ngFor="let step of steps" [label]="step.label"> | ||
<md-input-container> | ||
<input mdInput placeholder="Answer" [(ngModel)]="step.content"> | ||
</md-input-container> | ||
</md-step> | ||
</md-vertical-stepper> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {Component} from '@angular/core'; | ||
|
||
@Component({ | ||
moduleId: module.id, | ||
selector: 'stepper-demo', | ||
templateUrl: 'stepper-demo.html', | ||
styleUrls: ['stepper-demo.scss'], | ||
}) | ||
export class StepperDemo { | ||
steps = [ | ||
{label: 'Confirm your name', content: 'Last name, First name.'}, | ||
{label: 'Confirm your contact information', content: '123-456-7890'}, | ||
{label: 'Confirm your address', content: '1600 Amphitheater Pkwy MTV'}, | ||
{label: 'You are now done', content: 'Finished!'} | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.