Skip to content

Commit

Permalink
*BREAKING CHANGE* feature(steps): register/de-register steps dynamica…
Browse files Browse the repository at this point in the history
…lly. closes(#200) (#205)

* replaced numbers by steps in change step event + registered new steps when they change by making then dynamic

* remove number from step and validation that didnt allow to render td-step without a number

* remove changeStep event from demo

* better css labels for unit tests

* better css classes to diff between vertical header and horizontal header

* initial step unit tests

* added more basic unit tests and new use case for ngFor

* hide button-group labels when screen size is md sm and xs in stepper

* added demo and code as a better example

* missed a line in code

* fixed doc imports

* fix tslint issues
  • Loading branch information
emoralesb05 authored and kyleledbetter committed Dec 26, 2016
1 parent 6403262 commit 6486eb5
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 102 deletions.
132 changes: 99 additions & 33 deletions src/app/components/components/steps/steps.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,105 @@
<md-card-subtitle>A sequence of logical & numbered steps</md-card-subtitle>
<md-divider></md-divider>
<md-card-content>
<div layout="row" layout-align="start center">
<md-button-toggle-group (change)="modeChange()" name="mode" [(ngModel)]="mode">
<md-button-toggle md-tooltip="Vertical Stepper" [value]="0"><md-icon>swap_vert</md-icon> Vertical</md-button-toggle>
<md-button-toggle md-tooltip="Horizontal Stepper" [value]="1"><md-icon>swap_horiz</md-icon> Horizontal</md-button-toggle>
<md-button-toggle md-tooltip="Responsive (changes from horizontal to vertical)" [value]="2"><md-icon>devices</md-icon> Responsive (gt-sm)</md-button-toggle>
</md-button-toggle-group>
</div>
<p>Change Event: {{stepChangeMsg}}</p>
<p>Active/Deactive Event for Step 1: {{activeDeactiveStep1Msg}}</p>
<h3>{{horizontal ? 'Horizontal Mode' : 'Vertical Mode'}}</h3>
<td-steps (stepChange)="stepChange($event)" [mode]="horizontal ? 'horizontal' : 'vertical'">
<td-step #step1 label="Basic Usage" sublabel="Toggle between active and inactive and emit events." [active]="true" [disabled]="disabled" (activated)="activeStep1Event()" (deactivated)="deactiveStep1Event()">
<template td-step-label><span>Basic Usage (template)</span></template>
Include any content you like for an active stepper
</td-step>
<td-step #step2 label="Required State" sublabel="Toggle between active and inactive while in required state." [state]="stateStep2" [disabled]="disabled">
This step is required!
<template td-step-actions>
<button md-raised-button color="primary" (click)="toggleRequiredStep2()">Toggle Require</button>
<button md-button (click)="step2.active = false">Cancel</button>
</template>
</td-step>
<td-step #step3 label="Complete State" sublabel="Toggle between active and inactive while in complete state." [state]="stateStep3" [disabled]="disabled">
Mark this step complete and get a summary
<template td-step-summary>
Use an optional step summary to summarize the info in this step
</template>
<template td-step-actions>
<button md-raised-button color="primary" (click)="toggleCompleteStep3()">Toggle Complete</button>
<button md-button (click)="step3.active = false">Cancel</button>
</template>
</td-step>
</td-steps>
<h3 class="md-title">Basic Stepper</h3>
<md-tab-group md-stretch-tabs>
<md-tab>
<template md-tab-label>Demo</template>
<div layout="row" layout-align="start center">
<md-button-toggle-group (change)="modeChange()" name="mode" [(ngModel)]="mode">
<md-button-toggle md-tooltip="Vertical Stepper" [value]="0"><md-icon>swap_vert</md-icon> <span hide-md hide-sm hide-xs>Vertical</span></md-button-toggle>
<md-button-toggle md-tooltip="Horizontal Stepper" [value]="1"><md-icon>swap_horiz</md-icon> <span hide-md hide-sm hide-xs>Horizontal</span></md-button-toggle>
<md-button-toggle md-tooltip="Responsive (changes from horizontal to vertical)" [value]="2"><md-icon>devices</md-icon> <span hide-md hide-sm hide-xs>Responsive (gt-sm)</span></md-button-toggle>
</md-button-toggle-group>
</div>
<p>Active/Deactive Event for Step 1: {{activeDeactiveStep1Msg}}</p>
<h3>{{horizontal ? 'Horizontal Mode' : 'Vertical Mode'}}</h3>
<td-steps [mode]="horizontal ? 'horizontal' : 'vertical'">
<td-step #step1 label="Basic Usage" sublabel="Toggle between active and inactive and emit events." [active]="true" [disabled]="disabled" (activated)="activeStep1Event()" (deactivated)="deactiveStep1Event()">
<template td-step-label><span>Basic Usage (template)</span></template>
Include any content you like for an active stepper
</td-step>
<td-step #step2 label="Required State" sublabel="Toggle between active and inactive while in required state." [state]="stateStep2" [disabled]="disabled">
This step is required!
<template td-step-actions>
<button md-raised-button color="primary" (click)="toggleRequiredStep2()">Toggle Require</button>
<button md-button (click)="step2.active = false">Cancel</button>
</template>
</td-step>
<td-step #step3 label="Complete State" sublabel="Toggle between active and inactive while in complete state." [state]="stateStep3" [disabled]="disabled">
Mark this step complete and get a summary
<template td-step-summary>
Use an optional step summary to summarize the info in this step
</template>
<template td-step-actions>
<button md-raised-button color="primary" (click)="toggleCompleteStep3()">Toggle Complete</button>
<button md-button (click)="step3.active = false">Cancel</button>
</template>
</td-step>
</td-steps>
</md-tab>
<md-tab>
<template md-tab-label>Code</template>
<p>HTML:</p>
<td-highlight lang="html">
<![CDATA[
<td-steps>
<td-step #step1 label="Basic Usage" sublabel="Toggle between active and inactive and emit events." [active]="true" [disabled]="disabled" (activated)="activeStep1Event()" (deactivated)="deactiveStep1Event()">
<template td-step-label><span>Basic Usage (template)</span></template>
Include any content you like for an active stepper
</td-step>
<td-step #step2 label="Required State" sublabel="Toggle between active and inactive while in required state." [state]="stateStep2" [disabled]="disabled">
This step is required!
<template td-step-actions>
<button md-raised-button color="primary" (click)="toggleRequiredStep2()">Toggle Require</button>
<button md-button (click)="step2.active = false">Cancel</button>
</template>
</td-step>
<td-step #step3 label="Complete State" sublabel="Toggle between active and inactive while in complete state." [state]="stateStep3" [disabled]="disabled">
Mark this step complete and get a summary
<template td-step-summary>
Use an optional step summary to summarize the info in this step
</template>
<template td-step-actions>
<button md-raised-button color="primary" (click)="toggleCompleteStep3()">Toggle Complete</button>
<button md-button (click)="step3.active = false">Cancel</button>
</template>
</td-step>
</td-steps>
]]>
</td-highlight>
<p>Typescript:</p>
<td-highlight lang="typescript">
<![CDATA[
import { StepState } from '@covalent/core';
...
})
export class Demo {
activeDeactiveStep1Msg: string = 'No select/deselect detected yet';
stateStep2: StepState = StepState.Required;
stateStep3: StepState = StepState.Complete;
disabled: boolean = false;

toggleRequiredStep2(): void {
this.stateStep2 = (this.stateStep2 === StepState.Required ? StepState.None : StepState.Required);
}

toggleCompleteStep3(): void {
this.stateStep3 = (this.stateStep3 === StepState.Complete ? StepState.None : StepState.Complete);
}

activeStep1Event(): void {
this.activeDeactiveStep1Msg = 'Active event emitted.';
}

deactiveStep1Event(): void {
this.activeDeactiveStep1Msg = 'Deactive event emitted.';
}
}
]]>
</td-highlight>
</md-tab>
</md-tab-group>
</md-card-content>
<md-divider></md-divider>
<md-card-actions>
Expand Down
11 changes: 1 addition & 10 deletions src/app/components/components/steps/steps.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, OnInit, OnDestroy, NgZone } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

