UNPKG

@yelon/abc

Version:

Common business components of ng-yunzai.

425 lines (418 loc) 24.5 kB
import * as i0 from '@angular/core'; import { inject, ElementRef, Renderer2, ViewEncapsulation, ChangeDetectionStrategy, Component, booleanAttribute, numberAttribute, Input, ChangeDetectorRef, DestroyRef, TemplateRef, ViewChild, ContentChild, NgModule } from '@angular/core'; import { BehaviorSubject, filter } from 'rxjs'; import { YunzaiConfigService } from '@yelon/util/config'; import { NzStringTemplateOutletDirective, NzOutletModule } from 'ng-zorro-antd/core/outlet'; import { CdkObserveContent } from '@angular/cdk/observers'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Validators, RequiredValidator, NgModel, FormControlName } from '@angular/forms'; import { ResponsiveService } from '@yelon/theme'; import { isEmpty } from '@yelon/util/browser'; import { helpMotion } from 'ng-zorro-antd/core/animation'; import { NzFormStatusService } from 'ng-zorro-antd/core/form'; import { NzIconDirective, NzIconModule } from 'ng-zorro-antd/icon'; import { NzTooltipDirective, NzTooltipModule } from 'ng-zorro-antd/tooltip'; import { CommonModule } from '@angular/common'; class SETitleComponent { parentComp = inject(SEContainerComponent, { host: true, optional: true }); el = inject(ElementRef).nativeElement; ren = inject(Renderer2); constructor() { if (this.parentComp == null) { throw new Error(`[se-title] must include 'se-container' component`); } } setClass() { const { el } = this; const gutter = this.parentComp.gutter; this.ren.setStyle(el, 'padding-left', `${gutter / 2}px`); this.ren.setStyle(el, 'padding-right', `${gutter / 2}px`); } ngOnInit() { this.setClass(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SETitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: SETitleComponent, isStandalone: true, selector: "se-title, [se-title]", host: { properties: { "class.se__title": "true" } }, exportAs: ["seTitle"], ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SETitleComponent, decorators: [{ type: Component, args: [{ selector: 'se-title, [se-title]', exportAs: 'seTitle', template: '<ng-content />', host: { '[class.se__title]': 'true' }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }] }], ctorParameters: () => [] }); class SEContainerComponent { cogSrv = inject(YunzaiConfigService); errorNotify$ = new BehaviorSubject(null); colInCon; col; labelWidth; noColon = false; title; get gutter() { return this.nzLayout === 'horizontal' ? this._gutter : 0; } set gutter(value) { this._gutter = value; } _gutter; get nzLayout() { return this._nzLayout; } set nzLayout(value) { this._nzLayout = value; if (value === 'inline') { this.size = 'compact'; } } _nzLayout; size; firstVisual; ignoreDirty; line = false; set errors(val) { this.setErrors(val); } get margin() { return -(this.gutter / 2); } get errorNotify() { return this.errorNotify$.pipe(filter(v => v != null)); } constructor() { this.cogSrv.attach(this, 'se', { size: 'default', nzLayout: 'horizontal', gutter: 32, col: 2, labelWidth: 150, firstVisual: false, ignoreDirty: false }); } setErrors(errors) { for (const error of errors) { this.errorNotify$.next(error); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SEContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: SEContainerComponent, isStandalone: true, selector: "se-container, [se-container]", inputs: { colInCon: ["se-container", "colInCon", (v) => (v == null ? null : numberAttribute(v))], col: ["col", "col", (v) => (v == null ? null : numberAttribute(v))], labelWidth: ["labelWidth", "labelWidth", (v) => (v == null ? null : numberAttribute(v))], noColon: ["noColon", "noColon", booleanAttribute], title: "title", gutter: ["gutter", "gutter", numberAttribute], nzLayout: "nzLayout", size: "size", firstVisual: ["firstVisual", "firstVisual", booleanAttribute], ignoreDirty: ["ignoreDirty", "ignoreDirty", booleanAttribute], line: ["line", "line", booleanAttribute], errors: "errors" }, host: { properties: { "class.ant-row": "true", "class.se__container": "true", "class.se__horizontal": "nzLayout === 'horizontal'", "class.se__vertical": "nzLayout === 'vertical'", "class.se__inline": "nzLayout === 'inline'", "class.se__compact": "size === 'compact'", "style.margin-left.px": "margin", "style.margin-right.px": "margin" } }, exportAs: ["seContainer"], ngImport: i0, template: ` @if (title) { <div se-title> <ng-container *nzStringTemplateOutlet="title">{{ title }}</ng-container> </div> } <ng-content /> `, isInline: true, dependencies: [{ kind: "component", type: SETitleComponent, selector: "se-title, [se-title]", exportAs: ["seTitle"] }, { kind: "directive", type: NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SEContainerComponent, decorators: [{ type: Component, args: [{ selector: 'se-container, [se-container]', exportAs: 'seContainer', template: ` @if (title) { <div se-title> <ng-container *nzStringTemplateOutlet="title">{{ title }}</ng-container> </div> } <ng-content /> `, host: { '[class.ant-row]': `true`, '[class.se__container]': `true`, '[class.se__horizontal]': `nzLayout === 'horizontal'`, '[class.se__vertical]': `nzLayout === 'vertical'`, '[class.se__inline]': `nzLayout === 'inline'`, '[class.se__compact]': `size === 'compact'`, '[style.margin-left.px]': `margin`, '[style.margin-right.px]': `margin` }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [SETitleComponent, NzStringTemplateOutletDirective] }] }], ctorParameters: () => [], propDecorators: { colInCon: [{ type: Input, args: [{ alias: 'se-container', transform: (v) => (v == null ? null : numberAttribute(v)) }] }], col: [{ type: Input, args: [{ transform: (v) => (v == null ? null : numberAttribute(v)) }] }], labelWidth: [{ type: Input, args: [{ transform: (v) => (v == null ? null : numberAttribute(v)) }] }], noColon: [{ type: Input, args: [{ transform: booleanAttribute }] }], title: [{ type: Input }], gutter: [{ type: Input, args: [{ transform: numberAttribute }] }], nzLayout: [{ type: Input }], size: [{ type: Input }], firstVisual: [{ type: Input, args: [{ transform: booleanAttribute }] }], ignoreDirty: [{ type: Input, args: [{ transform: booleanAttribute }] }], line: [{ type: Input, args: [{ transform: booleanAttribute }] }], errors: [{ type: Input }] } }); const prefixCls = `se`; let nextUniqueId = 0; class SEComponent { parentComp = inject(SEContainerComponent, { host: true, optional: true }); el = inject(ElementRef).nativeElement; rep = inject(ResponsiveService); ren = inject(Renderer2); cdr = inject(ChangeDetectorRef); statusSrv = inject(NzFormStatusService); destroy$ = inject(DestroyRef); ngModel; formControlName; contentElement; clsMap = []; inited = false; onceFlag = false; errorData = {}; isBindModel = false; invalid = false; _labelWidth = null; _noColon = null; _error; // #region fields optional = null; optionalHelp = null; optionalHelpColor; set error(val) { this.errorData = typeof val === 'string' || val instanceof TemplateRef ? { '': val } : val; } extra; label; col; required = false; controlClass = ''; line; labelWidth; noColon; hideLabel = false; set id(value) { this._id = value; this._autoId = false; } _id = `_se-${++nextUniqueId}`; _autoId = true; // #endregion get paddingValue() { return this.parentComp.gutter / 2; } get showErr() { return this.invalid && !!this._error && !this.compact; } get compact() { return this.parentComp.size === 'compact'; } get ngControl() { return this.ngModel || this.formControlName; } constructor() { if (this.parentComp == null) { throw new Error(`[se] must include 'se-container' component`); } this.parentComp.errorNotify .pipe(takeUntilDestroyed(), filter(w => this.inited && this.ngControl != null && this.ngControl.name === w.name)) .subscribe(item => { this.error = item.error; this.updateStatus(this.ngControl.invalid); }); } setClass() { const { el, ren, clsMap, col, cdr, line, labelWidth, rep, noColon } = this; const parent = this.parentComp; this._noColon = noColon != null ? noColon : parent.noColon; this._labelWidth = parent.nzLayout === 'horizontal' ? (labelWidth != null ? labelWidth : parent.labelWidth) : null; clsMap.forEach(cls => ren.removeClass(el, cls)); clsMap.length = 0; const parentCol = parent.colInCon || parent.col; const repCls = parent.nzLayout === 'horizontal' ? rep.genCls(col != null ? col : parentCol, parentCol) : []; clsMap.push(`ant-form-item`, ...repCls, `${prefixCls}__item`); if (line || parent.line) { clsMap.push(`${prefixCls}__line`); } clsMap.forEach(cls => ren.addClass(el, cls)); cdr.detectChanges(); return this; } bindModel() { if (!this.ngControl || this.isBindModel) return; this.isBindModel = true; this.ngControl .statusChanges.pipe(takeUntilDestroyed(this.destroy$)) .subscribe(res => this.updateStatus(res === 'INVALID')); if (this._autoId) { const controlAccessor = this.ngControl.valueAccessor; const control = (controlAccessor?.elementRef || controlAccessor?._elementRef)?.nativeElement; if (control) { if (control.id) { this._id = control.id; } else { control.id = this._id; } } } // auto required if (this.required !== true) { let required = this.ngControl?.control?.hasValidator(Validators.required); if (required !== true) { const rawValidators = this.ngControl?._rawValidators; required = rawValidators.find(w => w instanceof RequiredValidator) != null; } this.required = required; this.cdr.detectChanges(); } } updateStatus(invalid) { if (this.ngControl?.disabled || this.ngControl?.isDisabled) { return; } this.invalid = !this.onceFlag && invalid && this.parentComp.ignoreDirty === false && !this.ngControl?.dirty ? false : invalid; const errors = this.ngControl?.errors; if (errors != null && Object.keys(errors).length > 0) { const key = Object.keys(errors)[0] || ''; const err = this.errorData[key]; this._error = err != null ? err : this.errorData[''] || ''; } this.statusSrv.formStatusChanges.next({ status: this.invalid ? 'error' : '', hasFeedback: false }); this.cdr.detectChanges(); } checkContent() { const el = this.contentElement.nativeElement; const cls = `${prefixCls}__item-empty`; if (isEmpty(el)) { this.ren.addClass(el, cls); } else { this.ren.removeClass(el, cls); } } ngAfterContentInit() { this.checkContent(); } ngOnChanges() { this.onceFlag = this.parentComp.firstVisual; if (this.inited) { this.setClass().bindModel(); } } ngAfterViewInit() { this.setClass().bindModel(); this.inited = true; if (this.onceFlag) { Promise.resolve().then(() => { this.updateStatus(this.ngControl.invalid); this.onceFlag = false; }); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SEComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: SEComponent, isStandalone: true, selector: "se", inputs: { optional: "optional", optionalHelp: "optionalHelp", optionalHelpColor: "optionalHelpColor", error: "error", extra: "extra", label: "label", col: ["col", "col", (v) => (v == null ? null : numberAttribute(v))], required: ["required", "required", booleanAttribute], controlClass: "controlClass", line: ["line", "line", (v) => (v == null ? null : booleanAttribute(v))], labelWidth: ["labelWidth", "labelWidth", (v) => (v == null ? null : numberAttribute(v))], noColon: ["noColon", "noColon", (v) => (v == null ? null : booleanAttribute(v))], hideLabel: ["hideLabel", "hideLabel", booleanAttribute], id: "id" }, host: { properties: { "style.padding-left.px": "paddingValue", "style.padding-right.px": "paddingValue", "class.se__hide-label": "hideLabel", "class.ant-form-item-has-error": "invalid", "class.ant-form-item-with-help": "showErr" } }, providers: [NzFormStatusService], queries: [{ propertyName: "ngModel", first: true, predicate: NgModel, descendants: true, static: true }, { propertyName: "formControlName", first: true, predicate: FormControlName, descendants: true, static: true }], viewQueries: [{ propertyName: "contentElement", first: true, predicate: ["contentElement"], descendants: true, static: true }], exportAs: ["se"], usesOnChanges: true, ngImport: i0, template: "<div class=\"ant-form-item-label\" [class.se__nolabel]=\"hideLabel || !label\" [style.width.px]=\"_labelWidth\">\n @if (label) {\n <label [attr.for]=\"_id\" class=\"se__label\" [class.ant-form-item-required]=\"required\" [class.se__no-colon]=\"_noColon\">\n <span class=\"se__label-text\">\n <ng-container *nzStringTemplateOutlet=\"label\">{{ label }}</ng-container>\n </span>\n @if (optional || optionalHelp) {\n <span class=\"se__label-optional\" [class.se__label-optional-no-text]=\"!optional\">\n <ng-container *nzStringTemplateOutlet=\"optional\">{{ optional }}</ng-container>\n @if (optionalHelp) {\n <nz-icon\n nz-tooltip\n [nzTooltipTitle]=\"optionalHelp\"\n [nzTooltipColor]=\"optionalHelpColor\"\n nzType=\"question-circle\"\n />\n }\n </span>\n }\n </label>\n }\n</div>\n<div class=\"ant-form-item-control se__control\">\n <div class=\"ant-form-item-control-input {{ controlClass }}\">\n <div class=\"ant-form-item-control-input-content\" (cdkObserveContent)=\"checkContent()\" #contentElement>\n <ng-content />\n </div>\n </div>\n @if (showErr) {\n <div @helpMotion class=\"ant-form-item-explain ant-form-item-explain-connected\">\n <div role=\"alert\" class=\"ant-form-item-explain-error\">\n <ng-container *nzStringTemplateOutlet=\"_error\">{{ _error }}</ng-container>\n </div>\n </div>\n }\n @if (extra && !compact) {\n <div class=\"ant-form-item-extra\">\n <ng-container *nzStringTemplateOutlet=\"extra\">{{ extra }}</ng-container>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }, { kind: "directive", type: NzTooltipDirective, selector: "[nz-tooltip]", inputs: ["nzTooltipTitle", "nzTooltipTitleContext", "nz-tooltip", "nzTooltipTrigger", "nzTooltipPlacement", "nzTooltipOrigin", "nzTooltipVisible", "nzTooltipMouseEnterDelay", "nzTooltipMouseLeaveDelay", "nzTooltipOverlayClassName", "nzTooltipOverlayStyle", "nzTooltipArrowPointAtCenter", "cdkConnectedOverlayPush", "nzTooltipColor"], outputs: ["nzTooltipVisibleChange"], exportAs: ["nzTooltip"] }, { kind: "directive", type: NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "directive", type: CdkObserveContent, selector: "[cdkObserveContent]", inputs: ["cdkObserveContentDisabled", "debounce"], outputs: ["cdkObserveContent"], exportAs: ["cdkObserveContent"] }], animations: [helpMotion], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SEComponent, decorators: [{ type: Component, args: [{ selector: 'se', exportAs: 'se', host: { '[style.padding-left.px]': 'paddingValue', '[style.padding-right.px]': 'paddingValue', '[class.se__hide-label]': 'hideLabel', '[class.ant-form-item-has-error]': 'invalid', '[class.ant-form-item-with-help]': 'showErr' }, providers: [NzFormStatusService], animations: [helpMotion], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [NzStringTemplateOutletDirective, NzTooltipDirective, NzIconDirective, CdkObserveContent], template: "<div class=\"ant-form-item-label\" [class.se__nolabel]=\"hideLabel || !label\" [style.width.px]=\"_labelWidth\">\n @if (label) {\n <label [attr.for]=\"_id\" class=\"se__label\" [class.ant-form-item-required]=\"required\" [class.se__no-colon]=\"_noColon\">\n <span class=\"se__label-text\">\n <ng-container *nzStringTemplateOutlet=\"label\">{{ label }}</ng-container>\n </span>\n @if (optional || optionalHelp) {\n <span class=\"se__label-optional\" [class.se__label-optional-no-text]=\"!optional\">\n <ng-container *nzStringTemplateOutlet=\"optional\">{{ optional }}</ng-container>\n @if (optionalHelp) {\n <nz-icon\n nz-tooltip\n [nzTooltipTitle]=\"optionalHelp\"\n [nzTooltipColor]=\"optionalHelpColor\"\n nzType=\"question-circle\"\n />\n }\n </span>\n }\n </label>\n }\n</div>\n<div class=\"ant-form-item-control se__control\">\n <div class=\"ant-form-item-control-input {{ controlClass }}\">\n <div class=\"ant-form-item-control-input-content\" (cdkObserveContent)=\"checkContent()\" #contentElement>\n <ng-content />\n </div>\n </div>\n @if (showErr) {\n <div @helpMotion class=\"ant-form-item-explain ant-form-item-explain-connected\">\n <div role=\"alert\" class=\"ant-form-item-explain-error\">\n <ng-container *nzStringTemplateOutlet=\"_error\">{{ _error }}</ng-container>\n </div>\n </div>\n }\n @if (extra && !compact) {\n <div class=\"ant-form-item-extra\">\n <ng-container *nzStringTemplateOutlet=\"extra\">{{ extra }}</ng-container>\n </div>\n }\n</div>\n" }] }], ctorParameters: () => [], propDecorators: { ngModel: [{ type: ContentChild, args: [NgModel, { static: true }] }], formControlName: [{ type: ContentChild, args: [FormControlName, { static: true }] }], contentElement: [{ type: ViewChild, args: ['contentElement', { static: true }] }], optional: [{ type: Input }], optionalHelp: [{ type: Input }], optionalHelpColor: [{ type: Input }], error: [{ type: Input }], extra: [{ type: Input }], label: [{ type: Input }], col: [{ type: Input, args: [{ transform: (v) => (v == null ? null : numberAttribute(v)) }] }], required: [{ type: Input, args: [{ transform: booleanAttribute }] }], controlClass: [{ type: Input }], line: [{ type: Input, args: [{ transform: (v) => (v == null ? null : booleanAttribute(v)) }] }], labelWidth: [{ type: Input, args: [{ transform: (v) => (v == null ? null : numberAttribute(v)) }] }], noColon: [{ type: Input, args: [{ transform: (v) => (v == null ? null : booleanAttribute(v)) }] }], hideLabel: [{ type: Input, args: [{ transform: booleanAttribute }] }], id: [{ type: Input }] } }); const COMPONENTS = [SEContainerComponent, SEComponent, SETitleComponent]; class SEModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SEModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.3", ngImport: i0, type: SEModule, imports: [CommonModule, NzTooltipModule, NzIconModule, NzOutletModule, SEContainerComponent, SEComponent, SETitleComponent], exports: [SEContainerComponent, SEComponent, SETitleComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SEModule, imports: [CommonModule, NzTooltipModule, NzIconModule, NzOutletModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SEModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, NzTooltipModule, NzIconModule, NzOutletModule, ...COMPONENTS], exports: COMPONENTS }] }] }); // /** // * Error collection // * - `name`: The value of` ngModel` or `formControlName` // * - `error`: Replaced error value // */ // errors: Array<{ name: string; error: SEErrorType }>; // /** // * Whether force show error, even if the form component has not invalid, Default: `false` // * - `false`: Whether to display error by `invalid` // * - `true`: Force show display error // */ // force?: boolean; /** * Generated bundle index. Do not edit. */ export { SEComponent, SEContainerComponent, SEModule, SETitleComponent }; //# sourceMappingURL=se.mjs.map