UNPKG

ng-devui

Version:

DevUI components based on Angular

232 lines (226 loc) 22.6 kB
import * as i0 from '@angular/core'; import { Directive, Input, Component, ContentChildren, NgModule } from '@angular/core'; import { merge } from 'lodash-es'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; class ProgressTemplateDirective { constructor(template) { this.template = template; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ProgressTemplateDirective, selector: "ng-template[position], ng-template[dPosition]", inputs: { position: "position", dPosition: "dPosition" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressTemplateDirective, decorators: [{ type: Directive, args: [{ /* eslint-disable */ selector: 'ng-template[position], ng-template[dPosition]', }] }], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { position: [{ type: Input }], dPosition: [{ type: Input }] } }); class ProgressComponent { static { this.ID_SEED = 0; } /** * @deprecated * 统一用strokeWidth */ set height(value) { this.strokeWidth = parseInt(value, 10); } /** * @deprecated * 用type类型替换 */ set isCircle(value) { this.type = value ? 'circle' : 'line'; } get content() { return this.percentageText ? this.percentageText : `${this.percentage}%`; } constructor() { this.isDynamic = true; this.percentage = 0; this.strokeColor = ''; this.strokeWidth = 14; // 进度条的线条宽度 this.type = 'line'; this.multiProgressConfig = []; this.progressData = []; this.gradientColor = []; this.isGradient = false; this.showContentConfig = { showInnerContent: false, showOuterContent: false, showCenterContent: true, }; this.id = ProgressComponent.ID_SEED++; } ngOnChanges(changes) { const { isCircle, multiProgressConfig, percentage, showContent, strokeColor, type } = changes; const hasChanged = [percentage, strokeColor, type, isCircle].some((change) => change); if (multiProgressConfig || (this.multiProgressConfig?.length && percentage) || (!this.multiProgressConfig?.length && hasChanged)) { this.render(); } if (showContent) { this.showContentConfig = typeof this.showContent === 'boolean' ? { showInnerContent: this.showContent, showOuterContent: this.showContent, showCenterContent: false, } : { ...this.showContentConfig, ...this.showContent }; } } ngAfterViewInit() { // 兼容之前line中自定义模板对应右侧模板,circle对应中间模板 if (this.templates?.length) { const restItem = []; this.templates.forEach((item) => { const pos = item.position || item.dPosition; const name = pos && `${pos}Template`; if (name) { this[name] = item.template; } else { restItem.push(item); } }); if (restItem.length) { this.outerTemplate = this.outerTemplate || restItem[0].template; this.centerTemplate = this.centerTemplate || restItem[restItem.length - 1]?.template; } } } render() { const data = this.multiProgressConfig?.length ? [...this.multiProgressConfig] : [ { color: (this.checkStrokeColor() || this.barbgcolor) ?? '', percentage: this.percentage ?? 0, percentageText: this.percentageText ?? '', content: this.content ?? '', }, ]; if (this.type === 'line') { this.checkSumOfPercentages(data, (sum, item) => { item.width = sum; }); } if (this.type === 'circle') { this.setCircleProgress(data); } // 展示数据倒序输出,短的后输出,显示层级高 data.reverse(); if (this.isDynamic) { // merge方式覆盖数据,不改变数据源,避免重渲染dom导致动画失效 merge(this.progressData, data); } else { this.progressData = [...data]; } } setCircleProgress(data) { const radius = 50 - this.strokeWidth / 2; const beginPositionY = -radius; const endPositionY = radius * -2; const len = Math.PI * 2 * radius; this.pathString = `M 50,50 m 0,${beginPositionY} a ${radius},${radius} 0 1 1 0,${-endPositionY} a ${radius},${radius} 0 1 1 0,${endPositionY}`; this.trailPath = { strokeDasharray: `${len}px ${len}px`, strokeDashoffset: `0`, transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s', }; this.checkSumOfPercentages(data, (sum, item) => { item.strokePath = { stroke: item.color || this.checkStrokeColor() || this.barbgcolor || null, strokeDasharray: `${(sum / 100) * len}px ${len}px`, strokeDashoffset: `0`, transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s', }; }); } checkSumOfPercentages(data, func) { const result = data.reduce((sum, item, index) => { sum += Number(item.percentage); sum = sum > 100 || (index > 0 && index === data.length - 1 && this.percentage === 100) ? 100 : sum; func(sum, item); return sum; }, 0); this.percentage = this.percentage >= 100 ? 100 : result; } checkStrokeColor() { if (Array.isArray(this.strokeColor)) { this.isGradient = true; this.gradientColor = this.strokeColor; if (this.type === 'line') { const colors = this.strokeColor.map((item) => `${item.color} ${item.percentage}`).join(', '); const result = `linear-gradient(to right, ${colors})`; return this.strokeColor.length ? result : ''; } if (this.type === 'circle') { return `url(#devui-progress-gradient-${this.id}`; } } else { this.isGradient = false; this.strokeColor = this.strokeColor || ''; return this.strokeColor; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ProgressComponent, selector: "d-progress", inputs: { isDynamic: "isDynamic", percentage: "percentage", percentageText: "percentageText", barbgcolor: "barbgcolor", strokeColor: "strokeColor", height: "height", strokeWidth: "strokeWidth", isCircle: "isCircle", type: "type", showContent: "showContent", multiProgressConfig: "multiProgressConfig" }, queries: [{ propertyName: "templates", predicate: ProgressTemplateDirective }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"type === 'line'\">\n <div id=\"devui-progress-line-{{ id }}\" class=\"devui-progress devui-progress-line\" [style.height]=\"strokeWidth + 'px'\">\n <div\n *ngFor=\"let bar of progressData\"\n class=\"devui-progress-bar\"\n [class.devui-progress-bar-default-bg]=\"!bar.color\"\n [style.background]=\"bar.color\"\n [style.width]=\"bar.width + '%'\"\n >\n <ng-template\n *ngIf=\"showContentConfig.showInnerContent\"\n [ngTemplateOutlet]=\"bar.template || defaultInnerContent\"\n [ngTemplateOutletContext]=\"{ $implicit: this, bar: bar }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"showContentConfig.showCenterContent\"\n [ngTemplateOutlet]=\"centerTemplate || defaultCenterContent\"\n [ngTemplateOutletContext]=\"{ $implicit: this }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"showContentConfig.showOuterContent\"\n [ngTemplateOutlet]=\"outerTemplate || defaultPercentageText\"\n [ngTemplateOutletContext]=\"{ $implicit: this, percentage: percentage }\"\n ></ng-template>\n</ng-container>\n\n<ng-container *ngIf=\"type === 'circle'\">\n <div id=\"devui-progress-circle-{{ id }}\" class=\"devui-progress devui-progress-circle\">\n <svg viewBox=\"0 0 100 100\">\n <defs *ngIf=\"isGradient\">\n <linearGradient id=\"devui-progress-gradient-{{ id }}\" x1=\"100%\" y1=\"0%\" x2=\"0%\" y2=\"0%\">\n <stop *ngFor=\"let color of gradientColor\" [attr.offset]=\"color.percentage\" [attr.stop-color]=\"color.color\"></stop>\n </linearGradient>\n </defs>\n <path\n class=\"devui-progress-circle-trail\"\n fill-opacity=\"0\"\n [attr.d]=\"pathString\"\n [attr.stroke-width]=\"strokeWidth\"\n [ngStyle]=\"trailPath\"\n ></path>\n <path\n *ngFor=\"let circle of progressData\"\n fill-opacity=\"0\"\n [attr.d]=\"pathString\"\n [attr.stroke]=\"circle.color\"\n [attr.stroke-linecap]=\"'round'\"\n [attr.stroke-width]=\"circle.percentage ? strokeWidth : 0\"\n [class.devui-progress-circle-path]=\"!isGradient\"\n [ngStyle]=\"circle.strokePath\"\n >\n <title>{{ circle.percentageText ? circle.percentageText : circle.percentage + '%' }}</title>\n </path>\n </svg>\n <ng-template\n *ngIf=\"showContentConfig.showCenterContent\"\n [ngTemplateOutlet]=\"centerTemplate || defaultPercentageText\"\n [ngTemplateOutletContext]=\"{ $implicit: this, percentage: percentage }\"\n ></ng-template>\n </div>\n</ng-container>\n\n<ng-template #defaultInnerContent let-bar=\"bar\">\n <span [style.line-height]=\"strokeWidth + 'px'\" [title]=\"bar.percentageText ? bar.percentageText : bar.percentage + '%'\">\n {{ bar.percentageText ? bar.percentageText : bar.percentage + '%' }}\n </span>\n</ng-template>\n\n<ng-template #defaultCenterContent>\n <span [style.line-height]=\"strokeWidth + 'px'\" [title]=\"content\">{{ content }}</span>\n</ng-template>\n\n<ng-template #defaultPercentageText>\n <div class=\"devui-progress-default-text\" [title]=\"content\">{{ content }}</div>\n</ng-template>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}:host{display:flex;align-items:center;justify-content:flex-start;flex-wrap:nowrap}:host .devui-progress-default-text{width:fit-content;margin:0;padding:0 8px;color:var(--devui-text, #191919);font-size:var(--devui-font-size, 12px);line-height:1}:host .devui-progress-line,:host .devui-progress-circle{flex:1 1 auto;position:relative}:host .devui-progress-line{background:var(--devui-range-item-hover-bg, #cedefd);border-radius:var(--devui-border-radius-full, 100px)}:host .devui-progress-line .devui-progress-bar{position:absolute;left:0;top:0;width:0;height:100%;transition:width .6s ease;border-radius:var(--devui-border-radius-full, 100px)}:host .devui-progress-line .devui-progress-bar.devui-progress-bar-default-bg{background-color:var(--devui-brand, #0a59f7)}:host .devui-progress-line .devui-progress-bar>span{color:var(--devui-light-text, #ffffff);font-size:var(--devui-font-size, 12px);position:absolute;right:8px;height:100%;line-height:100%;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .devui-progress-line>span{color:var(--devui-light-text, #ffffff);font-size:var(--devui-font-size, 12px);position:absolute;left:50%;top:0;width:fit-content;transform:translate(-50%);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .devui-progress-circle{height:100%}:host .devui-progress-circle .devui-progress-default-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .devui-progress-circle .devui-progress-circle-trail{stroke:var(--devui-dividing-line, #f0f0f0)}:host .devui-progress-circle .devui-progress-circle-path{stroke:var(--devui-brand, #0a59f7)}\n"], dependencies: [{ 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: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressComponent, decorators: [{ type: Component, args: [{ selector: 'd-progress', preserveWhitespaces: false, template: "<ng-container *ngIf=\"type === 'line'\">\n <div id=\"devui-progress-line-{{ id }}\" class=\"devui-progress devui-progress-line\" [style.height]=\"strokeWidth + 'px'\">\n <div\n *ngFor=\"let bar of progressData\"\n class=\"devui-progress-bar\"\n [class.devui-progress-bar-default-bg]=\"!bar.color\"\n [style.background]=\"bar.color\"\n [style.width]=\"bar.width + '%'\"\n >\n <ng-template\n *ngIf=\"showContentConfig.showInnerContent\"\n [ngTemplateOutlet]=\"bar.template || defaultInnerContent\"\n [ngTemplateOutletContext]=\"{ $implicit: this, bar: bar }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"showContentConfig.showCenterContent\"\n [ngTemplateOutlet]=\"centerTemplate || defaultCenterContent\"\n [ngTemplateOutletContext]=\"{ $implicit: this }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"showContentConfig.showOuterContent\"\n [ngTemplateOutlet]=\"outerTemplate || defaultPercentageText\"\n [ngTemplateOutletContext]=\"{ $implicit: this, percentage: percentage }\"\n ></ng-template>\n</ng-container>\n\n<ng-container *ngIf=\"type === 'circle'\">\n <div id=\"devui-progress-circle-{{ id }}\" class=\"devui-progress devui-progress-circle\">\n <svg viewBox=\"0 0 100 100\">\n <defs *ngIf=\"isGradient\">\n <linearGradient id=\"devui-progress-gradient-{{ id }}\" x1=\"100%\" y1=\"0%\" x2=\"0%\" y2=\"0%\">\n <stop *ngFor=\"let color of gradientColor\" [attr.offset]=\"color.percentage\" [attr.stop-color]=\"color.color\"></stop>\n </linearGradient>\n </defs>\n <path\n class=\"devui-progress-circle-trail\"\n fill-opacity=\"0\"\n [attr.d]=\"pathString\"\n [attr.stroke-width]=\"strokeWidth\"\n [ngStyle]=\"trailPath\"\n ></path>\n <path\n *ngFor=\"let circle of progressData\"\n fill-opacity=\"0\"\n [attr.d]=\"pathString\"\n [attr.stroke]=\"circle.color\"\n [attr.stroke-linecap]=\"'round'\"\n [attr.stroke-width]=\"circle.percentage ? strokeWidth : 0\"\n [class.devui-progress-circle-path]=\"!isGradient\"\n [ngStyle]=\"circle.strokePath\"\n >\n <title>{{ circle.percentageText ? circle.percentageText : circle.percentage + '%' }}</title>\n </path>\n </svg>\n <ng-template\n *ngIf=\"showContentConfig.showCenterContent\"\n [ngTemplateOutlet]=\"centerTemplate || defaultPercentageText\"\n [ngTemplateOutletContext]=\"{ $implicit: this, percentage: percentage }\"\n ></ng-template>\n </div>\n</ng-container>\n\n<ng-template #defaultInnerContent let-bar=\"bar\">\n <span [style.line-height]=\"strokeWidth + 'px'\" [title]=\"bar.percentageText ? bar.percentageText : bar.percentage + '%'\">\n {{ bar.percentageText ? bar.percentageText : bar.percentage + '%' }}\n </span>\n</ng-template>\n\n<ng-template #defaultCenterContent>\n <span [style.line-height]=\"strokeWidth + 'px'\" [title]=\"content\">{{ content }}</span>\n</ng-template>\n\n<ng-template #defaultPercentageText>\n <div class=\"devui-progress-default-text\" [title]=\"content\">{{ content }}</div>\n</ng-template>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}:host{display:flex;align-items:center;justify-content:flex-start;flex-wrap:nowrap}:host .devui-progress-default-text{width:fit-content;margin:0;padding:0 8px;color:var(--devui-text, #191919);font-size:var(--devui-font-size, 12px);line-height:1}:host .devui-progress-line,:host .devui-progress-circle{flex:1 1 auto;position:relative}:host .devui-progress-line{background:var(--devui-range-item-hover-bg, #cedefd);border-radius:var(--devui-border-radius-full, 100px)}:host .devui-progress-line .devui-progress-bar{position:absolute;left:0;top:0;width:0;height:100%;transition:width .6s ease;border-radius:var(--devui-border-radius-full, 100px)}:host .devui-progress-line .devui-progress-bar.devui-progress-bar-default-bg{background-color:var(--devui-brand, #0a59f7)}:host .devui-progress-line .devui-progress-bar>span{color:var(--devui-light-text, #ffffff);font-size:var(--devui-font-size, 12px);position:absolute;right:8px;height:100%;line-height:100%;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .devui-progress-line>span{color:var(--devui-light-text, #ffffff);font-size:var(--devui-font-size, 12px);position:absolute;left:50%;top:0;width:fit-content;transform:translate(-50%);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .devui-progress-circle{height:100%}:host .devui-progress-circle .devui-progress-default-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host .devui-progress-circle .devui-progress-circle-trail{stroke:var(--devui-dividing-line, #f0f0f0)}:host .devui-progress-circle .devui-progress-circle-path{stroke:var(--devui-brand, #0a59f7)}\n"] }] }], ctorParameters: () => [], propDecorators: { isDynamic: [{ type: Input }], percentage: [{ type: Input }], percentageText: [{ type: Input }], barbgcolor: [{ type: Input }], strokeColor: [{ type: Input }], height: [{ type: Input }], strokeWidth: [{ type: Input }], isCircle: [{ type: Input }], type: [{ type: Input }], showContent: [{ type: Input }], multiProgressConfig: [{ type: Input }], templates: [{ type: ContentChildren, args: [ProgressTemplateDirective] }] } }); class ProgressModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: ProgressModule, declarations: [ProgressComponent, ProgressTemplateDirective], imports: [CommonModule], exports: [ProgressComponent, ProgressTemplateDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressModule, imports: [CommonModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProgressModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule], exports: [ProgressComponent, ProgressTemplateDirective], declarations: [ProgressComponent, ProgressTemplateDirective], providers: [], }] }] }); /** * Generated bundle index. Do not edit. */ export { ProgressComponent, ProgressModule, ProgressTemplateDirective }; //# sourceMappingURL=ng-devui-progress.mjs.map