UNPKG

@progress/kendo-angular-layout

Version:

Kendo UI for Angular Layout Package - a collection of components to create professional application layoyts

427 lines (424 loc) 16.8 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Component, HostBinding, Input, Output, EventEmitter, ContentChild, Renderer2, ElementRef } from '@angular/core'; import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n'; import { StepperStepTemplateDirective } from './template-directives/step-template.directive'; import { StepperLabelTemplateDirective } from './template-directives/label-template.directive'; import { isPresent } from '../common/util'; import { StepperIndicatorTemplateDirective } from './template-directives/indicator-template.directive'; import { StepperService } from './stepper.service'; import { ProgressBarComponent } from '@progress/kendo-angular-progressbar'; import { NgStyle, NgIf } from '@angular/common'; import { StepperListComponent } from './list.component'; import { LocalizedStepperMessagesDirective } from './localization/localized-messages.directive'; import * as i0 from "@angular/core"; import * as i1 from "@progress/kendo-angular-l10n"; import * as i2 from "./stepper.service"; const DEFAULT_ANIMATION_DURATION = 400; /** * Represents the [Kendo UI Stepper component for Angular]({% slug overview_stepper %}). * * @example * ```ts-preview * _@Component({ * selector: 'my-app', * template: ` * <kendo-stepper [steps]="steps"> * </kendo-stepper> * ` * }) * class AppComponent { * public steps: Array<StepperStep> = [ * { label: 'Step One' }, { label: 'Step Two' }, { label: 'Step Three' } * ]; * } * ``` */ export class StepperComponent { renderer; elem; localization; stepperService; hostClasses = true; get linearClass() { return this.linear; } ariaRole = 'navigation'; direction; displayStyle = 'grid'; /** * Specifies the type of the steps in the Stepper. * * The possible values are: * * (Default) `indicator` * * `label` * * `full` */ stepType = 'indicator'; /** * Specifies the linear flow of the Stepper. * * @default true */ linear = true; /** * Specifies the orientation of the Stepper * ([see example]({% slug orientation_stepper %})). * * The possible values are: * * (Default) `horizontal` * * `vertical` */ orientation = 'horizontal'; /** * The index of the current step. */ set currentStep(value) { this.stepperService.currentStep = value; } get currentStep() { return this.stepperService.currentStep; } /** * The collection of steps that will be rendered in the Stepper. * ([see example]({% slug step_appearance_stepper %})) */ set steps(steps) { if (isPresent(steps) && steps.length > 0) { this._steps = steps; } } get steps() { return this._steps; } /** * Defines an SVG icon to be rendered inside the step indicator instead of the default numeric or text content. * The input can take either an [existing Kendo SVG icon](slug:svgicon_list) or a custom one. */ set svgIcon(icon) { this._svgIcon = icon; } get svgIcon() { return this._svgIcon; } /** * Defines an SVGIcon to be rendered for the success icon. * The input can take either an [existing Kendo SVG icon](slug:svgicon_list) or a custom one. */ successSVGIcon; /** * Defines an SVGIcon to be rendered for the error icon. * The input can take either an [existing Kendo SVG icon](slug:svgicon_list) or a custom one. */ errorSVGIcon; /** * Specifies a custom icon that will be rendered inside the step * for valid previous steps. */ successIcon; /** * Specifies a custom icon that will be rendered inside the step * for invalid previous steps. */ errorIcon; /** * Specifies the duration of the progress indicator animation in milliseconds. Defaults to `400ms`. * * The possible values are: * * Boolean * * (Default) `true` * * false * * Number */ animation = true; /** * Fires when a step is about to be activated. This event is preventable. */ activate = new EventEmitter(); /** * Fires when the `currentStep` property of the component was updated. * Used to provide a two-way binding for the `currentStep` property. */ currentStepChange = new EventEmitter(); /** * @hidden */ stepTemplate; /** * @hidden */ labelTemplate; /** * @hidden */ indicatorTemplate; dynamicRTLSubscription; _steps = []; _successSVGIcon; _errorSVGIcon; _svgIcon; constructor(renderer, elem, localization, stepperService) { this.renderer = renderer; this.elem = elem; this.localization = localization; this.stepperService = stepperService; this.dynamicRTLSubscription = this.localization.changes.subscribe(({ rtl }) => { this.direction = rtl ? 'rtl' : 'ltr'; }); this.stepperService.owner = this; } ngOnInit() { this.applyHostStyling(); } ngOnChanges(changes) { if (changes['steps'] && !changes['steps'].firstChange) { this.applyHostStyling(); } if (changes['orientation']) { this.resetHostStyling(); this.applyHostStyling(); } } ngOnDestroy() { if (this.dynamicRTLSubscription) { this.dynamicRTLSubscription.unsubscribe(); } } /** * Manually triggers the validity check configured by the [isValid]({% slug api_layout_stepperstep %}#toc-isvalid) property of the steps ([see example]({% slug step_validation_stepper %}#toc-triggering-the-validation)). * * Steps that have their [validate]({% slug api_layout_stepperstep %}#toc-validate) property set to `false`, will not be validated. */ validateSteps() { this.stepperService.validateSteps(); } applyHostStyling() { const stepFramesStyle = this.orientation === 'horizontal' ? 'grid-template-columns' : 'grid-template-rows'; const stepFramesValue = `repeat(${this.steps.length * 2}, 1fr)`; this.renderer.setStyle(this.elem.nativeElement, stepFramesStyle, stepFramesValue); } resetHostStyling() { this.renderer.removeStyle(this.elem.nativeElement, 'grid-template-columns'); this.renderer.removeStyle(this.elem.nativeElement, 'grid-template-rows'); } /** * @hidden */ get progressAnimation() { return { duration: this.animationDuration }; } /** * @hidden */ get animationDuration() { if (typeof this.animation === 'number') { return this.animation; } if (typeof this.animation === 'boolean' && this.animation) { return DEFAULT_ANIMATION_DURATION; } return 0; } /** * @hidden */ get stepsListStyling() { if (this.orientation === 'horizontal') { return { 'grid-column-start': 1, 'grid-column-end': -1 }; } return { 'grid-row-start': 1, 'grid-row-end': -1 }; } /** * @hidden */ get progressBarStyling() { if (this.orientation === 'horizontal') { return { 'grid-column-start': 2, 'grid-column-end': this.steps.length * 2 }; } return { 'grid-row-start': 2, 'grid-row-end': this.steps.length * 2 }; } /** * @hidden */ onListKeydown(e) { this.stepperService.keydown(e); } /** * @hidden */ onListClick(e) { if (e.stepIdx === e.currentStep) { this.stepperService.focus(e.stepIdx); return; } if (e.linear && this.stepperService.isPrevOrNextStep(e.stepIdx) === false) { return; } this.stepperService.onActivate(e.stepIdx, e.originalEvent); } /** * @hidden */ get isHorizontal() { return this.orientation === 'horizontal'; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: StepperComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.LocalizationService }, { token: i2.StepperService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: StepperComponent, isStandalone: true, selector: "kendo-stepper", inputs: { stepType: "stepType", linear: "linear", orientation: "orientation", currentStep: "currentStep", steps: "steps", svgIcon: "svgIcon", successSVGIcon: "successSVGIcon", errorSVGIcon: "errorSVGIcon", successIcon: "successIcon", errorIcon: "errorIcon", animation: "animation" }, outputs: { activate: "activate", currentStepChange: "currentStepChange" }, host: { properties: { "class.k-stepper": "this.hostClasses", "class.k-stepper-linear": "this.linearClass", "attr.role": "this.ariaRole", "attr.dir": "this.direction", "style.display": "this.displayStyle" } }, providers: [ LocalizationService, StepperService, { provide: L10N_PREFIX, useValue: 'kendo.stepper' } ], queries: [{ propertyName: "stepTemplate", first: true, predicate: StepperStepTemplateDirective, descendants: true }, { propertyName: "labelTemplate", first: true, predicate: StepperLabelTemplateDirective, descendants: true }, { propertyName: "indicatorTemplate", first: true, predicate: StepperIndicatorTemplateDirective, descendants: true }], exportAs: ["kendoStepper"], usesOnChanges: true, ngImport: i0, template: ` <ng-container kendoStepperLocalizedMessages i18n-optional="kendo.stepper.optional|The text for the optional segment of the step label" optional="Optional" > </ng-container> <ol kendoStepperList [stepType]='stepType' [linear]='linear' [orientation]='orientation' [steps]='steps' [currentStep]='currentStep' [successIcon]='successIcon' [successSVGIcon]='successSVGIcon' [errorIcon]='errorIcon' [errorSVGIcon]='errorSVGIcon' [svgIcon]="svgIcon" [indicatorTemplate]='indicatorTemplate?.templateRef' [labelTemplate]='labelTemplate?.templateRef' [stepTemplate]='stepTemplate?.templateRef' class='k-step-list' [class.k-step-list-horizontal]='isHorizontal' [class.k-step-list-vertical]='!isHorizontal' [ngStyle]='stepsListStyling' (listKeydown)="onListKeydown($event)" (listClick)="onListClick($event)"> </ol> <kendo-progressbar *ngIf='steps.length > 0' [attr.aria-hidden]='true' [animation]='progressAnimation' [max]='steps.length - 1' [label]='{position: "start", visible: false}' [orientation]='orientation' [reverse]='!isHorizontal' [value]='currentStep' [ngStyle]='progressBarStyling'> </kendo-progressbar> `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedStepperMessagesDirective, selector: "\n [kendoStepperLocalizedMessages]\n " }, { kind: "component", type: StepperListComponent, selector: "[kendoStepperList]", inputs: ["linear", "stepType", "orientation", "currentStep", "steps", "successIcon", "successSVGIcon", "errorIcon", "errorSVGIcon", "svgIcon", "indicatorTemplate", "labelTemplate", "stepTemplate"], outputs: ["listKeydown", "listClick"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ProgressBarComponent, selector: "kendo-progressbar", inputs: ["label", "progressCssStyle", "progressCssClass", "emptyCssStyle", "emptyCssClass", "animation"], outputs: ["animationEnd"], exportAs: ["kendoProgressBar"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: StepperComponent, decorators: [{ type: Component, args: [{ exportAs: 'kendoStepper', providers: [ LocalizationService, StepperService, { provide: L10N_PREFIX, useValue: 'kendo.stepper' } ], selector: 'kendo-stepper', template: ` <ng-container kendoStepperLocalizedMessages i18n-optional="kendo.stepper.optional|The text for the optional segment of the step label" optional="Optional" > </ng-container> <ol kendoStepperList [stepType]='stepType' [linear]='linear' [orientation]='orientation' [steps]='steps' [currentStep]='currentStep' [successIcon]='successIcon' [successSVGIcon]='successSVGIcon' [errorIcon]='errorIcon' [errorSVGIcon]='errorSVGIcon' [svgIcon]="svgIcon" [indicatorTemplate]='indicatorTemplate?.templateRef' [labelTemplate]='labelTemplate?.templateRef' [stepTemplate]='stepTemplate?.templateRef' class='k-step-list' [class.k-step-list-horizontal]='isHorizontal' [class.k-step-list-vertical]='!isHorizontal' [ngStyle]='stepsListStyling' (listKeydown)="onListKeydown($event)" (listClick)="onListClick($event)"> </ol> <kendo-progressbar *ngIf='steps.length > 0' [attr.aria-hidden]='true' [animation]='progressAnimation' [max]='steps.length - 1' [label]='{position: "start", visible: false}' [orientation]='orientation' [reverse]='!isHorizontal' [value]='currentStep' [ngStyle]='progressBarStyling'> </kendo-progressbar> `, standalone: true, imports: [LocalizedStepperMessagesDirective, StepperListComponent, NgStyle, NgIf, ProgressBarComponent] }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.LocalizationService }, { type: i2.StepperService }]; }, propDecorators: { hostClasses: [{ type: HostBinding, args: ['class.k-stepper'] }], linearClass: [{ type: HostBinding, args: ['class.k-stepper-linear'] }], ariaRole: [{ type: HostBinding, args: ['attr.role'] }], direction: [{ type: HostBinding, args: ['attr.dir'] }], displayStyle: [{ type: HostBinding, args: ['style.display'] }], stepType: [{ type: Input }], linear: [{ type: Input }], orientation: [{ type: Input }], currentStep: [{ type: Input }], steps: [{ type: Input }], svgIcon: [{ type: Input }], successSVGIcon: [{ type: Input }], errorSVGIcon: [{ type: Input }], successIcon: [{ type: Input }], errorIcon: [{ type: Input }], animation: [{ type: Input }], activate: [{ type: Output }], currentStepChange: [{ type: Output }], stepTemplate: [{ type: ContentChild, args: [StepperStepTemplateDirective, { static: false }] }], labelTemplate: [{ type: ContentChild, args: [StepperLabelTemplateDirective, { static: false }] }], indicatorTemplate: [{ type: ContentChild, args: [StepperIndicatorTemplateDirective, { static: false }] }] } });