@rg-software/angular-archwizard
Version:
A fork of the Angular Arch Wizard adapted for angular versions 17+.
1 lines • 112 kB
Source Map (JSON)
{"version":3,"file":"rg-software-angular-archwizard.mjs","sources":["../../../src/lib/directives/wizard-step-symbol.directive.ts","../../../src/lib/directives/wizard-step-title.directive.ts","../../../src/lib/util/wizard-step.interface.ts","../../../src/lib/util/wizard-completion-step.interface.ts","../../../src/lib/components/wizard-completion-step.component.ts","../../../src/lib/components/wizard-completion-step.component.html","../../../src/lib/util/wizard.interface.ts","../../../src/lib/util/step-id.interface.ts","../../../src/lib/util/step-index.interface.ts","../../../src/lib/util/step-offset.interface.ts","../../../src/lib/directives/go-to-step.directive.ts","../../../src/lib/components/wizard-navigation-bar.component.ts","../../../src/lib/components/wizard-navigation-bar.component.html","../../../src/lib/components/wizard-step.component.ts","../../../src/lib/components/wizard-step.component.html","../../../src/lib/util/moving-direction.enum.ts","../../../src/lib/navigation/base-navigation-mode.interface.ts","../../../src/lib/navigation/configurable-navigation-mode.ts","../../../src/lib/components/wizard.component.ts","../../../src/lib/components/wizard.component.html","../../../src/lib/directives/enable-back-links.directive.ts","../../../src/lib/directives/next-step.directive.ts","../../../src/lib/directives/optional-step.directive.ts","../../../src/lib/directives/previous-step.directive.ts","../../../src/lib/directives/reset-wizard.directive.ts","../../../src/lib/directives/selected-step.directive.ts","../../../src/lib/directives/wizard-completion-step.directive.ts","../../../src/lib/directives/wizard-step.directive.ts","../../../src/lib/directives/navigation-mode.directive.ts","../../../src/lib/directives/completed-step.directive.ts","../../../src/lib/archwizard.module.ts","../../../src/index.ts","../../../src/rg-software-angular-archwizard.ts"],"sourcesContent":["import {Directive, TemplateRef} from '@angular/core';\n\n/**\n * The `awWizardStepSymbol` directive can be used as an alternative to the `navigationSymbol` input of a [[WizardStep]]\n * to define the step symbol inside the navigation bar. This way step symbol may contain arbitrary content.\n *\n * ### Syntax\n *\n * ```html\n * <ng-template awWizardStepSymbol>\n * ...\n * </ng-template>\n * ```\n */\n@Directive({\n selector: 'ng-template[awStepSymbol], ng-template[awWizardStepSymbol]'\n})\nexport class WizardStepSymbolDirective {\n /**\n * Constructor\n *\n * @param templateRef A reference to the content of the `ng-template` that contains this [[WizardStepSymbolDirective]]\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(public templateRef: TemplateRef<any>) {\n }\n}\n","import {Directive, TemplateRef} from '@angular/core';\n\n/**\n * The `awWizardStepTitle` directive can be used as an alternative to the `stepTitle` input of a [[WizardStep]]\n * to define the content of a step title inside the navigation bar.\n * This step title can be freely created and can contain more than only plain text\n *\n * ### Syntax\n *\n * ```html\n * <ng-template awWizardStepTitle>\n * ...\n * </ng-template>\n * ```\n *\n * @author Marc Arndt\n */\n@Directive({\n selector: 'ng-template[awStepTitle], ng-template[awWizardStepTitle]'\n})\nexport class WizardStepTitleDirective {\n /**\n * Constructor\n *\n * @param templateRef A reference to the content of the `ng-template` that contains this [[WizardStepTitleDirective]]\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(public templateRef: TemplateRef<any>) {\n }\n}\n","import { ContentChild, EventEmitter, HostBinding, Input, Output, Directive } from '@angular/core';\nimport {WizardStepSymbolDirective} from '../directives/wizard-step-symbol.directive';\nimport {WizardStepTitleDirective} from '../directives/wizard-step-title.directive';\nimport {MovingDirection} from './moving-direction.enum';\nimport {NavigationSymbol} from './navigation-symbol.interface';\n\n/**\n * Basic functionality every type of wizard step needs to provide\n *\n * @author Marc Arndt\n */\n@Directive()\n/* tslint:disable-next-line directive-class-suffix */\nexport abstract class WizardStep {\n /**\n * A step title property, which contains the visible header title of the step.\n * This title is then shown inside the navigation bar.\n * Compared to `stepTitle` this property can contain any html content and not only plain text\n */\n @ContentChild(WizardStepTitleDirective)\n public stepTitleTemplate: WizardStepTitleDirective;\n\n /**\n * A step symbol property that, if defined, overrides `navigationSymbol`.\n * Allows to display arbitrary content as a step symbol instead of plain text.\n */\n @ContentChild(WizardStepSymbolDirective)\n public stepSymbolTemplate: WizardStepSymbolDirective;\n\n /**\n * A step id, unique to the step\n */\n @Input()\n public stepId: string;\n\n /**\n * A step title property, which contains the visible header title of the step.\n * This title is only shown inside the navigation bar, if `stepTitleTemplate` is not defined or null.\n */\n @Input()\n public stepTitle: string;\n\n /**\n * A symbol property, which contains an optional symbol for the step inside the navigation bar.\n * Takes effect when `stepSymbolTemplate` is not defined or null.\n */\n @Input()\n public navigationSymbol: NavigationSymbol = {symbol: ''};\n\n /**\n * A boolean describing if the wizard step is currently selected\n */\n public selected = false;\n\n /**\n * A boolean describing if the wizard step has been completed\n */\n public completed = false;\n\n /**\n * A boolean describing if the wizard step is shown as completed when the wizard is presented to the user\n *\n * Users will typically use `CompletedStepDirective` to set this flag\n */\n public initiallyCompleted = false;\n\n /**\n * A boolean describing if the wizard step is being edited after being competed\n *\n * This flag can only be true when `selected` is true.\n */\n public editing = false;\n\n /**\n * A boolean describing, if the wizard step should be selected by default, i.e. after the wizard has been initialized as the initial step\n */\n public defaultSelected = false;\n\n /**\n * A boolean describing if the wizard step is an optional step\n */\n public optional = false;\n\n /**\n * A function or boolean deciding, if this step can be entered\n */\n @Input()\n public canEnter: ((direction: MovingDirection) => boolean) | ((direction: MovingDirection) => Promise<boolean>) | boolean = true;\n\n /**\n * A function or boolean deciding, if this step can be exited\n */\n @Input()\n public canExit: ((direction: MovingDirection) => boolean) | ((direction: MovingDirection) => Promise<boolean>) | boolean = true;\n\n /**\n * This [[EventEmitter]] is called when the step is entered.\n * The bound method should be used to do initialization work.\n */\n @Output()\n public stepEnter: EventEmitter<MovingDirection> = new EventEmitter<MovingDirection>();\n\n /**\n * This [[EventEmitter]] is called when the step is exited.\n * The bound method can be used to do cleanup work.\n */\n @Output()\n public stepExit: EventEmitter<MovingDirection> = new EventEmitter<MovingDirection>();\n\n /**\n * Returns true if this wizard step should be visible to the user.\n * If the step should be visible to the user false is returned, otherwise true\n */\n @HostBinding('hidden')\n public get hidden(): boolean {\n return !this.selected;\n }\n\n /**\n * This method returns true, if this wizard step can be transitioned with a given direction.\n * Transitioned in this case means either entered or exited, depending on the given `condition` parameter.\n *\n * @param condition A condition variable, deciding if the step can be transitioned\n * @param direction The direction in which this step should be transitioned\n * @returns A [[Promise]] containing `true`, if this step can transitioned in the given direction\n * @throws An `Error` is thrown if `condition` is neither a function nor a boolean\n */\n private static canTransitionStep(condition: ((direction: MovingDirection) => boolean) |\n ((direction: MovingDirection) => Promise<boolean>) |\n boolean,\n direction: MovingDirection): Promise<boolean> {\n if (typeof(condition) === typeof(true)) {\n return Promise.resolve(condition as boolean);\n } else if (condition instanceof Function) {\n return Promise.resolve(condition(direction));\n } else {\n return Promise.reject(new Error(`Input value '${condition}' is neither a boolean nor a function`));\n }\n }\n\n /**\n * A function called when the step is entered\n *\n * @param direction The direction in which the step is entered\n */\n public enter(direction: MovingDirection): void {\n this.stepEnter.emit(direction);\n }\n\n /**\n * A function called when the step is exited\n *\n * @param direction The direction in which the step is exited\n */\n public exit(direction: MovingDirection) {\n this.stepExit.emit(direction);\n }\n\n /**\n * This method returns true, if this wizard step can be entered from the given direction.\n * Because this method depends on the value `canEnter`, it will throw an error, if `canEnter` is neither a boolean\n * nor a function.\n *\n * @param direction The direction in which this step should be entered\n * @returns A [[Promise]] containing `true`, if the step can be entered in the given direction, false otherwise\n * @throws An `Error` is thrown if `anEnter` is neither a function nor a boolean\n */\n public canEnterStep(direction: MovingDirection): Promise<boolean> {\n return WizardStep.canTransitionStep(this.canEnter, direction);\n }\n\n /**\n * This method returns true, if this wizard step can be exited into given direction.\n * Because this method depends on the value `canExit`, it will throw an error, if `canExit` is neither a boolean\n * nor a function.\n *\n * @param direction The direction in which this step should be left\n * @returns A [[Promise]] containing `true`, if the step can be exited in the given direction, false otherwise\n * @throws An `Error` is thrown if `canExit` is neither a function nor a boolean\n */\n public canExitStep(direction: MovingDirection): Promise<boolean> {\n return WizardStep.canTransitionStep(this.canExit, direction);\n }\n}\n","import {EventEmitter, Directive} from '@angular/core';\nimport {WizardStep} from './wizard-step.interface';\nimport {MovingDirection} from './moving-direction.enum';\n\n/**\n * Basic functionality every wizard completion step needs to provide\n *\n * @author Marc Arndt\n */\n@Directive()\n/* tslint:disable-next-line directive-class-suffix */\nexport abstract class WizardCompletionStep extends WizardStep {\n /**\n * @inheritDoc\n */\n public stepExit = new EventEmitter<MovingDirection>();\n\n /**\n * @inheritDoc\n */\n public canExit: ((direction: MovingDirection) => boolean) | boolean = false;\n\n /**\n * @inheritDoc\n */\n public enter(direction: MovingDirection): void {\n this.completed = true;\n this.stepEnter.emit(direction);\n }\n\n /**\n * @inheritDoc\n */\n public exit(direction: MovingDirection): void {\n // set this completion step as incomplete (unless it happens to be initiallyCompleted)\n this.completed = this.initiallyCompleted;\n this.stepExit.emit(direction);\n }\n}\n","import {Component, forwardRef} from '@angular/core';\nimport {WizardCompletionStep} from '../util/wizard-completion-step.interface';\nimport {WizardStep} from '../util/wizard-step.interface';\n\n/**\n * The `aw-wizard-completion-step` component can be used to define a completion/success step at the end of your wizard\n * After a `aw-wizard-completion-step` has been entered, it has the characteristic that the user is blocked from\n * leaving it again to a previous step.\n * In addition entering a `aw-wizard-completion-step` automatically sets the `aw-wizard` and all steps inside the `aw-wizard`\n * as completed.\n *\n * ### Syntax\n *\n * ```html\n * <aw-wizard-completion-step [stepTitle]=\"title of the wizard step\"\n * [navigationSymbol]=\"{ symbol: 'navigation symbol', fontFamily: 'navigation symbol font family' }\"\n * (stepEnter)=\"event emitter to be called when the wizard step is entered\"\n * (stepExit)=\"event emitter to be called when the wizard step is exited\">\n * ...\n * </aw-wizard-completion-step>\n * ```\n *\n * ### Example\n *\n * ```html\n * <aw-wizard-completion-step stepTitle=\"Step 1\" [navigationSymbol]=\"{ symbol: '1' }\">\n * ...\n * </aw-wizard-completion-step>\n * ```\n *\n * With a navigation symbol from the `font-awesome` font:\n *\n * ```html\n * <aw-wizard-completion-step stepTitle=\"Step 1\" [navigationSymbol]=\"{ symbol: '', fontFamily: 'FontAwesome' }\">\n * ...\n * </aw-wizard-completion-step>\n * ```\n *\n * @author Marc Arndt\n */\n@Component({\n selector: 'aw-wizard-completion-step',\n templateUrl: 'wizard-completion-step.component.html',\n providers: [\n {provide: WizardStep, useExisting: forwardRef(() => WizardCompletionStepComponent)},\n {provide: WizardCompletionStep, useExisting: forwardRef(() => WizardCompletionStepComponent)}\n ]\n})\nexport class WizardCompletionStepComponent extends WizardCompletionStep {\n}\n","<ng-content></ng-content>\n","import { EventEmitter, Injectable } from '@angular/core';\nimport { WizardStep } from './wizard-step.interface';\n\n@Injectable()\nexport abstract class WizardBase {\n public abstract navBarDirection: string;\n public abstract get wizardSteps(): WizardStep[];\n public abstract disableNavigationBar: boolean;\n public abstract get completed(): boolean;\n public abstract isNavigable(destinationIndex: number): boolean;\n public abstract getIndexOfStepWithId(stepId: string): number;\n public abstract getIndexOfStep(step: WizardStep): number;\n public abstract goToStep(destinationIndex: number, preFinalize?: EventEmitter<void>, postFinalize?: EventEmitter<void>): void;\n}\n","import {WizardStep} from './wizard-step.interface';\nimport {StepIndex} from \"./step-index.interface\";\nimport {StepOffset} from \"./step-offset.interface\";\n\n/**\n * An unique identifier of a wizard step\n *\n * @author Marc Arndt\n */\nexport interface StepId {\n /**\n * The id of the destination step\n */\n stepId: string;\n}\n\n/**\n * Checks whether the given `value` implements the interface [[StepId]].\n *\n * @param value The value to be checked\n * @returns True if the given value implements [[StepId]] and false otherwise\n */\nexport function isStepId(value: WizardStep | StepId | StepIndex | StepOffset): value is StepId {\n return Object.prototype.hasOwnProperty.call(value, 'stepId') && !(value instanceof WizardStep);\n}\n","/**\n * An index of a wizard step.\n * This index is the index of the step inside the wizard.\n * The index is always zero based, i.e. the step with index 0 is the first step of the wizard\n *\n * @author Marc Arndt\n */\nimport {StepOffset} from \"./step-offset.interface\";\nimport {StepId} from \"./step-id.interface\";\nimport {WizardStep} from \"./wizard-step.interface\";\n\nexport interface StepIndex {\n /**\n * The index of the destination step\n */\n stepIndex: number;\n}\n\n/**\n * Checks whether the given `value` implements the interface [[StepIndex]].\n *\n * @param value The value to be checked\n * @returns True if the given value implements [[StepIndex]] and false otherwise\n */\nexport function isStepIndex(value: WizardStep | StepId | StepIndex | StepOffset): value is StepIndex {\n return Object.prototype.hasOwnProperty.call(value, 'stepIndex');\n}\n","/**\n * An offset between two steps.\n * This offset can be either positive or negative.\n * A positive offset means, that the offset step is after the other step, while a negative offset means,\n * that the offset step is ahead of the other step.\n *\n * @author Marc Arndt\n */\nexport interface StepOffset {\n /**\n * The offset to the destination step\n */\n stepOffset: number;\n}\n\n/**\n * Checks whether the given `value` implements the interface [[StepOffset]].\n *\n * @param value The value to be checked\n * @returns True if the given value implements [[StepOffset]] and false otherwise\n */\nexport function isStepOffset(value: {stepOffset: number}): value is StepOffset {\n return Object.prototype.hasOwnProperty.call(value, 'stepOffset');\n}\n","import { Directive, EventEmitter, HostListener, Input, Optional, Output } from '@angular/core';\nimport { isStepId, StepId } from '../util/step-id.interface';\nimport { isStepIndex, StepIndex } from '../util/step-index.interface';\nimport { isStepOffset, StepOffset } from '../util/step-offset.interface';\nimport { WizardStep } from '../util/wizard-step.interface';\nimport { WizardBase } from '../util/wizard.interface';\n\n\n/**\n * The `awGoToStep` directive can be used to navigate to a given step.\n * This step can be defined in one of multiple formats\n *\n * ### Syntax\n *\n * With absolute step index:\n *\n * ```html\n * <button [awGoToStep]=\"{ stepIndex: absolute step index }\" (finalize)=\"finalize method\">...</button>\n * ```\n *\n * With unique step id:\n *\n * ```html\n * <button [awGoToStep]=\"{ stepId: 'step id of destination step' }\" (finalize)=\"finalize method\">...</button>\n * ```\n *\n * With a wizard step object:\n *\n * ```html\n * <button [awGoToStep]=\"wizard step object\" (finalize)=\"finalize method\">...</button>\n * ```\n *\n * With an offset to the defining step:\n *\n * ```html\n * <button [awGoToStep]=\"{ stepOffset: offset }\" (finalize)=\"finalize method\">...</button>\n * ```\n *\n * @author Marc Arndt\n */\n@Directive({\n selector: '[awGoToStep]'\n})\nexport class GoToStepDirective {\n /**\n * This [[EventEmitter]] is called directly before the current step is exited during a transition through a component with this directive.\n */\n @Output()\n public preFinalize: EventEmitter<void> = new EventEmitter();\n\n /**\n * This [[EventEmitter]] is called directly after the current step is exited during a transition through a component with this directive.\n */\n @Output()\n public postFinalize: EventEmitter<void> = new EventEmitter();\n\n /**\n * The destination step, to which the wizard should navigate, after the component, having this directive has been activated.\n * This destination step can be given either as a [[WizardStep]] containing the step directly,\n * a [[StepOffset]] between the current step and the `wizardStep`, in which this directive has been used,\n * or a step index as a number or string\n */\n // tslint:disable-next-line:no-input-rename\n @Input('awGoToStep')\n public targetStep: WizardStep | StepOffset | StepIndex | StepId;\n\n /**\n * Constructor\n *\n * @param wizard The wizard component\n * @param wizardStep The wizard step, which contains this [[GoToStepDirective]]\n */\n constructor(private wizard: WizardBase, @Optional() private wizardStep: WizardStep) {\n }\n\n /**\n * A convenience field for `preFinalize`\n */\n public get finalize(): EventEmitter<void> {\n return this.preFinalize;\n }\n\n /**\n * A convenience name for `preFinalize`\n *\n * @param emitter The [[EventEmitter]] to be set\n */\n @Output()\n public set finalize(emitter: EventEmitter<void>) {\n /* istanbul ignore next */\n this.preFinalize = emitter;\n }\n\n /**\n * Returns the destination step of this directive as an absolute step index inside the wizard\n *\n * @returns The index of the destination step\n * @throws If `targetStep` is of an unknown type an `Error` is thrown\n */\n public get destinationStep(): number {\n let destinationStep: number;\n\n if (isStepIndex(this.targetStep)) {\n destinationStep = this.targetStep.stepIndex;\n } else if (isStepId(this.targetStep)) {\n destinationStep = this.wizard.getIndexOfStepWithId(this.targetStep.stepId);\n } else if (isStepOffset(this.targetStep) && this.wizardStep !== null) {\n destinationStep = this.wizard.getIndexOfStep(this.wizardStep) + this.targetStep.stepOffset;\n } else if (this.targetStep instanceof WizardStep) {\n destinationStep = this.wizard.getIndexOfStep(this.targetStep);\n } else {\n throw new Error(`Input 'targetStep' is neither a WizardStep, StepOffset, StepIndex or StepId`);\n }\n\n return destinationStep;\n }\n\n /**\n * Listener method for `click` events on the component with this directive.\n * After this method is called the wizard will try to transition to the `destinationStep`\n */\n @HostListener('click')\n public onClick(): void {\n this.wizard.goToStep(this.destinationStep, this.preFinalize, this.postFinalize);\n }\n}\n","import { Component } from '@angular/core';\nimport { WizardCompletionStep } from '../util/wizard-completion-step.interface';\nimport { WizardStep } from '../util/wizard-step.interface';\nimport { WizardBase } from '../util/wizard.interface';\n\n/**\n * The `aw-wizard-navigation-bar` component contains the navigation bar inside a [[WizardComponent]].\n * To correctly display the navigation bar, it's required to set the right css classes for the navigation bar,\n * otherwise it will look like a normal `ul` component.\n *\n * ### Syntax\n *\n * ```html\n * <aw-wizard-navigation-bar></aw-wizard-navigation-bar>\n * ```\n *\n * @author Marc Arndt\n */\n@Component({\n selector: 'aw-wizard-navigation-bar',\n templateUrl: 'wizard-navigation-bar.component.html',\n})\nexport class WizardNavigationBarComponent {\n /**\n * Constructor\n *\n * @param wizard The state the wizard currently resides in\n */\n constructor(public wizard: WizardBase) {\n }\n\n /**\n * Returns all [[WizardStep]]s contained in the wizard\n *\n * @returns An array containing all [[WizardStep]]s\n */\n get wizardSteps(): Array<WizardStep> {\n switch (this.wizard.navBarDirection) {\n case 'right-to-left':\n return this.wizard.wizardSteps.slice().reverse();\n case 'left-to-right':\n default:\n return this.wizard.wizardSteps;\n }\n }\n\n /**\n * Returns the number of wizard steps, that need to be displaced in the navigation bar\n *\n * @returns The number of wizard steps to be displayed\n */\n get numberOfWizardSteps(): number {\n return this.wizard.wizardSteps.length;\n }\n\n /**\n * Checks, whether a [[WizardStep]] can be marked as `current` in the navigation bar\n *\n * @param wizardStep The wizard step to be checked\n * @returns True if the step can be marked as `current`\n */\n public isCurrent(wizardStep: WizardStep): boolean {\n return wizardStep.selected;\n }\n\n /**\n * Checks, whether a [[WizardStep]] can be marked as `editing` in the navigation bar\n *\n * @param wizardStep The wizard step to be checked\n * @returns True if the step can be marked as `editing`\n */\n public isEditing(wizardStep: WizardStep): boolean {\n return wizardStep.editing;\n }\n\n /**\n * Checks, whether a [[WizardStep]] can be marked as `done` in the navigation bar\n *\n * @param wizardStep The wizard step to be checked\n * @returns True if the step can be marked as `done`\n */\n public isDone(wizardStep: WizardStep): boolean {\n return wizardStep.completed;\n }\n\n /**\n * Checks, whether a [[WizardStep]] can be marked as `optional` in the navigation bar\n *\n * @param wizardStep The wizard step to be checked\n * @returns True if the step can be marked as `optional`\n */\n public isOptional(wizardStep: WizardStep): boolean {\n return wizardStep.optional;\n }\n\n /**\n * Checks, whether a [[WizardStep]] can be marked as `completed` in the navigation bar.\n *\n * The `completed` class is only applied to completion steps.\n *\n * @param wizardStep The wizard step to be checked\n * @returns True if the step can be marked as `completed`\n */\n public isCompleted(wizardStep: WizardStep): boolean {\n return wizardStep instanceof WizardCompletionStep && this.wizard.completed;\n }\n\n /**\n * Checks, whether a [[WizardStep]] can be marked as `navigable` in the navigation bar.\n * A wizard step can be navigated to if:\n * - the step is currently not selected\n * - the navigation bar isn't disabled\n * - the navigation mode allows navigation to the step\n *\n * @param wizardStep The wizard step to be checked\n * @returns True if the step can be marked as navigable\n */\n public isNavigable(wizardStep: WizardStep): boolean {\n return !wizardStep.selected && !this.wizard.disableNavigationBar &&\n this.wizard.isNavigable(this.wizard.getIndexOfStep(wizardStep));\n }\n}\n","<ul class=\"steps-indicator steps-{{numberOfWizardSteps}}\">\n <li [attr.id]=\"step.stepId\" *ngFor=\"let step of wizardSteps\" [ngClass]=\"{\n 'current': isCurrent(step),\n 'editing': isEditing(step),\n 'done': isDone(step),\n 'optional': isOptional(step),\n 'completed': isCompleted(step),\n 'navigable': isNavigable(step)\n }\">\n <a [awGoToStep]=\"step\">\n <div class=\"label\">\n <ng-container *ngIf=\"step.stepTitleTemplate\" [ngTemplateOutlet]=\"step.stepTitleTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{wizardStep: step}\"></ng-container>\n <ng-container *ngIf=\"!step.stepTitleTemplate\">{{step.stepTitle}}</ng-container>\n </div>\n <div class=\"step-indicator\"\n [ngStyle]=\"{ 'font-family': step.stepSymbolTemplate ? '' : step.navigationSymbol.fontFamily }\">\n <ng-container *ngIf=\"step.stepSymbolTemplate\" [ngTemplateOutlet]=\"step.stepSymbolTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{wizardStep: step}\"></ng-container>\n <ng-container *ngIf=\"!step.stepSymbolTemplate\">{{step.navigationSymbol.symbol}}</ng-container>\n </div>\n </a>\n </li>\n</ul>\n","import {Component, forwardRef} from '@angular/core';\nimport {WizardStep} from '../util/wizard-step.interface';\n\n/**\n * The `aw-wizard-step` component is used to define a normal step inside a wizard.\n *\n * ### Syntax\n *\n * With `stepTitle` and `navigationSymbol` inputs:\n *\n * ```html\n * <aw-wizard-step [stepTitle]=\"step title\" [navigationSymbol]=\"{ symbol: 'symbol', fontFamily: 'font-family' }\"\n * [canExit]=\"deciding function\" (stepEnter)=\"enter function\" (stepExit)=\"exit function\">\n * ...\n * </aw-wizard-step>\n * ```\n *\n * With `awWizardStepTitle` and `awWizardStepSymbol` directives:\n *\n * ```html\n * <aw-wizard-step\"\n * [canExit]=\"deciding function\" (stepEnter)=\"enter function\" (stepExit)=\"exit function\">\n * <ng-template awWizardStepTitle>\n * step title\n * </ng-template>\n * <ng-template awWizardStepSymbol>\n * symbol\n * </ng-template>\n * ...\n * </aw-wizard-step>\n * ```\n *\n * ### Example\n *\n * With `stepTitle` and `navigationSymbol` inputs:\n *\n * ```html\n * <aw-wizard-step stepTitle=\"Address information\" [navigationSymbol]=\"{ symbol: '', fontFamily: 'FontAwesome' }\">\n * ...\n * </aw-wizard-step>\n * ```\n *\n * With `awWizardStepTitle` and `awWizardStepSymbol` directives:\n *\n * ```html\n * <aw-wizard-step>\n * <ng-template awWizardStepTitle>\n * Address information\n * </ng-template>\n * <ng-template awWizardStepSymbol>\n * <i class=\"fa fa-taxi\"></i>\n * </ng-template>\n * </aw-wizard-step>\n * ```\n *\n * @author Marc Arndt\n */\n@Component({\n selector: 'aw-wizard-step',\n templateUrl: 'wizard-step.component.html',\n providers: [\n {provide: WizardStep, useExisting: forwardRef(() => WizardStepComponent)}\n ]\n})\nexport class WizardStepComponent extends WizardStep {\n}\n","<ng-content></ng-content>\n","/**\n * The direction in which a step transition was made\n *\n * @author Marc Arndt\n */\n\n/**\n * This enum contains the different possible moving directions in which a wizard can be traversed\n *\n * @author Marc Arndt\n */\nexport enum MovingDirection {\n /**\n * A forward step transition\n */\n Forwards,\n /**\n * A backward step transition\n */\n Backwards,\n /**\n * No step transition was done\n */\n Stay\n}\n","import {EventEmitter} from '@angular/core';\nimport {MovingDirection} from '../util/moving-direction.enum';\nimport {NavigationMode} from './navigation-mode.interface';\nimport {WizardComponent} from '../components/wizard.component';\n\n/**\n * Base implementation of [[NavigationMode]]\n *\n * Note: Built-in [[NavigationMode]] classes should be stateless, allowing the library user to easily create\n * an instance of a particular [[NavigationMode]] class and pass it to `<aw-wizard [navigationMode]=\"...\">`.\n *\n * @author Marc Arndt\n */\nexport abstract class BaseNavigationMode implements NavigationMode {\n\n /**\n * Checks, whether a wizard step, as defined by the given destination index, can be transitioned to.\n *\n * This method controls navigation by [[goToStep]], [[goToPreviousStep]], and [[goToNextStep]] directives.\n * Navigation by navigation bar is governed by [[isNavigable]].\n *\n * In this implementation, a destination wizard step can be entered if:\n * - it exists\n * - the current step can be exited in the direction of the destination step\n * - the destination step can be entered in the direction from the current step\n *\n * Subclasses can impose additional restrictions, see [[canTransitionToStep]].\n *\n * @param wizard The wizard component to operate on\n * @param destinationIndex The index of the destination step\n * @returns A [[Promise]] containing `true`, if the destination step can be transitioned to and `false` otherwise\n */\n public canGoToStep(wizard: WizardComponent, destinationIndex: number): Promise<boolean> {\n const hasStep = wizard.hasStep(destinationIndex);\n\n const movingDirection = wizard.getMovingDirection(destinationIndex);\n\n const canExitCurrentStep = (previous: boolean) => {\n return previous && wizard.currentStep.canExitStep(movingDirection);\n };\n\n const canEnterDestinationStep = (previous: boolean) => {\n return previous && wizard.getStepAtIndex(destinationIndex).canEnterStep(movingDirection);\n };\n\n const canTransitionToStep = (previous: boolean) => {\n return previous && this.canTransitionToStep(wizard, destinationIndex);\n };\n\n return Promise.resolve(hasStep)\n .then(canTransitionToStep)\n // Apply user-defined checks at the end. They can involve user interaction\n // which is better to be avoided if navigation mode does not actually allow the transition\n // (`canTransitionToStep` returns `false`).\n .then(canExitCurrentStep)\n .then(canEnterDestinationStep);\n }\n\n /**\n * Imposes additional restrictions for `canGoToStep` in current navigation mode.\n *\n * The base implementation allows transition iff the given step is navigable from the navigation bar (see `isNavigable`).\n * However, in some navigation modes `canTransitionToStep` can be more relaxed to allow navigation to certain steps\n * by previous/next buttons, but not using the navigation bar.\n *\n * @param wizard The wizard component to operate on\n * @param destinationIndex The index of the destination step\n * @returns `true`, if the destination step can be transitioned to and `false` otherwise\n */\n protected canTransitionToStep(wizard: WizardComponent, destinationIndex: number): boolean {\n return this.isNavigable(wizard, destinationIndex);\n }\n\n /**\n * Tries to transition to the wizard step, as denoted by the given destination index.\n *\n * When entering the destination step, the following actions are done:\n * - the old current step is set as completed\n * - the old current step is set as unselected\n * - the old current step is exited\n * - the destination step is set as selected\n * - the destination step is entered\n *\n * When the destination step couldn't be entered, the following actions are done:\n * - the current step is exited and entered in the direction `MovingDirection.Stay`\n *\n * @param wizard The wizard component to operate on\n * @param destinationIndex The index of the destination wizard step, which should be entered\n * @param preFinalize An event emitter, to be called before the step has been transitioned\n * @param postFinalize An event emitter, to be called after the step has been transitioned\n */\n public goToStep(\n wizard: WizardComponent,\n destinationIndex: number,\n preFinalize?: EventEmitter<void>,\n postFinalize?: EventEmitter<void>): void {\n\n this.canGoToStep(wizard, destinationIndex).then(navigationAllowed => {\n if (navigationAllowed) {\n // the current step can be exited in the given direction\n const movingDirection: MovingDirection = wizard.getMovingDirection(destinationIndex);\n\n /* istanbul ignore if */\n if (preFinalize) {\n preFinalize.emit();\n }\n\n // leave current step\n wizard.currentStep.completed = true;\n wizard.currentStep.exit(movingDirection);\n wizard.currentStep.editing = false;\n wizard.currentStep.selected = false;\n\n this.transition(wizard, destinationIndex);\n\n // remember if the next step is already completed before entering it to properly set `editing` flag\n const wasCompleted = wizard.completed || wizard.currentStep.completed;\n\n // go to next step\n wizard.currentStep.enter(movingDirection);\n wizard.currentStep.selected = true;\n if (wasCompleted) {\n wizard.currentStep.editing = true;\n }\n\n /* istanbul ignore if */\n if (postFinalize) {\n postFinalize.emit();\n }\n } else {\n // if the current step can't be left, reenter the current step\n wizard.currentStep.exit(MovingDirection.Stay);\n wizard.currentStep.enter(MovingDirection.Stay);\n }\n });\n }\n\n /**\n * Transitions the wizard to the given step index.\n *\n * Can perform additional actions in particular navigation mode implementations.\n *\n * @param wizard The wizard component to operate on\n * @param destinationIndex The index of the destination wizard step\n */\n protected transition(wizard: WizardComponent, destinationIndex: number): void {\n wizard.currentStepIndex = destinationIndex;\n }\n\n /**\n * @inheritDoc\n */\n public abstract isNavigable(WizardComponent: WizardComponent, destinationIndex: number): boolean;\n\n /**\n * Resets the state of this wizard.\n *\n * A reset transitions the wizard automatically to the first step and sets all steps as incomplete.\n * In addition the whole wizard is set as incomplete.\n *\n * @param wizard The wizard component to operate on\n */\n public reset(wizard: WizardComponent): void {\n this.ensureCanReset(wizard);\n\n // reset the step internal state\n wizard.wizardSteps.forEach(step => {\n step.completed = step.initiallyCompleted;\n step.selected = false;\n step.editing = false;\n });\n\n // set the first step as the current step\n wizard.currentStepIndex = wizard.defaultStepIndex;\n wizard.currentStep.selected = true;\n wizard.currentStep.enter(MovingDirection.Forwards);\n }\n\n /**\n * Checks if wizard configuration allows to perform reset.\n *\n * A check failure is indicated by throwing an `Error` with the message discribing the discovered misconfiguration issue.\n *\n * Can include additional checks in particular navigation mode implementations.\n *\n * @param wizard The wizard component to operate on\n * @throws An `Error` is thrown, if a micconfiguration issue is discovered.\n */\n protected ensureCanReset(wizard: WizardComponent): void {\n // the wizard doesn't contain a step with the default step index\n if (!wizard.hasStep(wizard.defaultStepIndex)) {\n throw new Error(`The wizard doesn't contain a step with index ${wizard.defaultStepIndex}`);\n }\n }\n}\n","import {BaseNavigationMode} from './base-navigation-mode.interface';\nimport {WizardComponent} from '../components/wizard.component';\nimport {WizardCompletionStep} from '../util/wizard-completion-step.interface';\n\n/**\n * The default navigation mode used by [[WizardComponent]] and [[NavigationModeDirective]].\n *\n * It is parameterized with two navigation policies passed to constructor:\n *\n * - [[navigateBackward]] policy controls whether wizard steps before the current step are navigable:\n *\n * - `\"deny\"` -- the steps are not navigable\n * - `\"allow\"` -- the steps are navigable\n * - If the corresponding constructor argument is omitted or is `null` or `undefined`,\n * then the default value is applied which is `\"deny\"`\n *\n * - [[navigateForward]] policy controls whether wizard steps after the current step are navigable:\n *\n * - `\"deny\"` -- the steps are not navigable\n * - `\"allow\"` -- the steps are navigable\n * - `\"visited\"` -- a step is navigable iff it was already visited before\n * - If the corresponding constructor argument is omitted or is `null` or `undefined`,\n * then the default value is applied which is `\"allow\"`\n */\nexport class ConfigurableNavigationMode extends BaseNavigationMode {\n\n /**\n * Constructor\n *\n * @param navigateBackward Controls whether wizard steps before the current step are navigable\n * @param navigateForward Controls whether wizard steps before the current step are navigable\n */\n constructor(\n private navigateBackward: 'allow'|'deny'|null = null,\n private navigateForward: 'allow'|'deny'|'visited'|null = null,\n ) {\n super();\n this.navigateBackward = this.navigateBackward || 'allow';\n this.navigateForward = this.navigateForward || 'deny';\n }\n\n /**\n * @inheritDoc\n */\n protected canTransitionToStep(wizard: WizardComponent, destinationIndex: number): boolean {\n // if the destination step can be navigated to using the navigation bar,\n // it should be accessible with [goToStep] as well\n if (this.isNavigable(wizard, destinationIndex)) {\n return true;\n }\n\n // navigation with [goToStep] is permitted if all previous steps\n // to the destination step have been completed or are optional\n return wizard.wizardSteps\n .filter((step, index) => index < destinationIndex && index !== wizard.currentStepIndex)\n .every(step => step.completed || step.optional);\n }\n\n /**\n * @inheritDoc\n */\n protected transition(wizard: WizardComponent, destinationIndex: number): void {\n if (this.navigateForward === 'deny') {\n // set all steps after the destination step to incomplete\n wizard.wizardSteps\n .filter((step, index) => wizard.currentStepIndex > destinationIndex && index > destinationIndex)\n .forEach(step => step.completed = false);\n }\n\n super.transition(wizard, destinationIndex);\n }\n\n /**\n * @inheritDoc\n */\n public isNavigable(wizard: WizardComponent, destinationIndex: number): boolean {\n // Check if the destination step can be navigated to\n const destinationStep = wizard.getStepAtIndex(destinationIndex);\n if (destinationStep instanceof WizardCompletionStep) {\n // A completion step can only be entered, if all previous steps have been completed, are optional, or selected\n const previousStepsCompleted = wizard.wizardSteps\n .filter((step, index) => index < destinationIndex)\n .every(step => step.completed || step.optional || step.selected);\n if (!previousStepsCompleted) {\n return false;\n }\n }\n\n // Apply navigation pocicies\n if (destinationIndex < wizard.currentStepIndex) {\n // If the destination step is before current, apply the `navigateBackward` policy\n switch (this.navigateBackward) {\n case 'allow': return true;\n case 'deny': return false;\n default:\n throw new Error(`Invalid value for navigateBackward: ${this.navigateBackward}`);\n }\n } else if (destinationIndex > wizard.currentStepIndex) {\n // If the destination step is after current, apply the `navigateForward` policy\n switch (this.navigateForward) {\n case 'allow': return true;\n case 'deny': return false;\n case 'visited': return destinationStep.completed;\n default:\n throw new Error(`Invalid value for navigateForward: ${this.navigateForward}`);\n }\n } else {\n // Re-entering the current step is not allowed\n return false;\n }\n }\n\n /**\n * @inheritDoc\n */\n protected ensureCanReset(wizard: WizardComponent): void {\n super.ensureCanReset(wizard);\n\n // the default step is a completion step and the wizard contains more than one step\n const defaultWizardStep = wizard.getStepAtIndex(wizard.defaultStepIndex);\n const defaultCompletionStep = defaultWizardStep instanceof WizardCompletionStep;\n if (defaultCompletionStep && wizard.wizardSteps.length !== 1) {\n throw new Error(`The default step index ${wizard.defaultStepIndex} references a completion step`);\n }\n }\n}\n","import {\n AfterContentInit,\n Component,\n ContentChildren,\n HostBinding,\n Input,\n QueryList,\n EventEmitter\n} from '@angular/core';\nimport {NavigationMode} from '../navigation/navigation-mode.interface';\nimport {WizardStep} from '../util/wizard-step.interface';\nimport {MovingDirection} from '../util/moving-direction.enum';\nimport {ConfigurableNavigationMode} from '../navigation/configurable-navigation-mode';\nimport { WizardBase } from '../util/wizard.interface';\n\n/**\n * The `aw-wizard` component defines the root component of a wizard.\n * Through the setting of input parameters for the `aw-wizard` component it's possible to change the location and size\n * of its navigation bar.\n *\n * ### Syntax\n * ```html\n * <aw-wizard [navBarLocation]=\"location of navigation bar\" [navBarLayout]=\"layout of navigation bar\">\n * ...\n * </aw-wizard>\n * ```\n *\n * ### Example\n *\n * Without completion step:\n *\n * ```html\n * <aw-wizard navBarLocation=\"top\" navBarLayout=\"small\">\n * <aw-wizard-step>...</aw-wizard-step>\n * <aw-wizard-step>...</aw-wizard-step>\n * </aw-wizard>\n * ```\n *\n * With completion step:\n *\n * ```html\n * <aw-wizard navBarLocation=\"top\" navBarLayout=\"small\">\n * <aw-wizard-step>...</aw-wizard-step>\n * <aw-wizard-step>...</aw-wizard-step>\n * <aw-wizard-completion-step>...</aw-wizard-completion-step>\n * </aw-wizard>\n * ```\n *\n * @author Marc Arndt\n */\n@Component({\n selector: 'aw-wizard',\n templateUrl: 'wizard.component.html',\n providers: [\n { provide: WizardBase, useExisting: WizardComponent }\n ]\n})\nexport class WizardComponent implements WizardBase, AfterContentInit {\n /**\n * A QueryList containing all [[WizardStep]]s inside this wizard\n */\n @ContentChildren(WizardStep, { descendants: true })\n public wizardStepsQueryList: QueryList<WizardStep>;\n\n /**\n * The location of the navigation bar inside the wizard.\n * This location can be either top, bottom, left or right\n */\n @Input()\n public navBarLocation = 'top';\n\n /**\n * The layout of the navigation bar inside the wizard.\n * The layout can be either small, large-filled, large-empty or large-symbols\n */\n @Input()\n public navBarLayout = 'small';\n\n /**\n * The direction in which the steps inside the navigation bar should be shown.\n * The direction can be either `left-to-right` or `right-to-left`\n */\n @Input()\n public navBarDirection = 'left-to-right';\n\n /**\n * The initially selected step, represented by its index\n * Beware: This initial default is only used if no wizard step has been enhanced with the `selected` directive\n */\n @Input()\n public get defaultStepIndex(): number {\n // This value can be either:\n // - the index of a wizard step with a `selected` directive, or\n // - the default step index, set in the [[WizardComponent]]\n\n const foundDefaultStep = this.wizardSteps.find(step => step.defaultSelected);\n\n if (foundDefaultStep) {\n return this.getIndexOfStep(foundDefaultStep);\n } else {\n return this._defaultStepIndex;\n }\n }\n public set defaultStepIndex(defaultStepIndex: number) {\n this._defaultStepIndex = defaultStepIndex;\n }\n private _defaultStepIndex = 0;\n\n /**\n * True, if the navigation bar shouldn't be used for navigating\n */\n @Input()\n public disableNavigationBar = false;\n\n /**\n * The navigation mode used to navigate inside the wizard\n *\n * For outside access, use the [[navigation]] getter.\n */\n private _navigation: NavigationMode = new ConfigurableNavigationMode();\n\n /**\n * An array representation of all wizard steps belonging to this model\n *\n * For outside access, use the [[wizardSteps]] getter.\n */\n private _wizardSteps: WizardStep[] = [];\n\n /**\n * The index of the currently visible and selected step inside the wizardSteps QueryList.\n * If this wizard contains no steps, currentStepIndex is -1\n *\n * Note: Do not modify this field directly. Instead, use navigation methods:\n * [[goToStep]], [[goToPreviousStep]], [[goToNextStep]].\n */\n public currentStepIndex = -1;\n\n /**\n * Constructor\n */\n constructor() {\n }\n\n /**\n * Returns true if this wizard uses a horizontal orientation.\n * The wizard uses a horizontal orientation, iff the navigation bar is shown at the top or bottom of this wizard\n *\n * @returns True if this wizard uses a horizontal orientation\n */\n @HostBinding('class.horizontal')\n public get horizontalOrientation(): boolean {\n return this.navBarLocation === 'top' || this.navBarLocation === 'bottom';\n }\n\n /**\n * Returns true if this wizard uses a vertical orientation.\n * The wizard uses a vertical orientation, iff the navigation bar is shown at the left or right of this wizard\n *\n * @returns True if this wizard uses a vertical orientation\n */\n @HostBinding('class.vertical')\n public get verticalOrientation(): boolean {\n return this.navBarLocation === 'left' || this.navBarLocation === 'right';\n }\n\n /**\n * Initialization work\n */\n public ngAfterContentInit(): void {\n // add a subscriber to the wizard steps QueryList to listen to changes in the DOM\n this.wizardStepsQueryList.changes.subscribe(changedWizardSteps => {\n this.updateWizardSteps(changedWizardSteps.toArray());\n });\n\n // initialize the model\n this.updateWizardSteps(this.wizardStepsQueryList.toArray());\n\n // finally reset the whole wizard component\n setTimeout(() => this.reset());\n }\n\n /**\n * The WizardStep object belonging to the currently visible and selected step.\n * The currentStep is always the currently selected wizard step.\n * The currentStep can be either completed, if it was visited earlier,\n * or not completed, if it is visited for the first time or its state is currently out of date.\n *\n * If this wizard contains no steps, currentStep is null\n */\n public get currentStep(): WizardStep {\n if (this.hasStep(this.currentStepIndex)) {\n return this.wizardSteps[this.currentStepIndex];\n } else {\n return null;\n }\n }\n\n /**\n * The completeness of the wizard.\n * If the wizard has been completed, i.e. all steps are either completed or optional, this value is true, otherwise it is false\n */\n public get completed(): boolean {\n return this.wizardSteps.every(step => step.completed || step.optional);\n }\n\n /**\n * An array representation of all wizard steps belonging to this model\n */\n public get wizardSteps(): WizardStep[] {\n return this._wizardSteps;\n }\n\n /**\n * Updates the wizard steps to the new array\n *\n * @param wizardSteps The updated wizard steps\n */\n private updateWizardSteps(wizardSteps: WizardStep[]): void {\n // the wizard is currently not in the initialization phase\n if (this.wizardSteps.length > 0 && this.currentStepIndex > -1) {\n this.currentStepIndex = wizardSteps.indexOf(this.wizardSteps[this.currentStepIndex]);\n }\n\n this._wizardSteps = wizardSteps;\n }\n\n /**\n * The navigation mode used to navigate inside the wizard\n */\n public get navigation(): NavigationMode {\n return this._navigation;\n }\n\n /**\n * Updates the navigation mode for this wizard component\n *\n * @param navigation The updated navigation mode\n */\n public set navigation(navigation: NavigationMode) {\n this._navigation = navigation;\n }\n\n /**\n * Checks if a given index `stepIndex` is inside the range of possible wizard steps inside this wizard\n *\n * @param stepIndex The to be checked index of a step inside this wizard\n * @returns True if the given `stepIndex` is contained inside this wizard, false otherwise\n */\n public hasStep(stepIndex: number): boolean {\n return this.wizardSteps.length > 0 && 0 <= stepIndex && stepIndex < this.wizardSteps.length;\n }\n\n /**\n * Checks if this wizard has a previous step, compared to the current step\n *\n * @returns True if this wizard has a previous step before the current step\n */\n public hasPreviousStep(): boolean {\n return this.hasStep(this.currentStepIndex - 1);\n }\n\n /**\n * Checks if this wizard has a next step, compared to the current step\n *\n * @returns True if