import { StepState, IStepChangeEvent, TdMediaService } from '../../../../platform/core';
import { StepState, TdMediaService } from '../../../../platform/core';

@Component({
selector: 'steps-demo',
Expand Down Expand Up @@ -70,7 +70,6 @@ export class StepsDemoComponent implements OnInit, OnDestroy {
mode: number = 0;
horizontal: boolean = true;
isScreenGtSm: boolean = false;
stepChangeMsg: string = 'No change detected yet.';
activeDeactiveStep1Msg: string = 'No select/deselect detected yet';
stateStep2: StepState = StepState.Required;
stateStep3: StepState = StepState.Complete;
Expand Down Expand Up @@ -116,14 +115,6 @@ export class StepsDemoComponent implements OnInit, OnDestroy {
this.stateStep3 = (this.stateStep3 === StepState.Complete ? StepState.None : StepState.Complete);
}

stepChange(event: IStepChangeEvent): void {
if (event.prevStep === undefined) {
this.stepChangeMsg = `Started at step: ${event.newStep}`;
} else {
this.stepChangeMsg = `Changed from step: ${event.prevStep} to step: ${event.newStep}`;
}
}

toggleDisabled(): void {
this.disabled = !this.disabled;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
*ngIf="isRequired()">
<md-icon class="md-warn">warning</md-icon>
</div>
<div class="td-step-label"
<div class="td-step-label-wrapper"
[class.md-disabled]="(!active && !isComplete()) || disabled"
[class.md-warn]="isRequired() && !disabled">
<div class="md-body-2">
<div class="md-body-2 td-step-label">
<ng-content select="[td-step-header-label]"></ng-content>
</div>
<div class="md-caption td-step-sublabel">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ md-icon {
.td-triangle {
margin-left: 7px;
}
.td-step-label {
.td-step-label-wrapper {
padding-left: 8px;
padding-right: 8px;
}
Expand Down
24 changes: 2 additions & 22 deletions src/platform/core/steps/step.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, Directive, Input, Output, TemplateRef, ViewChild,
ViewContainerRef, ContentChild, AfterViewInit, OnInit } from '@angular/core';
ViewContainerRef, ContentChild, OnInit } from '@angular/core';
import { EventEmitter } from '@angular/core';
import { TemplatePortalDirective, TemplatePortal } from '@angular/material';

Expand Down Expand Up @@ -40,9 +40,8 @@ export class TdStepSummaryDirective extends TemplatePortalDirective {
selector: 'td-step',
templateUrl: 'step.component.html',
})
export class TdStepComponent implements OnInit, AfterViewInit {
export class TdStepComponent implements OnInit {

private _number: number;
private _active: boolean = false;
private _state: StepState = StepState.None;
private _disabled: boolean = false;
Expand All @@ -57,19 +56,6 @@ export class TdStepComponent implements OnInit, AfterViewInit {
@ContentChild(TdStepActionsDirective) stepActions: TdStepActionsDirective;
@ContentChild(TdStepSummaryDirective) stepSummary: TdStepSummaryDirective;

/**
* Number assigned by [TdStepsComponent] parent element.
*/
set number(num: number) {
if (this._number > 0) {
return;
}
this._number = num;
}
get number(): number {
return this._number;
}

/**
* label?: string
* Sets label of [TdStepComponent] header.
Expand Down Expand Up @@ -152,12 +138,6 @@ export class TdStepComponent implements OnInit, AfterViewInit {
this._contentPortal = new TemplatePortal(this._content, this._viewContainerRef);
}

ngAfterViewInit(): void {
if (this.number === undefined) {
throw 'The [td-step] component needs to have a [td-steps] parent component to work.';
}
}

/**
* Toggle active state of [TdStepComponent]
* retuns 'true' if successful, else 'false'.
Expand Down
16 changes: 9 additions & 7 deletions src/platform/core/steps/steps.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<div *ngIf="isHorizontal()" class="td-steps-header" layout="row" title>
<template let-step let-last="last" ngFor [ngForOf]="steps">
<td-step-header (keydown.enter)="step.toggle()"
[number]="step.number"
<template let-step let-index="index" let-last="last" ngFor [ngForOf]="steps">
<td-step-header class="td-step-horizontal-header"
(keydown.enter)="step.toggle()"
[number]="index + 1"
[active]="step.active"
[disabled]="step.disabled"
[state]="step.state"
Expand All @@ -13,9 +14,10 @@
<span *ngIf="!last" class="td-horizontal-line" flex></span>
</template>
</div>
<div *ngFor="let step of steps; let last = last" class="td-step" layout="column">
<td-step-header (keydown.enter)="step.toggle()"
[number]="step.number"
<div *ngFor="let step of steps; let index = index; let last = last" class="td-step" layout="column">
<td-step-header class="td-step-vertical-header"
(keydown.enter)="step.toggle()"
[number]="index + 1"
[active]="step.active"
[disabled]="step.disabled"
[state]="step.state"
Expand All @@ -25,7 +27,7 @@
<template td-step-header-label [ngIf]="!step.stepLabel">{{step.label}}</template>
<template td-step-header-sublabel [ngIf]="true">{{step.sublabel}}</template>
</td-step-header>
<template [ngIf]="isVertical() || step.active || (!areStepsActive() && _prevStep === step.number)">
<template [ngIf]="isVertical() || step.active || (!areStepsActive() && prevStep === step)">
<td-step-body [active]="step.active" [state]="step.state">
<div *ngIf="isVertical()" class="td-line-wrapper">
<div *ngIf="!last" class="td-vertical-line"></div>
Expand Down
Loading

0 comments on commit 6486eb5

Please sign in to comment.