ngx-ui-builder
Version:
Angular - Render component ui with configurations
139 lines (134 loc) • 14.2 kB
JavaScript
import * as i0 from '@angular/core';
import { Component, ChangeDetectionStrategy, Input, NgModule } from '@angular/core';
import * as i2 from '@angular/forms';
import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
class NubStepperComponent {
set configs(configs) {
this.setConfigs(configs);
}
constructor() {
this.localConfigs = {
formGroup: new FormGroup({}),
stepPosition: 'top',
isLinear: false,
currentStep: {
idx: 0,
name: '',
component: null,
},
stepOptions: [
{
name: 'Step 1',
component: null,
}
],
};
}
setConfigs(configs) {
// Combine configs and local configs
let currentStepIdx = 0;
if (configs.defaultStep) {
if (typeof configs.defaultStep === 'string') {
currentStepIdx = configs.stepOptions.findIndex(step => step.name === configs.defaultStep);
}
}
this.localConfigs.currentStep = {
idx: currentStepIdx || 0,
name: configs.stepOptions[currentStepIdx].name,
component: configs.stepOptions[currentStepIdx].component,
};
this.localConfigs = { ...this.localConfigs, ...configs };
}
allowGoToStepAfter(idx) {
// Back step
if (idx <= this.localConfigs.currentStep.idx) {
return true;
}
// Check dependsOn
const dependsOn = this.localConfigs.stepOptions[idx].dependsOn;
if (!this.localConfigs.isLinear && dependsOn) {
if (typeof dependsOn === 'string') {
return this.localConfigs.formGroup.controls[dependsOn].valid;
}
else {
return dependsOn.every(name => this.localConfigs.formGroup.controls[name].valid);
}
}
// Go ahead with isLinear
if (idx > this.localConfigs.currentStep.idx
&& (!this.localConfigs.isLinear || this.localConfigs.formGroup.controls[this.localConfigs.currentStep.name].valid)) {
return true;
}
return false;
}
changeStep(idx) {
if (!this.allowGoToStepAfter(idx)) {
return;
}
this.localConfigs.currentStep = {
idx: idx,
name: this.localConfigs.stepOptions[idx].name,
component: this.localConfigs.stepOptions[idx].component,
};
// TODO: Should fire an event after change step. It contains current step infos
}
handleBack() {
this.changeStep(this.localConfigs.currentStep.idx - 1);
}
handleNext() {
if (this.localConfigs.isLinear && this.localConfigs.formGroup.controls[this.localConfigs.currentStep.name].invalid) {
return;
}
this.changeStep(this.localConfigs.currentStep.idx + 1);
}
calcContFlexDirection() {
switch (this.localConfigs.stepPosition) {
case 'top':
return 'column';
case 'bottom':
return 'column-reverse';
case 'left':
return 'row';
case 'right':
return 'row-reverse';
default:
return 'column';
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.5", ngImport: i0, type: NubStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.5", type: NubStepperComponent, selector: "nub-stepper", inputs: { configs: "configs" }, ngImport: i0, template: "<section\n class=\"stepper-container\"\n [ngClass]=\"localConfigs.coverClass\"\n [style.flex-direction]=\"calcContFlexDirection()\"\n [formGroup]=\"localConfigs.formGroup\"\n>\n <section\n class=\"step-section\"\n [class]=\"localConfigs.class || ''\"\n [ngClass]=\"{ 'aside': calcContFlexDirection().includes('row') }\"\n >\n <ng-container *ngFor=\"let step of localConfigs.stepOptions; index as i\">\n <div\n class=\"step-header\"\n [class]=\"step.stepClass || ''\"\n [ngClass]=\"{\n 'active': localConfigs.currentStep.idx === i,\n 'disabled': !allowGoToStepAfter(i),\n }\"\n (click)=\"i !== localConfigs.currentStep.idx && changeStep(i)\"\n >\n <span class=\"step-number\">{{ i + 1 }}</span>\n <h3 class=\"step-title\">{{step.title}}</h3>\n </div>\n </ng-container>\n </section>\n <section>\n <section\n class=\"step-component-section\"\n [class]=\"localConfigs.stepOptions[localConfigs.currentStep.idx].class\"\n >\n <ng-container\n *ngComponentOutlet=\"localConfigs.currentStep.component\"\n [formGroupName]=\"localConfigs.currentStep.name\"\n ></ng-container>\n </section>\n <section class=\"step-footer\" [ngClass]=\"localConfigs.footer?.class\">\n <button\n *ngIf=\"localConfigs.currentStep.idx !== 0\"\n class=\"btn btn-back\"\n type=\"button\"\n (click)=\"handleBack()\"\n >\n {{ localConfigs.footer?.backTitle || 'Back' }}\n </button>\n\n <button\n *ngIf=\"localConfigs.currentStep.idx !== (localConfigs.stepOptions.length - 1)\"\n class=\"btn btn-next\"\n type=\"button\"\n [disabled]=\"!allowGoToStepAfter(localConfigs.currentStep.idx + 1)\"\n (click)=\"handleNext()\"\n >\n {{ localConfigs.footer?.nextTitle || 'Next' }}\n </button>\n </section>\n </section>\n</section>\n", styles: [":host{--circle-size: 8px;--spacing: clamp(.25rem, 2vw, .5rem)}.stepper-container{display:flex}.step-section{display:flex;margin:8px}.step-section.aside{flex-direction:column}.step-section .step-header{display:flex;flex-direction:column;flex:1;padding:0 16px;text-align:center;align-items:center}.step-header.active{font-weight:700}.step-header:not(.active){cursor:pointer}.step-header.disabled{cursor:not-allowed}.step-section.aside .step-header{flex-direction:row;text-align:left;min-width:100px;padding:16px 0}.step-title{padding:0;margin:0}.step-number{padding:3px 8px;width:var(--circle-size);border-radius:50%;background-color:gray;color:#fff;margin-right:6px}.step-header.active .step-number{background-color:#3f51b5}.step-header:not(:last-child):after{content:\"\";position:relative;top:calc(var(--circle-size));width:calc(100% - var(--circle-size) - calc(var(--spacing) * 2));left:calc(50% + calc(var(--circle-size) / 2 + var(--spacing)));height:2px;background-color:#e0e0e0;order:-1}.step-section.aside .step-header:not(:last-child):after{content:\"\";position:relative;left:calc(var(--circle-size) * 1.5);height:calc(100% - var(--circle-size) + calc(var(--spacing) / 2));top:calc(100% - calc(var(--circle-size) / 2 - var(--spacing)));width:2px;background-color:#e0e0e0;order:-1}.step-component-section{padding:4px}.btn{border-radius:4px;border-style:none;box-sizing:border-box;color:#fff;cursor:pointer;font-weight:700;margin:0;max-width:none;min-height:36px;min-width:10px;outline:none;overflow:hidden;padding:9px 20px 8px;position:relative;text-align:center;text-transform:none;user-select:none;-webkit-user-select:none;touch-action:manipulation}.btn:hover,.btn:focus{opacity:.75}.btn:disabled{opacity:.6;cursor:not-allowed}.btn-back{background-color:#222}.btn-next{background-color:#3f51b5}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.5", ngImport: i0, type: NubStepperComponent, decorators: [{
type: Component,
args: [{ selector: 'nub-stepper', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n class=\"stepper-container\"\n [ngClass]=\"localConfigs.coverClass\"\n [style.flex-direction]=\"calcContFlexDirection()\"\n [formGroup]=\"localConfigs.formGroup\"\n>\n <section\n class=\"step-section\"\n [class]=\"localConfigs.class || ''\"\n [ngClass]=\"{ 'aside': calcContFlexDirection().includes('row') }\"\n >\n <ng-container *ngFor=\"let step of localConfigs.stepOptions; index as i\">\n <div\n class=\"step-header\"\n [class]=\"step.stepClass || ''\"\n [ngClass]=\"{\n 'active': localConfigs.currentStep.idx === i,\n 'disabled': !allowGoToStepAfter(i),\n }\"\n (click)=\"i !== localConfigs.currentStep.idx && changeStep(i)\"\n >\n <span class=\"step-number\">{{ i + 1 }}</span>\n <h3 class=\"step-title\">{{step.title}}</h3>\n </div>\n </ng-container>\n </section>\n <section>\n <section\n class=\"step-component-section\"\n [class]=\"localConfigs.stepOptions[localConfigs.currentStep.idx].class\"\n >\n <ng-container\n *ngComponentOutlet=\"localConfigs.currentStep.component\"\n [formGroupName]=\"localConfigs.currentStep.name\"\n ></ng-container>\n </section>\n <section class=\"step-footer\" [ngClass]=\"localConfigs.footer?.class\">\n <button\n *ngIf=\"localConfigs.currentStep.idx !== 0\"\n class=\"btn btn-back\"\n type=\"button\"\n (click)=\"handleBack()\"\n >\n {{ localConfigs.footer?.backTitle || 'Back' }}\n </button>\n\n <button\n *ngIf=\"localConfigs.currentStep.idx !== (localConfigs.stepOptions.length - 1)\"\n class=\"btn btn-next\"\n type=\"button\"\n [disabled]=\"!allowGoToStepAfter(localConfigs.currentStep.idx + 1)\"\n (click)=\"handleNext()\"\n >\n {{ localConfigs.footer?.nextTitle || 'Next' }}\n </button>\n </section>\n </section>\n</section>\n", styles: [":host{--circle-size: 8px;--spacing: clamp(.25rem, 2vw, .5rem)}.stepper-container{display:flex}.step-section{display:flex;margin:8px}.step-section.aside{flex-direction:column}.step-section .step-header{display:flex;flex-direction:column;flex:1;padding:0 16px;text-align:center;align-items:center}.step-header.active{font-weight:700}.step-header:not(.active){cursor:pointer}.step-header.disabled{cursor:not-allowed}.step-section.aside .step-header{flex-direction:row;text-align:left;min-width:100px;padding:16px 0}.step-title{padding:0;margin:0}.step-number{padding:3px 8px;width:var(--circle-size);border-radius:50%;background-color:gray;color:#fff;margin-right:6px}.step-header.active .step-number{background-color:#3f51b5}.step-header:not(:last-child):after{content:\"\";position:relative;top:calc(var(--circle-size));width:calc(100% - var(--circle-size) - calc(var(--spacing) * 2));left:calc(50% + calc(var(--circle-size) / 2 + var(--spacing)));height:2px;background-color:#e0e0e0;order:-1}.step-section.aside .step-header:not(:last-child):after{content:\"\";position:relative;left:calc(var(--circle-size) * 1.5);height:calc(100% - var(--circle-size) + calc(var(--spacing) / 2));top:calc(100% - calc(var(--circle-size) / 2 - var(--spacing)));width:2px;background-color:#e0e0e0;order:-1}.step-component-section{padding:4px}.btn{border-radius:4px;border-style:none;box-sizing:border-box;color:#fff;cursor:pointer;font-weight:700;margin:0;max-width:none;min-height:36px;min-width:10px;outline:none;overflow:hidden;padding:9px 20px 8px;position:relative;text-align:center;text-transform:none;user-select:none;-webkit-user-select:none;touch-action:manipulation}.btn:hover,.btn:focus{opacity:.75}.btn:disabled{opacity:.6;cursor:not-allowed}.btn-back{background-color:#222}.btn-next{background-color:#3f51b5}\n"] }]
}], ctorParameters: function () { return []; }, propDecorators: { configs: [{
type: Input
}] } });
class NubStepperModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.5", ngImport: i0, type: NubStepperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.5", ngImport: i0, type: NubStepperModule, declarations: [NubStepperComponent], imports: [CommonModule,
FormsModule,
ReactiveFormsModule], exports: [NubStepperComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.5", ngImport: i0, type: NubStepperModule, imports: [CommonModule,
FormsModule,
ReactiveFormsModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.5", ngImport: i0, type: NubStepperModule, decorators: [{
type: NgModule,
args: [{
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
],
declarations: [NubStepperComponent],
exports: [NubStepperComponent]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { NubStepperComponent, NubStepperModule };
//# sourceMappingURL=ngx-ui-builder-stepper.mjs.map