@aspire-ui/element-component-pro 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/ProForm/FormattedNumberInput.vue.d.ts +55 -0
- package/dist/ProForm/ProForm.vue.d.ts +7 -0
- package/dist/ProForm/ProFormItem.vue.d.ts +2 -0
- package/dist/ProForm/index.d.ts +2 -1
- package/dist/element-component-pro.es.js +966 -759
- package/dist/element-component-pro.es.js.map +1 -1
- package/dist/element-component-pro.umd.js +2 -2
- package/dist/element-component-pro.umd.js.map +1 -1
- package/dist/index.d.ts +130 -50
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +13 -2
- package/dist/utils/formattedNumber.d.ts +16 -0
- package/dist/utils/tooltip.d.ts +4 -0
- package/package.json +2 -1
- package/src/ProDescriptions/ProDescriptions.vue +24 -6
- package/src/ProForm/FormattedNumberInput.vue +122 -0
- package/src/ProForm/ProForm.vue +3 -1
- package/src/ProForm/ProFormItem.vue +155 -123
- package/src/ProForm/index.ts +2 -1
- package/src/ProTable/TableAction.vue +2 -5
- package/src/index.ts +5 -2
- package/src/types/index.ts +9 -1
- package/src/utils/formattedNumber.ts +118 -0
- package/src/utils/tooltip.ts +56 -0
- package/src/vite-env.d.ts +5 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/** 进位方式:向下取整、向上取整、四舍五入 */
|
|
2
|
+
export type FormattedNumberRounding = 'floor' | 'ceil' | 'round'
|
|
3
|
+
|
|
4
|
+
/** 仅保留数字、至多一个小数点、可选前导负号 */
|
|
5
|
+
export function sanitizeNumericInput(raw: string): string {
|
|
6
|
+
const t = raw.trim()
|
|
7
|
+
if (!t) return ''
|
|
8
|
+
let i = 0
|
|
9
|
+
let res = ''
|
|
10
|
+
if (t[0] === '-') {
|
|
11
|
+
res = '-'
|
|
12
|
+
i = 1
|
|
13
|
+
}
|
|
14
|
+
let dot = false
|
|
15
|
+
for (; i < t.length; i++) {
|
|
16
|
+
const c = t[i]
|
|
17
|
+
if (c >= '0' && c <= '9') {
|
|
18
|
+
res += c
|
|
19
|
+
continue
|
|
20
|
+
}
|
|
21
|
+
if (c === '.' && !dot) {
|
|
22
|
+
dot = true
|
|
23
|
+
if (res === '' || res === '-') res += '0'
|
|
24
|
+
res += '.'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return res
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function stripNumberGrouping(s: string): string {
|
|
31
|
+
return s.replace(/,/g, '').trim()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function maxAbsValue(integerDigits: number, decimalPlaces: number): number {
|
|
35
|
+
const maxInt = Math.pow(10, integerDigits) - 1
|
|
36
|
+
if (decimalPlaces <= 0) return maxInt
|
|
37
|
+
return maxInt + (1 - Math.pow(10, -decimalPlaces))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** 按整数位数上限约束绝对值 */
|
|
41
|
+
export function clampByIntegerDigits(
|
|
42
|
+
value: number,
|
|
43
|
+
integerDigits: number,
|
|
44
|
+
decimalPlaces: number
|
|
45
|
+
): number {
|
|
46
|
+
const max = maxAbsValue(integerDigits, decimalPlaces)
|
|
47
|
+
const sign = value < 0 ? -1 : 1
|
|
48
|
+
const abs = Math.abs(value)
|
|
49
|
+
if (abs <= max) return value
|
|
50
|
+
return sign * max
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function roundToDecimals(
|
|
54
|
+
value: number,
|
|
55
|
+
decimalPlaces: number,
|
|
56
|
+
rounding: FormattedNumberRounding
|
|
57
|
+
): number {
|
|
58
|
+
if (decimalPlaces <= 0) {
|
|
59
|
+
switch (rounding) {
|
|
60
|
+
case 'floor':
|
|
61
|
+
return Math.floor(value)
|
|
62
|
+
case 'ceil':
|
|
63
|
+
return Math.ceil(value)
|
|
64
|
+
default:
|
|
65
|
+
return Math.round(value)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const factor = Math.pow(10, decimalPlaces)
|
|
69
|
+
const x = value * factor
|
|
70
|
+
let y: number
|
|
71
|
+
switch (rounding) {
|
|
72
|
+
case 'floor':
|
|
73
|
+
y = Math.floor(x)
|
|
74
|
+
break
|
|
75
|
+
case 'ceil':
|
|
76
|
+
y = Math.ceil(x)
|
|
77
|
+
break
|
|
78
|
+
default:
|
|
79
|
+
y = Math.round(x)
|
|
80
|
+
}
|
|
81
|
+
return y / factor
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 解析 → 按整数位夹紧 → 按小数位与进位方式舍入 → 再夹紧(防止舍入后越界)
|
|
86
|
+
*/
|
|
87
|
+
export function normalizeNumericValue(
|
|
88
|
+
value: number,
|
|
89
|
+
integerDigits: number,
|
|
90
|
+
decimalPlaces: number,
|
|
91
|
+
rounding: FormattedNumberRounding
|
|
92
|
+
): number {
|
|
93
|
+
let v = clampByIntegerDigits(value, integerDigits, decimalPlaces)
|
|
94
|
+
v = roundToDecimals(v, decimalPlaces, rounding)
|
|
95
|
+
v = clampByIntegerDigits(v, integerDigits, decimalPlaces)
|
|
96
|
+
return v
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 千分位格式化展示(整数部分),小数部分固定 m 位 */
|
|
100
|
+
export function formatWithThousands(value: number, decimalPlaces: number): string {
|
|
101
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) return ''
|
|
102
|
+
const fixed = value.toFixed(Math.max(0, decimalPlaces))
|
|
103
|
+
const neg = fixed.startsWith('-')
|
|
104
|
+
const body = neg ? fixed.slice(1) : fixed
|
|
105
|
+
const [intPart, decPart] = body.split('.')
|
|
106
|
+
const withSep = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|
107
|
+
if (decimalPlaces <= 0 || decPart === undefined) return (neg ? '-' : '') + withSep
|
|
108
|
+
return (neg ? '-' : '') + withSep + '.' + decPart
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** 编辑态:无千分位,去掉多余尾部 0(在 m 位精度内) */
|
|
112
|
+
export function numberToEditString(value: number, decimalPlaces: number): string {
|
|
113
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) return ''
|
|
114
|
+
let s = value.toFixed(Math.max(0, decimalPlaces))
|
|
115
|
+
s = s.replace(/(\.\d*?)0+$/, '$1')
|
|
116
|
+
s = s.replace(/\.$/, '')
|
|
117
|
+
return s
|
|
118
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export type TooltipValue = boolean | string | Record<string, unknown>
|
|
2
|
+
|
|
3
|
+
export const hasTooltipContent = (value: unknown): boolean => {
|
|
4
|
+
if (Array.isArray(value)) return value.length > 0
|
|
5
|
+
return value !== undefined && value !== null && String(value).trim() !== ''
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const getTooltipContent = (value: unknown): string => {
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
return value.map((item) => String(item)).join(', ')
|
|
11
|
+
}
|
|
12
|
+
if (value === undefined || value === null) return ''
|
|
13
|
+
if (typeof value === 'object') return JSON.stringify(value)
|
|
14
|
+
return String(value)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const normalizeTooltipConfig = (
|
|
18
|
+
tooltip: TooltipValue | null | undefined,
|
|
19
|
+
fallbackValue?: unknown
|
|
20
|
+
): Record<string, unknown> | null => {
|
|
21
|
+
if (!tooltip) return null
|
|
22
|
+
|
|
23
|
+
if (tooltip === true) {
|
|
24
|
+
return {
|
|
25
|
+
content: getTooltipContent(fallbackValue),
|
|
26
|
+
placement: 'top',
|
|
27
|
+
effect: 'dark',
|
|
28
|
+
disabled: !hasTooltipContent(fallbackValue),
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (typeof tooltip === 'string') {
|
|
33
|
+
return {
|
|
34
|
+
content: tooltip,
|
|
35
|
+
placement: 'top',
|
|
36
|
+
effect: 'dark',
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const normalized = { ...tooltip }
|
|
41
|
+
const hasExplicitContent = Object.prototype.hasOwnProperty.call(normalized, 'content')
|
|
42
|
+
if (!hasExplicitContent) {
|
|
43
|
+
normalized.content = getTooltipContent(fallbackValue)
|
|
44
|
+
}
|
|
45
|
+
if (!Object.prototype.hasOwnProperty.call(normalized, 'placement')) {
|
|
46
|
+
normalized.placement = 'top'
|
|
47
|
+
}
|
|
48
|
+
if (!Object.prototype.hasOwnProperty.call(normalized, 'effect')) {
|
|
49
|
+
normalized.effect = 'dark'
|
|
50
|
+
}
|
|
51
|
+
if (!Object.prototype.hasOwnProperty.call(normalized, 'disabled')) {
|
|
52
|
+
normalized.disabled = !hasTooltipContent(normalized.content)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return normalized
|
|
56
|
+
}
|