@progress/kendo-angular-layout
Version: 
Kendo UI for Angular Layout Package - a collection of components to create professional application layoyts
367 lines (358 loc) • 15.3 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, Input, HostBinding, TemplateRef, NgZone, ElementRef, ViewChild } from '@angular/core';
import { validatePackage } from '@progress/kendo-licensing';
import { packageMetadata } from '../package-metadata';
import { isPresent } from '../common/util';
import { StepperService } from './stepper.service';
import { LocalizationService } from '@progress/kendo-angular-l10n';
import { checkCircleIcon, exclamationCircleIcon } from '@progress/kendo-svg-icons';
import { IconWrapperComponent } from '@progress/kendo-angular-icons';
import { NgIf, NgTemplateOutlet } from '@angular/common';
import * as i0 from "@angular/core";
import * as i1 from "./stepper.service";
import * as i2 from "@progress/kendo-angular-l10n";
/**
 * @hidden
 */
export class StepperStepComponent {
    service;
    localization;
    ngZone;
    step;
    index;
    current;
    type;
    successIcon;
    successSVGIcon;
    errorIcon;
    errorSVGIcon;
    svgIcon;
    indicatorTemplate;
    labelTemplate;
    stepTemplate;
    stepLink;
    isStepValid = undefined;
    shouldCheckValidity = undefined;
    checkCircleIcon = checkCircleIcon;
    exclamationCircleIcon = exclamationCircleIcon;
    subs;
    constructor(service, localization, ngZone) {
        this.service = service;
        this.localization = localization;
        this.ngZone = ngZone;
        validatePackage(packageMetadata);
        this.subs = this.service.focusedStepChange.subscribe(() => {
            this.onFocusedStepChange();
        });
        this.subs.add(this.service.triggerValidation.subscribe(() => {
            this.handleValidityChecks();
        }));
    }
    get errorStepClass() {
        if (isPresent(this.isStepValid)) {
            return !this.isStepValid;
        }
        return false;
    }
    get successStepClass() {
        if (isPresent(this.isStepValid)) {
            return this.isStepValid;
        }
        return false;
    }
    ngOnInit() {
        this.handleValidityChecks();
    }
    ngOnChanges(changes) {
        if (changes['current'] && !changes['current'].firstChange) {
            this.handleValidityChecks();
        }
    }
    ngOnDestroy() {
        if (this.subs) {
            this.subs.unsubscribe();
        }
    }
    onFocusedStepChange() {
        this.ngZone.runOutsideAngular(() => {
            if (this.index === this.service.focusedStep) {
                this.stepLink.nativeElement.focus();
            }
        });
    }
    onFocus() {
        this.service.focus(this.index);
    }
    get tabIndexAttr() {
        const active = this.service.focusedStep || this.service.currentStep;
        return this.index === active ? 0 : -1;
    }
    get indicatorIconClass() {
        if (this.step.icon && !this.step.iconClass) {
            return `${this.step.icon}`;
        }
        if (!this.step.icon && !this.step.iconClass && this.shouldCheckValidity) {
            return this.validationIconClasses;
        }
    }
    get customIndicatorIconClass() {
        if (this.step.iconClass) {
            return `${this.step.iconClass}`;
        }
        const renderCustomValidationIcon = !this.step.icon && !this.step.iconClass && this.shouldCheckValidity;
        if (renderCustomValidationIcon) {
            return this.customValidationIconClasses;
        }
    }
    get SVGIndicatorIcon() {
        if (this.step.svgIcon) {
            return this.step.svgIcon;
        }
        if (!this.step.svgIcon && this.shouldCheckValidity) {
            return this.validationSVGIcon;
        }
    }
    get validationIconClasses() {
        if (this.isStepValid) {
            return !this.successIcon ? 'check-circle' : '';
        }
        return !this.errorIcon ? 'exclamation-circle' : '';
    }
    get customValidationIconClasses() {
        if (this.isStepValid) {
            return this.successIcon ? this.successIcon : '';
        }
        return this.errorIcon ? this.errorIcon : '';
    }
    get validationSVGIcon() {
        if (this.isStepValid) {
            return this.successSVGIcon ? this.successSVGIcon : this.checkCircleIcon;
        }
        return this.errorSVGIcon ? this.errorSVGIcon : this.exclamationCircleIcon;
    }
    get showIndicatorIcon() {
        if (this.shouldCheckValidity) {
            return true;
        }
        if (this.step.icon || this.step.iconClass || this.step.svgIcon) {
            return true;
        }
        return false;
    }
    get showLabelIcon() {
        if (this.shouldCheckValidity) {
            if (this.type === 'label') {
                return true;
            }
            if (this.step.icon || this.step.iconClass) {
                return true;
            }
        }
        return false;
    }
    get showLabelText() {
        return this.type === 'label' || this.type === 'full';
    }
    get indicatorText() {
        const text = this.step.text;
        return text ? text : this.index + 1;
    }
    updateStepValidity() {
        if (typeof this.step.isValid === 'boolean') {
            return this.step.isValid;
        }
        if (typeof this.step.isValid === 'function') {
            return this.step.isValid(this.index);
        }
        return undefined;
    }
    get showIndicator() {
        return this.type === 'indicator' || this.type === 'full';
    }
    get showLabel() {
        if (this.type === 'label' || this.type === 'full') {
            return true;
        }
        return this.step.optional;
    }
    get optionalText() {
        return this.localization.get('optional');
    }
    get transitionDuration() {
        return this.service.owner.animationDuration;
    }
    _shouldCheckValidity() {
        if (isPresent(this.step.validate)) {
            if (typeof this.step.validate === 'boolean') {
                return this.step.validate;
            }
            if (typeof this.step.validate === 'function') {
                return this.step.validate(this.index);
            }
        }
        return isPresent(this.step.isValid) && this.index < this.current;
    }
    handleValidityChecks() {
        this.isStepValid = undefined;
        this.shouldCheckValidity = this._shouldCheckValidity();
        if (this.shouldCheckValidity) {
            this.isStepValid = this.updateStepValidity();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: StepperStepComponent, deps: [{ token: i1.StepperService }, { token: i2.LocalizationService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: StepperStepComponent, isStandalone: true, selector: "[kendoStepperStep]", inputs: { step: "step", index: "index", current: "current", type: "type", successIcon: "successIcon", successSVGIcon: "successSVGIcon", errorIcon: "errorIcon", errorSVGIcon: "errorSVGIcon", svgIcon: "svgIcon", indicatorTemplate: "indicatorTemplate", labelTemplate: "labelTemplate", stepTemplate: "stepTemplate" }, host: { properties: { "class.k-step-error": "this.errorStepClass", "class.k-step-success": "this.successStepClass" } }, viewQueries: [{ propertyName: "stepLink", first: true, predicate: ["stepLink"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
        <a href='#' class='k-step-link' #stepLink
            [attr.tabindex]='tabIndexAttr'
            [attr.title]='step.label'
            [attr.aria-disabled]='step.disabled'
            [attr.aria-current]='index === current ? "step" : null'
            (focus)='onFocus()'
        >
            <ng-template *ngIf='stepTemplate'
                [ngTemplateOutlet]='stepTemplate'
                [ngTemplateOutletContext]='{ $implicit: step, index: index }'>
            </ng-template>
            <ng-container *ngIf='!stepTemplate'>
                <span *ngIf='showIndicator'
                    class='k-step-indicator'
                    aria-hidden='true'
                    [style.transition-duration.ms]='transitionDuration'
                >
                    <ng-template *ngIf='indicatorTemplate'
                        [ngTemplateOutlet]='indicatorTemplate'
                        [ngTemplateOutletContext]='{ $implicit: step, index: index }'>
                    </ng-template>
                    <ng-container *ngIf='!indicatorTemplate'>
                        <kendo-icon-wrapper
                            *ngIf='showIndicatorIcon'
                            [name]='indicatorIconClass'
                            [customFontClass]='customIndicatorIconClass'
                            [svgIcon]='SVGIndicatorIcon'
                            innerCssClass='k-step-indicator-icon'
                        >
                        </kendo-icon-wrapper>
                        <span class='k-step-indicator-text' *ngIf='!showIndicatorIcon'>{{ indicatorText }}</span>
                    </ng-container>
                </span>
                <span class='k-step-label' *ngIf='showLabel'>
                    <ng-template *ngIf='labelTemplate'
                        [ngTemplateOutlet]='labelTemplate'
                        [ngTemplateOutletContext]='{ $implicit: step, index: index }'>
                    </ng-template>
                    <ng-container *ngIf='!labelTemplate'>
                        <span class='k-step-text' *ngIf='showLabelText'>{{ step.label }}</span>
                        <kendo-icon-wrapper
                            *ngIf='showLabelIcon'
                            aria-hidden='true'
                            [name]='validationIconClasses'
                            [customFontClass]='customValidationIconClasses'
                            [svgIcon]='validationSVGIcon'
                        >
                        </kendo-icon-wrapper>
                        <span class='k-step-label-optional' *ngIf='step.optional'>({{optionalText}})</span>
                    </ng-container>
                </span>
            </ng-container>
        </a>
    `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: StepperStepComponent, decorators: [{
            type: Component,
            args: [{
                    // eslint-disable-next-line @angular-eslint/component-selector
                    selector: '[kendoStepperStep]',
                    template: `
        <a href='#' class='k-step-link' #stepLink
            [attr.tabindex]='tabIndexAttr'
            [attr.title]='step.label'
            [attr.aria-disabled]='step.disabled'
            [attr.aria-current]='index === current ? "step" : null'
            (focus)='onFocus()'
        >
            <ng-template *ngIf='stepTemplate'
                [ngTemplateOutlet]='stepTemplate'
                [ngTemplateOutletContext]='{ $implicit: step, index: index }'>
            </ng-template>
            <ng-container *ngIf='!stepTemplate'>
                <span *ngIf='showIndicator'
                    class='k-step-indicator'
                    aria-hidden='true'
                    [style.transition-duration.ms]='transitionDuration'
                >
                    <ng-template *ngIf='indicatorTemplate'
                        [ngTemplateOutlet]='indicatorTemplate'
                        [ngTemplateOutletContext]='{ $implicit: step, index: index }'>
                    </ng-template>
                    <ng-container *ngIf='!indicatorTemplate'>
                        <kendo-icon-wrapper
                            *ngIf='showIndicatorIcon'
                            [name]='indicatorIconClass'
                            [customFontClass]='customIndicatorIconClass'
                            [svgIcon]='SVGIndicatorIcon'
                            innerCssClass='k-step-indicator-icon'
                        >
                        </kendo-icon-wrapper>
                        <span class='k-step-indicator-text' *ngIf='!showIndicatorIcon'>{{ indicatorText }}</span>
                    </ng-container>
                </span>
                <span class='k-step-label' *ngIf='showLabel'>
                    <ng-template *ngIf='labelTemplate'
                        [ngTemplateOutlet]='labelTemplate'
                        [ngTemplateOutletContext]='{ $implicit: step, index: index }'>
                    </ng-template>
                    <ng-container *ngIf='!labelTemplate'>
                        <span class='k-step-text' *ngIf='showLabelText'>{{ step.label }}</span>
                        <kendo-icon-wrapper
                            *ngIf='showLabelIcon'
                            aria-hidden='true'
                            [name]='validationIconClasses'
                            [customFontClass]='customValidationIconClasses'
                            [svgIcon]='validationSVGIcon'
                        >
                        </kendo-icon-wrapper>
                        <span class='k-step-label-optional' *ngIf='step.optional'>({{optionalText}})</span>
                    </ng-container>
                </span>
            </ng-container>
        </a>
    `,
                    standalone: true,
                    imports: [NgIf, NgTemplateOutlet, IconWrapperComponent]
                }]
        }], ctorParameters: function () { return [{ type: i1.StepperService }, { type: i2.LocalizationService }, { type: i0.NgZone }]; }, propDecorators: { step: [{
                type: Input
            }], index: [{
                type: Input
            }], current: [{
                type: Input
            }], type: [{
                type: Input
            }], successIcon: [{
                type: Input
            }], successSVGIcon: [{
                type: Input
            }], errorIcon: [{
                type: Input
            }], errorSVGIcon: [{
                type: Input
            }], svgIcon: [{
                type: Input
            }], indicatorTemplate: [{
                type: Input
            }], labelTemplate: [{
                type: Input
            }], stepTemplate: [{
                type: Input
            }], stepLink: [{
                type: ViewChild,
                args: ['stepLink', { static: true }]
            }], errorStepClass: [{
                type: HostBinding,
                args: ['class.k-step-error']
            }], successStepClass: [{
                type: HostBinding,
                args: ['class.k-step-success']
            }] } });