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
@@ -0,0 +1,9 @@
import { SFCWithInstall } from "../../utils/vue/typescript.js";
import "../../utils/index.js";
import { CountdownEmits, CountdownInstance, CountdownProps, CountdownPropsPublic, countdownEmits, countdownProps } from "./src/countdown.js";
import { _default } from "./src/countdown.vue.js";
//#region ../../packages/components/countdown/index.d.ts
declare const ElCountdown: SFCWithInstall<typeof _default>;
//#endregion
export { CountdownEmits, CountdownInstance, CountdownProps, CountdownPropsPublic, ElCountdown, ElCountdown as default, countdownEmits, countdownProps };
+10
View File
@@ -0,0 +1,10 @@
import { withInstall } from "../../utils/vue/install.mjs";
import { countdownEmits, countdownProps } from "./src/countdown.mjs";
import countdown_default from "./src/countdown2.mjs";
//#region ../../packages/components/countdown/index.ts
const ElCountdown = withInstall(countdown_default);
//#endregion
export { ElCountdown, ElCountdown as default, countdownEmits, countdownProps };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","names":["Countdown"],"sources":["../../../../../packages/components/countdown/index.ts"],"sourcesContent":["import { withInstall } from '@element-plus/utils'\nimport Countdown from './src/countdown.vue'\n\nimport type { SFCWithInstall } from '@element-plus/utils'\n\nexport const ElCountdown: SFCWithInstall<typeof Countdown> =\n withInstall(Countdown)\nexport default ElCountdown\n\nexport * from './src/countdown'\n"],"mappings":";;;;;AAKA,MAAa,cACX,YAAYA,kBAAU"}
@@ -0,0 +1,62 @@
import { EpPropFinalized, EpPropMergeType } from "../../../utils/vue/props/types.js";
import "../../../utils/index.js";
import { _default } from "./countdown.vue.js";
import * as vue from "vue";
import { ExtractPublicPropTypes, StyleValue } from "vue";
import { Dayjs } from "dayjs";
//#region ../../packages/components/countdown/src/countdown.d.ts
interface CountdownProps {
/**
* @description Formatting the countdown display
*/
format?: string;
/**
* @description Sets the prefix of a countdown
*/
prefix?: string;
/**
* @description Sets the suffix of a countdown
*/
suffix?: string;
/**
* @description countdown titles
*/
title?: string;
/**
* @description target time
*/
value?: number | Dayjs;
/**
* @description Styles countdown values
*/
valueStyle?: StyleValue;
}
/**
* @deprecated Removed after 3.0.0, Use `CountdownProps` instead.
*/
declare const countdownProps: {
readonly format: EpPropFinalized<StringConstructor, unknown, unknown, "HH:mm:ss", boolean>;
readonly prefix: StringConstructor;
readonly suffix: StringConstructor;
readonly title: StringConstructor;
readonly value: EpPropFinalized<(new (...args: any[]) => number | Dayjs) | (() => number | Dayjs) | (((new (...args: any[]) => number | Dayjs) | (() => number | Dayjs)) | null)[], unknown, unknown, 0, boolean>;
readonly valueStyle: {
readonly type: vue.PropType<EpPropMergeType<(new (...args: any[]) => string | false | vue.CSSProperties | StyleValue[]) | (() => StyleValue) | (((new (...args: any[]) => string | false | vue.CSSProperties | StyleValue[]) | (() => StyleValue)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
};
/**
* @deprecated Removed after 3.0.0, Use `CountdownProps` instead.
*/
type CountdownPropsPublic = ExtractPublicPropTypes<typeof countdownProps>;
declare const countdownEmits: {
finish: () => boolean;
change: (value: number) => boolean;
};
type CountdownEmits = typeof countdownEmits;
type CountdownInstance = InstanceType<typeof _default> & unknown;
//#endregion
export { CountdownEmits, CountdownInstance, CountdownProps, CountdownPropsPublic, countdownEmits, countdownProps };
@@ -0,0 +1,34 @@
import { CHANGE_EVENT } from "../../../constants/event.mjs";
import { isNumber } from "../../../utils/types.mjs";
import { buildProps, definePropType } from "../../../utils/vue/props/runtime.mjs";
//#region ../../packages/components/countdown/src/countdown.ts
/**
* @deprecated Removed after 3.0.0, Use `CountdownProps` instead.
*/
const countdownProps = buildProps({
format: {
type: String,
default: "HH:mm:ss"
},
prefix: String,
suffix: String,
title: String,
value: {
type: definePropType([Number, Object]),
default: 0
},
valueStyle: { type: definePropType([
String,
Object,
Array
]) }
});
const countdownEmits = {
finish: () => true,
[CHANGE_EVENT]: (value) => isNumber(value)
};
//#endregion
export { countdownEmits, countdownProps };
//# sourceMappingURL=countdown.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"countdown.mjs","names":[],"sources":["../../../../../../packages/components/countdown/src/countdown.ts"],"sourcesContent":["import { buildProps, definePropType, isNumber } from '@element-plus/utils'\nimport { CHANGE_EVENT } from '@element-plus/constants'\n\nimport type { ExtractPublicPropTypes, StyleValue } from 'vue'\nimport type { Dayjs } from 'dayjs'\nimport type Countdown from './countdown.vue'\n\nexport interface CountdownProps {\n /**\n * @description Formatting the countdown display\n */\n format?: string\n /**\n * @description Sets the prefix of a countdown\n */\n prefix?: string\n /**\n * @description Sets the suffix of a countdown\n */\n suffix?: string\n /**\n * @description countdown titles\n */\n title?: string\n /**\n * @description target time\n */\n value?: number | Dayjs\n /**\n * @description Styles countdown values\n */\n valueStyle?: StyleValue\n}\n\n/**\n * @deprecated Removed after 3.0.0, Use `CountdownProps` instead.\n */\nexport const countdownProps = buildProps({\n /**\n * @description Formatting the countdown display\n */\n format: {\n type: String,\n default: 'HH:mm:ss',\n },\n /**\n * @description Sets the prefix of a countdown\n */\n prefix: String,\n /**\n * @description Sets the suffix of a countdown\n */\n suffix: String,\n /**\n * @description countdown titles\n */\n title: String,\n /**\n * @description target time\n */\n value: {\n type: definePropType<number | Dayjs>([Number, Object]),\n default: 0,\n },\n /**\n * @description Styles countdown values\n */\n valueStyle: {\n type: definePropType<StyleValue>([String, Object, Array]),\n },\n} as const)\n\n/**\n * @deprecated Removed after 3.0.0, Use `CountdownProps` instead.\n */\nexport type CountdownPropsPublic = ExtractPublicPropTypes<typeof countdownProps>\n\nexport const countdownEmits = {\n finish: () => true,\n [CHANGE_EVENT]: (value: number) => isNumber(value),\n}\nexport type CountdownEmits = typeof countdownEmits\n\nexport type CountdownInstance = InstanceType<typeof Countdown> & unknown\n"],"mappings":";;;;;;;;AAqCA,MAAa,iBAAiB,WAAW;CAIvC,QAAQ;EACN,MAAM;EACN,SAAS;EACV;CAID,QAAQ;CAIR,QAAQ;CAIR,OAAO;CAIP,OAAO;EACL,MAAM,eAA+B,CAAC,QAAQ,OAAO,CAAC;EACtD,SAAS;EACV;CAID,YAAY,EACV,MAAM,eAA2B;EAAC;EAAQ;EAAQ;EAAM,CAAC,EAC1D;CACF,CAAU;AAOX,MAAa,iBAAiB;CAC5B,cAAc;EACb,gBAAgB,UAAkB,SAAS,MAAM;CACnD"}
@@ -0,0 +1,32 @@
import { CountdownProps } from "./countdown.js";
import * as vue from "vue";
import * as dayjs$1 from "dayjs";
//#region ../../packages/components/countdown/src/countdown.vue.d.ts
declare var __VLS_10: string, __VLS_11: {};
type __VLS_Slots = {} & { [K in NonNullable<typeof __VLS_10>]?: (props: typeof __VLS_11) => any };
declare const __VLS_base: vue.DefineComponent<CountdownProps, {
/**
* @description current display value
*/
displayValue: vue.ComputedRef<string>;
}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
change: (value: number) => void;
finish: () => void;
}, string, vue.PublicProps, Readonly<CountdownProps> & Readonly<{
onChange?: ((value: number) => any) | undefined;
onFinish?: (() => any) | undefined;
}>, {
value: number | dayjs$1.Dayjs;
format: string;
valueStyle: string | false | vue.CSSProperties | vue.StyleValue[] | null;
}, {}, {}, {}, 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,78 @@
import { CHANGE_EVENT } from "../../../constants/event.mjs";
import { cAF, rAF } from "../../../utils/raf.mjs";
import { ElStatistic } from "../../statistic/index.mjs";
import { countdownEmits, countdownProps } from "./countdown.mjs";
import { formatTime, getTime } from "./utils.mjs";
import { computed, createBlock, createSlots, defineComponent, onBeforeUnmount, onMounted, openBlock, ref, renderList, renderSlot, unref, watch, withCtx } from "vue";
//#region ../../packages/components/countdown/src/countdown.vue?vue&type=script&setup=true&lang.ts
var countdown_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
name: "ElCountdown",
__name: "countdown",
props: countdownProps,
emits: countdownEmits,
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const emit = __emit;
let timer;
const rawValue = ref(0);
const displayValue = computed(() => formatTime(rawValue.value, props.format));
const formatter = (val) => formatTime(val, props.format);
const stopTimer = () => {
if (timer) {
cAF(timer);
timer = void 0;
}
};
const startTimer = () => {
const timestamp = getTime(props.value);
const frameFunc = () => {
let diff = timestamp - Date.now();
emit(CHANGE_EVENT, diff);
if (diff <= 0) {
diff = 0;
stopTimer();
emit("finish");
} else timer = rAF(frameFunc);
rawValue.value = diff;
};
timer = rAF(frameFunc);
};
onMounted(() => {
rawValue.value = getTime(props.value) - Date.now();
watch(() => [props.value, props.format], () => {
stopTimer();
startTimer();
}, { immediate: true });
});
onBeforeUnmount(() => {
stopTimer();
});
__expose({ displayValue });
return (_ctx, _cache) => {
return openBlock(), createBlock(unref(ElStatistic), {
value: rawValue.value,
title: __props.title,
prefix: __props.prefix,
suffix: __props.suffix,
"value-style": __props.valueStyle,
formatter
}, createSlots({ _: 2 }, [renderList(_ctx.$slots, (_, name) => {
return {
name,
fn: withCtx(() => [renderSlot(_ctx.$slots, name)])
};
})]), 1032, [
"value",
"title",
"prefix",
"suffix",
"value-style"
]);
};
}
});
//#endregion
export { countdown_vue_vue_type_script_setup_true_lang_default as default };
//# sourceMappingURL=countdown.vue_vue_type_script_setup_true_lang.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"countdown.vue_vue_type_script_setup_true_lang.mjs","names":["$slots"],"sources":["../../../../../../packages/components/countdown/src/countdown.vue"],"sourcesContent":["<template>\n <el-statistic\n :value=\"rawValue\"\n :title=\"title\"\n :prefix=\"prefix\"\n :suffix=\"suffix\"\n :value-style=\"valueStyle\"\n :formatter=\"formatter\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]>\n <slot :name=\"name\" />\n </template>\n </el-statistic>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { ElStatistic } from '@element-plus/components/statistic'\nimport { cAF, rAF } from '@element-plus/utils'\nimport { CHANGE_EVENT } from '@element-plus/constants'\nimport { countdownEmits } from './countdown'\nimport { formatTime, getTime } from './utils'\n\nimport type { CountdownProps } from './countdown'\n\ndefineOptions({\n name: 'ElCountdown',\n})\nconst props = withDefaults(defineProps<CountdownProps>(), {\n format: 'HH:mm:ss',\n value: 0,\n valueStyle: undefined,\n})\nconst emit = defineEmits(countdownEmits)\n\nlet timer: ReturnType<typeof rAF> | undefined\nconst rawValue = ref<number>(0)\nconst displayValue = computed(() => formatTime(rawValue.value, props.format))\n\nconst formatter = (val: number) => formatTime(val, props.format)\n\nconst stopTimer = () => {\n if (timer) {\n cAF(timer)\n timer = undefined\n }\n}\n\nconst startTimer = () => {\n const timestamp = getTime(props.value)\n const frameFunc = () => {\n let diff = timestamp - Date.now()\n emit(CHANGE_EVENT, diff)\n if (diff <= 0) {\n diff = 0\n stopTimer()\n emit('finish')\n } else {\n timer = rAF(frameFunc)\n }\n rawValue.value = diff\n }\n timer = rAF(frameFunc)\n}\n\nonMounted(() => {\n rawValue.value = getTime(props.value) - Date.now()\n\n watch(\n () => [props.value, props.format],\n () => {\n stopTimer()\n startTimer()\n },\n {\n immediate: true,\n }\n )\n})\n\nonBeforeUnmount(() => {\n stopTimer()\n})\n\ndefineExpose({\n /**\n * @description current display value\n */\n displayValue,\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;EA4BA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,IAAI;EACJ,MAAM,WAAW,IAAY,EAAC;EAC9B,MAAM,eAAe,eAAe,WAAW,SAAS,OAAO,MAAM,OAAO,CAAA;EAE5E,MAAM,aAAa,QAAgB,WAAW,KAAK,MAAM,OAAM;EAE/D,MAAM,kBAAkB;AACtB,OAAI,OAAO;AACT,QAAI,MAAK;AACT,YAAQ;;;EAIZ,MAAM,mBAAmB;GACvB,MAAM,YAAY,QAAQ,MAAM,MAAK;GACrC,MAAM,kBAAkB;IACtB,IAAI,OAAO,YAAY,KAAK,KAAI;AAChC,SAAK,cAAc,KAAI;AACvB,QAAI,QAAQ,GAAG;AACb,YAAO;AACP,gBAAU;AACV,UAAK,SAAQ;UAEb,SAAQ,IAAI,UAAS;AAEvB,aAAS,QAAQ;;AAEnB,WAAQ,IAAI,UAAS;;AAGvB,kBAAgB;AACd,YAAS,QAAQ,QAAQ,MAAM,MAAM,GAAG,KAAK,KAAI;AAEjD,eACQ,CAAC,MAAM,OAAO,MAAM,OAAO,QAC3B;AACJ,eAAU;AACV,gBAAW;MAEb,EACE,WAAW,MACb,CACF;IACD;AAED,wBAAsB;AACpB,cAAU;IACX;AAED,WAAa,EAIX,cACD,CAAA;;uBAxFC,YAWe,MAAA,YAAA,EAAA;IAVZ,OAAO,SAAA;IACP,OAAO,QAAA;IACP,QAAQ,QAAA;IACR,QAAQ,QAAA;IACR,eAAa,QAAA;IACF;wCAEkBA,KAAAA,SAAZ,GAAG,SAAI;;KAAc;uBAChB,CAArB,WAAqB,KAAA,QAAR,KAAI"}
@@ -0,0 +1,8 @@
import countdown_vue_vue_type_script_setup_true_lang_default from "./countdown.vue_vue_type_script_setup_true_lang.mjs";
//#region ../../packages/components/countdown/src/countdown.vue
var countdown_default = countdown_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { countdown_default as default };
//# sourceMappingURL=countdown2.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"countdown2.mjs","names":[],"sources":["../../../../../../packages/components/countdown/src/countdown.vue"],"sourcesContent":["<template>\n <el-statistic\n :value=\"rawValue\"\n :title=\"title\"\n :prefix=\"prefix\"\n :suffix=\"suffix\"\n :value-style=\"valueStyle\"\n :formatter=\"formatter\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]>\n <slot :name=\"name\" />\n </template>\n </el-statistic>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { ElStatistic } from '@element-plus/components/statistic'\nimport { cAF, rAF } from '@element-plus/utils'\nimport { CHANGE_EVENT } from '@element-plus/constants'\nimport { countdownEmits } from './countdown'\nimport { formatTime, getTime } from './utils'\n\nimport type { CountdownProps } from './countdown'\n\ndefineOptions({\n name: 'ElCountdown',\n})\nconst props = withDefaults(defineProps<CountdownProps>(), {\n format: 'HH:mm:ss',\n value: 0,\n valueStyle: undefined,\n})\nconst emit = defineEmits(countdownEmits)\n\nlet timer: ReturnType<typeof rAF> | undefined\nconst rawValue = ref<number>(0)\nconst displayValue = computed(() => formatTime(rawValue.value, props.format))\n\nconst formatter = (val: number) => formatTime(val, props.format)\n\nconst stopTimer = () => {\n if (timer) {\n cAF(timer)\n timer = undefined\n }\n}\n\nconst startTimer = () => {\n const timestamp = getTime(props.value)\n const frameFunc = () => {\n let diff = timestamp - Date.now()\n emit(CHANGE_EVENT, diff)\n if (diff <= 0) {\n diff = 0\n stopTimer()\n emit('finish')\n } else {\n timer = rAF(frameFunc)\n }\n rawValue.value = diff\n }\n timer = rAF(frameFunc)\n}\n\nonMounted(() => {\n rawValue.value = getTime(props.value) - Date.now()\n\n watch(\n () => [props.value, props.format],\n () => {\n stopTimer()\n startTimer()\n },\n {\n immediate: true,\n }\n )\n})\n\nonBeforeUnmount(() => {\n stopTimer()\n})\n\ndefineExpose({\n /**\n * @description current display value\n */\n displayValue,\n})\n</script>\n"],"mappings":""}
@@ -0,0 +1,31 @@
import { isNumber } from "../../../utils/types.mjs";
//#region ../../packages/components/countdown/src/utils.ts
const timeUnits = [
["Y", 1e3 * 60 * 60 * 24 * 365],
["M", 1e3 * 60 * 60 * 24 * 30],
["D", 1e3 * 60 * 60 * 24],
["H", 1e3 * 60 * 60],
["m", 1e3 * 60],
["s", 1e3],
["S", 1]
];
const getTime = (value) => {
return isNumber(value) ? new Date(value).getTime() : value.valueOf();
};
const formatTime = (timestamp, format) => {
let timeLeft = timestamp;
return timeUnits.reduce((current, [name, unit]) => {
const replaceRegex = new RegExp(`${name}+(?![^\\[\\]]*\\])`, "g");
if (replaceRegex.test(current)) {
const value = Math.floor(timeLeft / unit);
timeLeft -= value * unit;
return current.replace(replaceRegex, (match) => String(value).padStart(match.length, "0"));
}
return current;
}, format).replace(/\[([^\]]*)]/g, "$1");
};
//#endregion
export { formatTime, getTime };
//# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../../../../packages/components/countdown/src/utils.ts"],"sourcesContent":["import { isNumber } from '@element-plus/utils'\n\nimport type { Dayjs } from 'dayjs'\n\nconst timeUnits = [\n ['Y', 1000 * 60 * 60 * 24 * 365], // years\n ['M', 1000 * 60 * 60 * 24 * 30], // months\n ['D', 1000 * 60 * 60 * 24], // days\n ['H', 1000 * 60 * 60], // hours\n ['m', 1000 * 60], // minutes\n ['s', 1000], // seconds\n ['S', 1], // million seconds\n] as const\n\nexport const getTime = (value: number | Dayjs) => {\n return isNumber(value) ? new Date(value).getTime() : value.valueOf()\n}\n\nexport const formatTime = (timestamp: number, format: string) => {\n let timeLeft = timestamp\n const escapeRegex = /\\[([^\\]]*)]/g\n\n const replacedText = timeUnits.reduce((current, [name, unit]) => {\n const replaceRegex = new RegExp(`${name}+(?![^\\\\[\\\\]]*\\\\])`, 'g')\n if (replaceRegex.test(current)) {\n const value = Math.floor(timeLeft / unit)\n timeLeft -= value * unit\n return current.replace(replaceRegex, (match) =>\n String(value).padStart(match.length, '0')\n )\n }\n return current\n }, format)\n\n return replacedText.replace(escapeRegex, '$1')\n}\n"],"mappings":";;;AAIA,MAAM,YAAY;CAChB,CAAC,KAAK,MAAO,KAAK,KAAK,KAAK,IAAI;CAChC,CAAC,KAAK,MAAO,KAAK,KAAK,KAAK,GAAG;CAC/B,CAAC,KAAK,MAAO,KAAK,KAAK,GAAG;CAC1B,CAAC,KAAK,MAAO,KAAK,GAAG;CACrB,CAAC,KAAK,MAAO,GAAG;CAChB,CAAC,KAAK,IAAK;CACX,CAAC,KAAK,EAAE;CACT;AAED,MAAa,WAAW,UAA0B;AAChD,QAAO,SAAS,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC,SAAS,GAAG,MAAM,SAAS;;AAGtE,MAAa,cAAc,WAAmB,WAAmB;CAC/D,IAAI,WAAW;AAef,QAZqB,UAAU,QAAQ,SAAS,CAAC,MAAM,UAAU;EAC/D,MAAM,eAAe,IAAI,OAAO,GAAG,KAAK,qBAAqB,IAAI;AACjE,MAAI,aAAa,KAAK,QAAQ,EAAE;GAC9B,MAAM,QAAQ,KAAK,MAAM,WAAW,KAAK;AACzC,eAAY,QAAQ;AACpB,UAAO,QAAQ,QAAQ,eAAe,UACpC,OAAO,MAAM,CAAC,SAAS,MAAM,QAAQ,IAAI,CAC1C;;AAEH,SAAO;IACN,OAAO,CAEU,QAdA,gBAcqB,KAAK"}
@@ -0,0 +1,2 @@
import "../../base/style/css.mjs";
import "element-plus/theme-chalk/el-statistic.css";
@@ -0,0 +1,2 @@
import "../../base/style/index.mjs";
import "element-plus/theme-chalk/src/statistic.scss";