import { AfterContentInit , Component , ContentChildren , HostBinding , Input , QueryList } from '@angular/core' ; import { MovingDirection } from '../util/moving-direction.enum' ; import { WizardStep } from '../util/wizard-step.interface' ; import { isBoolean } from 'util' ; author Marc Arndt
  @ Component ( { selector : 'wizard' , templateUrl : 'wizard.component.html' , styleUrls : [ 'wizard.component.scss' ] , } ) export class WizardComponent implements AfterContentInit { /**
     * A QueryList containing all WizardSteps in this Wizard
     */ @ ContentChildren ( WizardStep ) public wizardSteps : QueryList < WizardStep > ; type { string } @ Input ( ) public navBarLocation = 'top' ; returns { boolean } @ HostBinding ( 'class.horizontal' ) public get horizontalOrientation ( ) : boolean { return this . navBarLocation === 'top' || this . navBarLocation === 'bottom' ; } returns { boolean } @ HostBinding ( 'class.vertical' ) public get verticalOrientation ( ) : boolean { return this . navBarLocation === 'left' || this . navBarLocation === 'right' ; } /**
     * The index of the currently visible and selected step inside the wizardSteps QueryList.
     * If this wizard contains no steps, currentStepIndex is -1
     */ public currentStepIndex = - 1 ; /**
     * The WizardStep object belonging to the currently visible and selected step.
     * The currentStep is always the currently selected wizard step.
     * The currentStep can be either completed, if it was visited earlier,
     * or not completed, if it is visited for the first time or its state is currently out of date.
     *
     * If this wizard contains no steps, currentStep is null
     */ public currentStep : WizardStep ; /**
     * If this wizard has been completed, `completed` will be true
     */ public completed : boolean ; /**
     * Constructor
     */ constructor ( ) { } /**
     * Initialization work
     */ ngAfterContentInit ( ) { this . reset ( ) ; } param stepIndex returns { boolean } hasStep ( stepIndex ) { return this . wizardSteps . length > 0 && 0 <= stepIndex && stepIndex < this . wizardSteps . length ; } returns { boolean } hasPreviousStep ( ) { return this . hasStep ( this . currentStepIndex - 1 ) ; } returns { boolean } hasNextStep ( ) { return this . hasStep ( this . currentStepIndex + 1 ) ; } returns { boolean } isLastStep ( ) { return this . wizardSteps . length > 0 && this . currentStepIndex === this . wizardSteps . length - 1 ; } param stepIndex returns { undefined | WizardStep } throws getStepAtIndex ( stepIndex ) { if ( ! this . hasStep ( stepIndex ) ) { throw new Error ( `Expected a known step, but got stepIndex: ${ stepIndex }.` ) ; } return this . wizardSteps . find ( ( item , index , array ) => index === stepIndex ) ; } param step returns { number } getIndexOfStep ( step ) { let stepIndex = - 1 ; this . wizardSteps . forEach ( ( item , index , array ) => { if ( item === step ) { stepIndex = index ; } } ) ; return stepIndex ; } param destinationStep returns { MovingDirection } getMovingDirection ( destinationStep ) { let movingDirection ; if ( destinationStep > this . currentStepIndex ) { movingDirection = MovingDirection . Forwards ; } else if ( destinationStep < this . currentStepIndex ) { movingDirection = MovingDirection . Backwards ; } else { movingDirection = MovingDirection . Stay ; } return movingDirection ; } /**
     * Tries to transition the wizard to the previous step from the `currentStep`
     */ goToPreviousStep ( ) { if ( this . hasPreviousStep ( ) ) { this . goToStep ( this . currentStepIndex - 1 ) ; } } /**
     * Tries to transition the wizard to the next step from the `currentStep`
     */ goToNextStep ( ) { if ( this . hasNextStep ( ) ) { this . goToStep ( this . currentStepIndex + 1 ) ; } } returns { boolean } canGoToPreviousStep ( ) { const previousStepIndex = this . currentStepIndex - 1 ; return this . hasStep ( previousStepIndex ) && this . canGoToStep ( previousStepIndex ) ; } returns { boolean } canGoToNextStep ( ) { const nextStepIndex = this . currentStepIndex + 1 ; return this . hasStep ( nextStepIndex ) && this . canGoToStep ( nextStepIndex ) ; } param stepIndex returns { boolean } canGoToStep ( stepIndex ) { let result = this . canExitStep ( this . currentStep , this . getMovingDirection ( stepIndex ) ) && this . hasStep ( stepIndex ) ; this . wizardSteps . forEach ( ( wizardStep , index , array ) => { if ( index < stepIndex && index !== this . currentStepIndex ) { result = result && ( wizardStep . completed || wizardStep . optional ) ; } } ) ; return result ; } param destinationStepIndex goToStep ( destinationStepIndex ) { const destinationStep = this . getStepAtIndex ( destinationStepIndex ) ; const movingDirection = this . getMovingDirection ( destinationStepIndex ) ; if ( this . canExitStep ( this . currentStep , movingDirection ) ) { this . wizardSteps . forEach ( ( wizardStep , index , array ) => { if ( index === this . currentStepIndex ) { wizardStep . completed = true ; } if ( this . currentStepIndex > destinationStepIndex && index > destinationStepIndex ) { wizardStep . completed = false ; } } ) ; this . currentStep . exit ( movingDirection ) ; this . currentStep . selected = false ; this . currentStepIndex = destinationStepIndex ; this . currentStep = destinationStep ; this . currentStep . enter ( movingDirection ) ; this . currentStep . selected = true ; } else { this . currentStep . exit ( MovingDirection . Stay ) ; this . currentStep . enter ( MovingDirection . Stay ) ; } } /**
     * Resets the state of this wizard.
     * A reset transitions the wizard automatically to the first step and sets all steps as incomplete.
     * In addition the whole wizard is set as incomplete
     */ reset ( ) { this . wizardSteps . forEach ( ( step , index ) => { step . completed = false ; step . selected = false ; } ) ; this . completed = false ; this . currentStepIndex = 0 ; this . currentStep = this . getStepAtIndex ( 0 ) ; this . currentStep . selected = true ; this . currentStep . enter ( MovingDirection . Forwards ) ; } param wizardStep param direction returns { any } throws public canExitStep ( wizardStep , direction ) { if ( isBoolean ( wizardStep . canExit ) ) { return wizardStep . canExit as boolean ; } else if ( wizardStep . canExit instanceof Function ) { return wizardStep . canExit ( direction ) ; } else { throw new Error ( `Input value '${ wizardStep . canExit }' is neither a boolean nor a function` ) ; } } }