UNPKG

ngx-ui-builder

Version:

Angular - Render component ui with configurations

139 lines (134 loc) 14.2 kB
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