feat: initial commit - Phase 1 & 2 core features

This commit is contained in:
hiderfong
2026-04-22 17:07:33 +08:00
commit 1773bda06b
25005 changed files with 6252106 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
import { SFCWithInstall } from "../../utils/vue/typescript.js";
import "../../utils/index.js";
import { ProgressColor, ProgressFn, ProgressInstance, ProgressProps, ProgressPropsPublic, progressProps } from "./src/progress.js";
import { _default } from "./src/progress.vue.js";
//#region ../../packages/components/progress/index.d.ts
declare const ElProgress: SFCWithInstall<typeof _default>;
//#endregion
export { ElProgress, ElProgress as default, ProgressColor, ProgressFn, ProgressInstance, ProgressProps, ProgressPropsPublic, progressProps };
+10
View File
@@ -0,0 +1,10 @@
import { withInstall } from "../../utils/vue/install.mjs";
import { progressProps } from "./src/progress.mjs";
import progress_default from "./src/progress2.mjs";
//#region ../../packages/components/progress/index.ts
const ElProgress = withInstall(progress_default);
//#endregion
export { ElProgress, ElProgress as default, progressProps };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","names":["Progress"],"sources":["../../../../../packages/components/progress/index.ts"],"sourcesContent":["import { withInstall } from '@element-plus/utils'\nimport Progress from './src/progress.vue'\n\nimport type { SFCWithInstall } from '@element-plus/utils'\n\nexport const ElProgress: SFCWithInstall<typeof Progress> = withInstall(Progress)\nexport default ElProgress\n\nexport * from './src/progress'\n"],"mappings":";;;;;AAKA,MAAa,aAA8C,YAAYA,iBAAS"}
@@ -0,0 +1,103 @@
import { EpPropFinalized } from "../../../utils/vue/props/types.js";
import "../../../utils/index.js";
import { _default } from "./progress.vue.js";
import { ExtractPublicPropTypes, SVGAttributes } from "vue";
//#region ../../packages/components/progress/src/progress.d.ts
type ProgressColor = {
color: string;
percentage: number;
};
type ProgressFn = (percentage: number) => string;
interface ProgressProps {
/**
* @description type of progress bar
*/
type?: 'line' | 'circle' | 'dashboard';
/**
* @description percentage, required
*/
percentage?: number;
/**
* @description the current status of progress bar
*/
status?: '' | 'success' | 'exception' | 'warning';
/**
* @description set indeterminate progress
*/
indeterminate?: boolean;
/**
* @description control the animation duration of indeterminate progress or striped flow progress
*/
duration?: number;
/**
* @description the width of progress bar
*/
strokeWidth?: number;
/**
* @description butt/circle/dashboard type shape at the end path
*/
strokeLinecap?: NonNullable<SVGAttributes['stroke-linecap']>;
/**
* @description whether to place the percentage inside progress bar, only works when `type` is 'line'
*/
textInside?: boolean;
/**
* @description the canvas width of circle progress bar
*/
width?: number;
/**
* @description whether to show percentage
*/
showText?: boolean;
/**
* @description background color of progress bar. Overrides `status` prop
*/
color?: string | ProgressColor[] | ProgressFn;
/**
* @description stripe over the progress bar's color
*/
striped?: boolean;
/**
* @description get the stripes to flow
*/
stripedFlow?: boolean;
/**
* @description custom text format
*/
format?: ProgressFn;
}
/**
* @deprecated Removed after 3.0.0, Use `ProgressProps` instead.
*/
declare const progressProps: {
readonly type: EpPropFinalized<StringConstructor, "circle" | "line" | "dashboard", unknown, "line", boolean>;
readonly percentage: EpPropFinalized<NumberConstructor, unknown, unknown, 0, boolean>;
readonly status: EpPropFinalized<StringConstructor, "" | "success" | "warning" | "exception", unknown, "", boolean>;
readonly indeterminate: BooleanConstructor;
readonly duration: EpPropFinalized<NumberConstructor, unknown, unknown, 3, boolean>;
readonly strokeWidth: EpPropFinalized<NumberConstructor, unknown, unknown, 6, boolean>;
readonly strokeLinecap: EpPropFinalized<(new (...args: any[]) => "inherit" | "round" | "butt" | "square") | (() => NonNullable<"inherit" | "round" | "butt" | "square" | undefined>) | (((new (...args: any[]) => "inherit" | "round" | "butt" | "square") | (() => NonNullable<"inherit" | "round" | "butt" | "square" | undefined>)) | null)[], unknown, unknown, "round", boolean>;
readonly textInside: BooleanConstructor;
readonly width: EpPropFinalized<NumberConstructor, unknown, unknown, 126, boolean>;
readonly showText: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly color: EpPropFinalized<(new (...args: any[]) => string | ProgressColor[] | ProgressFn) | (() => string | ProgressColor[] | ProgressFn) | (((new (...args: any[]) => string | ProgressColor[] | ProgressFn) | (() => string | ProgressColor[] | ProgressFn)) | null)[], unknown, unknown, "", boolean>;
readonly striped: BooleanConstructor;
readonly stripedFlow: BooleanConstructor;
readonly format: EpPropFinalized<(new (...args: any[]) => ProgressFn) | (() => ProgressFn) | {
(): ProgressFn;
new (): any;
readonly prototype: any;
} | (((new (...args: any[]) => ProgressFn) | (() => ProgressFn) | {
(): ProgressFn;
new (): any;
readonly prototype: any;
}) | null)[], unknown, unknown, (percentage: number) => string, boolean>;
};
/**
* @deprecated Removed after 3.0.0, Use `ProgressProps` instead.
*/
type ProgressPropsPublic = ExtractPublicPropTypes<typeof progressProps>;
type ProgressInstance = InstanceType<typeof _default> & unknown;
//#endregion
export { ProgressColor, ProgressFn, ProgressInstance, ProgressProps, ProgressPropsPublic, progressProps };
@@ -0,0 +1,72 @@
import { buildProps, definePropType } from "../../../utils/vue/props/runtime.mjs";
//#region ../../packages/components/progress/src/progress.ts
/**
* @deprecated Removed after 3.0.0, Use `ProgressProps` instead.
*/
const progressProps = buildProps({
type: {
type: String,
default: "line",
values: [
"line",
"circle",
"dashboard"
]
},
percentage: {
type: Number,
default: 0,
validator: (val) => val >= 0 && val <= 100
},
status: {
type: String,
default: "",
values: [
"",
"success",
"exception",
"warning"
]
},
indeterminate: Boolean,
duration: {
type: Number,
default: 3
},
strokeWidth: {
type: Number,
default: 6
},
strokeLinecap: {
type: definePropType(String),
default: "round"
},
textInside: Boolean,
width: {
type: Number,
default: 126
},
showText: {
type: Boolean,
default: true
},
color: {
type: definePropType([
String,
Array,
Function
]),
default: ""
},
striped: Boolean,
stripedFlow: Boolean,
format: {
type: definePropType(Function),
default: (percentage) => `${percentage}%`
}
});
//#endregion
export { progressProps };
//# sourceMappingURL=progress.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,35 @@
import { ProgressColor, ProgressFn, ProgressProps } from "./progress.js";
import * as vue from "vue";
//#region ../../packages/components/progress/src/progress.vue.d.ts
declare var __VLS_1: {
percentage: number;
}, __VLS_3: {
percentage: number;
};
type __VLS_Slots = {} & {
default?: (props: typeof __VLS_1) => any;
} & {
default?: (props: typeof __VLS_3) => any;
};
declare const __VLS_base: vue.DefineComponent<ProgressProps, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<ProgressProps> & Readonly<{}>, {
type: "line" | "circle" | "dashboard";
color: string | ProgressColor[] | ProgressFn;
strokeLinecap: NonNullable<vue.SVGAttributes["stroke-linecap"]>;
strokeWidth: number;
width: number;
format: ProgressFn;
percentage: number;
status: "" | "success" | "exception" | "warning";
duration: number;
showText: boolean;
}, {}, {}, {}, string, vue.ComponentProvideOptions, false, {}, any>;
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
declare const _default: typeof __VLS_export;
type __VLS_WithSlots<T, S> = T & {
new (): {
$slots: S;
};
};
//#endregion
export { _default };
@@ -0,0 +1,182 @@
import { isFunction, isString } from "../../../utils/types.mjs";
import { useNamespace } from "../../../hooks/use-namespace/index.mjs";
import { ElIcon } from "../../icon/index.mjs";
import { progressProps } from "./progress.mjs";
import { Check, CircleCheck, CircleClose, Close, WarningFilled } from "@element-plus/icons-vue";
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, renderSlot, resolveDynamicComponent, toDisplayString, unref, withCtx } from "vue";
//#region ../../packages/components/progress/src/progress.vue?vue&type=script&setup=true&lang.ts
const _hoisted_1 = ["aria-valuenow"];
const _hoisted_2 = { viewBox: "0 0 100 100" };
const _hoisted_3 = [
"d",
"stroke",
"stroke-linecap",
"stroke-width"
];
const _hoisted_4 = [
"d",
"stroke",
"opacity",
"stroke-linecap",
"stroke-width"
];
const _hoisted_5 = { key: 0 };
var progress_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
name: "ElProgress",
__name: "progress",
props: progressProps,
setup(__props) {
const STATUS_COLOR_MAP = {
success: "#13ce66",
exception: "#ff4949",
warning: "#e6a23c",
default: "#20a0ff"
};
const props = __props;
const ns = useNamespace("progress");
const barStyle = computed(() => {
const barStyle = {
width: `${props.percentage}%`,
animationDuration: `${props.duration}s`
};
const color = getCurrentColor(props.percentage);
if (color.includes("gradient")) barStyle.background = color;
else barStyle.backgroundColor = color;
return barStyle;
});
const relativeStrokeWidth = computed(() => (props.strokeWidth / props.width * 100).toFixed(1));
const radius = computed(() => {
if (["circle", "dashboard"].includes(props.type)) return Number.parseInt(`${50 - Number.parseFloat(relativeStrokeWidth.value) / 2}`, 10);
return 0;
});
const trackPath = computed(() => {
const r = radius.value;
const isDashboard = props.type === "dashboard";
return `
M 50 50
m 0 ${isDashboard ? "" : "-"}${r}
a ${r} ${r} 0 1 1 0 ${isDashboard ? "-" : ""}${r * 2}
a ${r} ${r} 0 1 1 0 ${isDashboard ? "" : "-"}${r * 2}
`;
});
const perimeter = computed(() => 2 * Math.PI * radius.value);
const rate = computed(() => props.type === "dashboard" ? .75 : 1);
const strokeDashoffset = computed(() => {
return `${-1 * perimeter.value * (1 - rate.value) / 2}px`;
});
const trailPathStyle = computed(() => ({
strokeDasharray: `${perimeter.value * rate.value}px, ${perimeter.value}px`,
strokeDashoffset: strokeDashoffset.value
}));
const circlePathStyle = computed(() => ({
strokeDasharray: `${perimeter.value * rate.value * (props.percentage / 100)}px, ${perimeter.value}px`,
strokeDashoffset: strokeDashoffset.value,
transition: "stroke-dasharray 0.6s ease 0s, stroke 0.6s ease, opacity ease 0.6s"
}));
const stroke = computed(() => {
let ret;
if (props.color) ret = getCurrentColor(props.percentage);
else ret = STATUS_COLOR_MAP[props.status] || STATUS_COLOR_MAP.default;
return ret;
});
const statusIcon = computed(() => {
if (props.status === "warning") return WarningFilled;
if (props.type === "line") return props.status === "success" ? CircleCheck : CircleClose;
else return props.status === "success" ? Check : Close;
});
const progressTextSize = computed(() => {
return props.type === "line" ? 12 + props.strokeWidth * .4 : props.width * .111111 + 2;
});
const content = computed(() => props.format(props.percentage));
function getColors(color) {
const span = 100 / color.length;
return color.map((seriesColor, index) => {
if (isString(seriesColor)) return {
color: seriesColor,
percentage: (index + 1) * span
};
return seriesColor;
}).sort((a, b) => a.percentage - b.percentage);
}
const getCurrentColor = (percentage) => {
const { color } = props;
if (isFunction(color)) return color(percentage);
else if (isString(color)) return color;
else {
const colors = getColors(color);
for (const color of colors) if (color.percentage > percentage) return color.color;
return colors[colors.length - 1]?.color;
}
};
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass([
unref(ns).b(),
unref(ns).m(__props.type),
unref(ns).is(__props.status),
{
[unref(ns).m("without-text")]: !__props.showText,
[unref(ns).m("text-inside")]: __props.textInside
}
]),
role: "progressbar",
"aria-valuenow": __props.percentage,
"aria-valuemin": "0",
"aria-valuemax": "100"
}, [__props.type === "line" ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(unref(ns).b("bar"))
}, [createElementVNode("div", {
class: normalizeClass(unref(ns).be("bar", "outer")),
style: normalizeStyle({ height: `${__props.strokeWidth}px` })
}, [createElementVNode("div", {
class: normalizeClass([
unref(ns).be("bar", "inner"),
{ [unref(ns).bem("bar", "inner", "indeterminate")]: __props.indeterminate },
{ [unref(ns).bem("bar", "inner", "striped")]: __props.striped },
{ [unref(ns).bem("bar", "inner", "striped-flow")]: __props.stripedFlow }
]),
style: normalizeStyle(barStyle.value)
}, [(__props.showText || _ctx.$slots.default) && __props.textInside ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(unref(ns).be("bar", "innerText"))
}, [renderSlot(_ctx.$slots, "default", { percentage: __props.percentage }, () => [createElementVNode("span", null, toDisplayString(content.value), 1)])], 2)) : createCommentVNode("v-if", true)], 6)], 6)], 2)) : (openBlock(), createElementBlock("div", {
key: 1,
class: normalizeClass(unref(ns).b("circle")),
style: normalizeStyle({
height: `${__props.width}px`,
width: `${__props.width}px`
})
}, [(openBlock(), createElementBlock("svg", _hoisted_2, [createElementVNode("path", {
class: normalizeClass(unref(ns).be("circle", "track")),
d: trackPath.value,
stroke: `var(${unref(ns).cssVarName("fill-color-light")}, #e5e9f2)`,
"stroke-linecap": __props.strokeLinecap,
"stroke-width": relativeStrokeWidth.value,
fill: "none",
style: normalizeStyle(trailPathStyle.value)
}, null, 14, _hoisted_3), createElementVNode("path", {
class: normalizeClass(unref(ns).be("circle", "path")),
d: trackPath.value,
stroke: stroke.value,
fill: "none",
opacity: __props.percentage ? 1 : 0,
"stroke-linecap": __props.strokeLinecap,
"stroke-width": relativeStrokeWidth.value,
style: normalizeStyle(circlePathStyle.value)
}, null, 14, _hoisted_4)]))], 6)), (__props.showText || _ctx.$slots.default) && !__props.textInside ? (openBlock(), createElementBlock("div", {
key: 2,
class: normalizeClass(unref(ns).e("text")),
style: normalizeStyle({ fontSize: `${progressTextSize.value}px` })
}, [renderSlot(_ctx.$slots, "default", { percentage: __props.percentage }, () => [!__props.status ? (openBlock(), createElementBlock("span", _hoisted_5, toDisplayString(content.value), 1)) : (openBlock(), createBlock(unref(ElIcon), { key: 1 }, {
default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(statusIcon.value)))]),
_: 1
}))])], 6)) : createCommentVNode("v-if", true)], 10, _hoisted_1);
};
}
});
//#endregion
export { progress_vue_vue_type_script_setup_true_lang_default as default };
//# sourceMappingURL=progress.vue_vue_type_script_setup_true_lang.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
import progress_vue_vue_type_script_setup_true_lang_default from "./progress.vue_vue_type_script_setup_true_lang.mjs";
//#region ../../packages/components/progress/src/progress.vue
var progress_default = progress_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { progress_default as default };
//# sourceMappingURL=progress2.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
import "../../base/style/css.mjs";
import "element-plus/theme-chalk/el-progress.css";
@@ -0,0 +1,2 @@
import "../../base/style/index.mjs";
import "element-plus/theme-chalk/src/progress.scss";