@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']
}] } });