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