ng-devui
Version:
DevUI components based on Angular
232 lines (226 loc) • 22.6 kB
JavaScript
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