@aspire-ui/element-component-pro 1.0.6 → 1.0.7
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 +21 -0
- package/dist/ProForm/ProForm.vue.d.ts +7 -0
- package/dist/ProForm/ProFormItem.vue.d.ts +2 -0
- package/dist/element-component-pro.es.js +758 -723
- 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 +52 -24
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +11 -0
- package/dist/utils/tooltip.d.ts +4 -0
- package/package.json +2 -1
- package/src/ProDescriptions/ProDescriptions.vue +24 -6
- package/src/ProForm/ProForm.vue +3 -1
- package/src/ProForm/ProFormItem.vue +144 -123
- package/src/ProTable/TableAction.vue +2 -5
- package/src/types/index.ts +7 -0
- package/src/utils/tooltip.ts +56 -0
- package/src/vite-env.d.ts +5 -0
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
:label-width="schema.labelWidth"
|
|
9
9
|
>
|
|
10
10
|
<template slot="label">
|
|
11
|
-
<span>
|
|
11
|
+
<span>
|
|
12
|
+
{{ schema.label }}<span v-if="showColon" class="ecp-pro-form-item__colon">:</span>
|
|
13
|
+
</span>
|
|
12
14
|
<el-tooltip
|
|
13
15
|
v-if="schema.helpMessage"
|
|
14
16
|
placement="top"
|
|
@@ -35,131 +37,133 @@
|
|
|
35
37
|
<!-- 默认组件渲染 -->
|
|
36
38
|
<template v-else>
|
|
37
39
|
<!-- 自定义 component:组件名或内联组件 -->
|
|
38
|
-
<component
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<el-input
|
|
49
|
-
v-else-if="schema.component === 'input' || !schema.component"
|
|
50
|
-
v-model="formModel[schema.field]"
|
|
51
|
-
:placeholder="schema.placeholder || (autoPlaceholder ? `请输入${schema.label}` : undefined)"
|
|
52
|
-
:disabled="effectiveDisabled"
|
|
53
|
-
v-bind="effectiveComponentProps"
|
|
54
|
-
v-on="effectiveComponentListeners"
|
|
55
|
-
/>
|
|
56
|
-
<el-input-number
|
|
57
|
-
v-else-if="schema.component === 'input-number'"
|
|
58
|
-
v-model="formModel[schema.field]"
|
|
59
|
-
:placeholder="schema.placeholder"
|
|
60
|
-
:disabled="effectiveDisabled"
|
|
61
|
-
v-bind="effectiveComponentProps"
|
|
62
|
-
v-on="effectiveComponentListeners"
|
|
63
|
-
/>
|
|
64
|
-
<el-select
|
|
65
|
-
class="ecp-pro-form-item__select"
|
|
66
|
-
v-else-if="schema.component === 'select'"
|
|
67
|
-
v-model="formModel[schema.field]"
|
|
68
|
-
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
69
|
-
:disabled="effectiveDisabled"
|
|
70
|
-
v-bind="effectiveComponentProps"
|
|
71
|
-
v-on="effectiveComponentListeners"
|
|
72
|
-
>
|
|
73
|
-
<el-option
|
|
74
|
-
v-for="opt in (getOptions(effectiveComponentProps) || [])"
|
|
75
|
-
:key="String(opt.value)"
|
|
76
|
-
:label="opt.label"
|
|
77
|
-
:value="opt.value"
|
|
40
|
+
<component :is="fieldWrapperComponent" v-bind="fieldWrapperProps">
|
|
41
|
+
<component
|
|
42
|
+
v-if="resolvedCustomComponent"
|
|
43
|
+
:is="resolvedCustomComponent"
|
|
44
|
+
:value="formModel[schema.field]"
|
|
45
|
+
@input="setFieldValue"
|
|
46
|
+
:placeholder="schema.placeholder || (autoPlaceholder ? `请输入${schema.label}` : undefined)"
|
|
47
|
+
:disabled="effectiveDisabled"
|
|
48
|
+
v-bind="effectiveComponentProps"
|
|
49
|
+
v-on="effectiveComponentListeners"
|
|
78
50
|
/>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
v-bind="effectiveComponentProps"
|
|
104
|
-
v-on="effectiveComponentListeners"
|
|
105
|
-
/>
|
|
106
|
-
<el-date-picker
|
|
107
|
-
v-else-if="schema.component === 'date-range'"
|
|
108
|
-
v-model="formModel[schema.field]"
|
|
109
|
-
type="daterange"
|
|
110
|
-
range-separator="至"
|
|
111
|
-
start-placeholder="开始日期"
|
|
112
|
-
end-placeholder="结束日期"
|
|
113
|
-
value-format="yyyy-MM-dd"
|
|
114
|
-
:disabled="effectiveDisabled"
|
|
115
|
-
v-bind="effectiveComponentProps"
|
|
116
|
-
v-on="effectiveComponentListeners"
|
|
117
|
-
/>
|
|
118
|
-
<el-switch
|
|
119
|
-
v-else-if="schema.component === 'switch'"
|
|
120
|
-
v-model="formModel[schema.field]"
|
|
121
|
-
:disabled="effectiveDisabled"
|
|
122
|
-
v-bind="effectiveComponentProps"
|
|
123
|
-
v-on="effectiveComponentListeners"
|
|
124
|
-
/>
|
|
125
|
-
<el-cascader
|
|
126
|
-
v-else-if="schema.component === 'cascader'"
|
|
127
|
-
v-model="formModel[schema.field]"
|
|
128
|
-
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
129
|
-
:disabled="effectiveDisabled"
|
|
130
|
-
v-bind="effectiveComponentProps"
|
|
131
|
-
v-on="effectiveComponentListeners"
|
|
132
|
-
/>
|
|
133
|
-
<el-checkbox-group
|
|
134
|
-
v-else-if="schema.component === 'checkbox'"
|
|
135
|
-
v-model="formModel[schema.field]"
|
|
136
|
-
:disabled="effectiveDisabled"
|
|
137
|
-
v-bind="effectiveComponentProps"
|
|
138
|
-
v-on="effectiveComponentListeners"
|
|
139
|
-
>
|
|
140
|
-
<el-checkbox
|
|
141
|
-
v-for="opt in (getOptions(effectiveComponentProps) || [])"
|
|
142
|
-
:key="String(opt.value)"
|
|
143
|
-
:label="opt.value"
|
|
51
|
+
<el-input
|
|
52
|
+
v-else-if="schema.component === 'input' || !schema.component"
|
|
53
|
+
v-model="formModel[schema.field]"
|
|
54
|
+
:placeholder="schema.placeholder || (autoPlaceholder ? `请输入${schema.label}` : undefined)"
|
|
55
|
+
:disabled="effectiveDisabled"
|
|
56
|
+
v-bind="effectiveComponentProps"
|
|
57
|
+
v-on="effectiveComponentListeners"
|
|
58
|
+
/>
|
|
59
|
+
<el-input-number
|
|
60
|
+
v-else-if="schema.component === 'input-number'"
|
|
61
|
+
v-model="formModel[schema.field]"
|
|
62
|
+
:placeholder="schema.placeholder"
|
|
63
|
+
:disabled="effectiveDisabled"
|
|
64
|
+
v-bind="effectiveComponentProps"
|
|
65
|
+
v-on="effectiveComponentListeners"
|
|
66
|
+
/>
|
|
67
|
+
<el-select
|
|
68
|
+
class="ecp-pro-form-item__select"
|
|
69
|
+
v-else-if="schema.component === 'select'"
|
|
70
|
+
v-model="formModel[schema.field]"
|
|
71
|
+
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
72
|
+
:disabled="effectiveDisabled"
|
|
73
|
+
v-bind="effectiveComponentProps"
|
|
74
|
+
v-on="effectiveComponentListeners"
|
|
144
75
|
>
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
76
|
+
<el-option
|
|
77
|
+
v-for="opt in (getOptions(effectiveComponentProps) || [])"
|
|
78
|
+
:key="String(opt.value)"
|
|
79
|
+
:label="opt.label"
|
|
80
|
+
:value="opt.value"
|
|
81
|
+
/>
|
|
82
|
+
</el-select>
|
|
83
|
+
<ApiSelect
|
|
84
|
+
v-else-if="schema.component === 'api-select'"
|
|
85
|
+
:value="formModel[schema.field]"
|
|
86
|
+
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
87
|
+
:disabled="effectiveDisabled"
|
|
88
|
+
v-bind="effectiveComponentProps"
|
|
89
|
+
v-on="effectiveComponentListeners"
|
|
90
|
+
@input="setFieldValue"
|
|
91
|
+
/>
|
|
92
|
+
<TreeSelect
|
|
93
|
+
v-else-if="schema.component === 'tree-select'"
|
|
94
|
+
:value="formModel[schema.field]"
|
|
95
|
+
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
96
|
+
:disabled="effectiveDisabled"
|
|
97
|
+
v-bind="effectiveComponentProps"
|
|
98
|
+
v-on="effectiveComponentListeners"
|
|
99
|
+
@input="setFieldValue"
|
|
100
|
+
/>
|
|
101
|
+
<el-date-picker
|
|
102
|
+
v-else-if="schema.component === 'date-picker'"
|
|
103
|
+
v-model="formModel[schema.field]"
|
|
104
|
+
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
105
|
+
:disabled="effectiveDisabled"
|
|
106
|
+
v-bind="effectiveComponentProps"
|
|
107
|
+
v-on="effectiveComponentListeners"
|
|
108
|
+
/>
|
|
109
|
+
<el-date-picker
|
|
110
|
+
v-else-if="schema.component === 'date-range'"
|
|
111
|
+
v-model="formModel[schema.field]"
|
|
112
|
+
type="daterange"
|
|
113
|
+
range-separator="至"
|
|
114
|
+
start-placeholder="开始日期"
|
|
115
|
+
end-placeholder="结束日期"
|
|
116
|
+
value-format="yyyy-MM-dd"
|
|
117
|
+
:disabled="effectiveDisabled"
|
|
118
|
+
v-bind="effectiveComponentProps"
|
|
119
|
+
v-on="effectiveComponentListeners"
|
|
120
|
+
/>
|
|
121
|
+
<el-switch
|
|
122
|
+
v-else-if="schema.component === 'switch'"
|
|
123
|
+
v-model="formModel[schema.field]"
|
|
124
|
+
:disabled="effectiveDisabled"
|
|
125
|
+
v-bind="effectiveComponentProps"
|
|
126
|
+
v-on="effectiveComponentListeners"
|
|
127
|
+
/>
|
|
128
|
+
<el-cascader
|
|
129
|
+
v-else-if="schema.component === 'cascader'"
|
|
130
|
+
v-model="formModel[schema.field]"
|
|
131
|
+
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
132
|
+
:disabled="effectiveDisabled"
|
|
133
|
+
v-bind="effectiveComponentProps"
|
|
134
|
+
v-on="effectiveComponentListeners"
|
|
135
|
+
/>
|
|
136
|
+
<el-checkbox-group
|
|
137
|
+
v-else-if="schema.component === 'checkbox'"
|
|
138
|
+
v-model="formModel[schema.field]"
|
|
139
|
+
:disabled="effectiveDisabled"
|
|
140
|
+
v-bind="effectiveComponentProps"
|
|
141
|
+
v-on="effectiveComponentListeners"
|
|
159
142
|
>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
143
|
+
<el-checkbox
|
|
144
|
+
v-for="opt in (getOptions(effectiveComponentProps) || [])"
|
|
145
|
+
:key="String(opt.value)"
|
|
146
|
+
:label="opt.value"
|
|
147
|
+
>
|
|
148
|
+
{{ opt.label }}
|
|
149
|
+
</el-checkbox>
|
|
150
|
+
</el-checkbox-group>
|
|
151
|
+
<el-radio-group
|
|
152
|
+
v-else-if="schema.component === 'radio'"
|
|
153
|
+
v-model="formModel[schema.field]"
|
|
154
|
+
:disabled="effectiveDisabled"
|
|
155
|
+
v-bind="effectiveComponentProps"
|
|
156
|
+
v-on="effectiveComponentListeners"
|
|
157
|
+
>
|
|
158
|
+
<el-radio
|
|
159
|
+
v-for="opt in (getOptions(effectiveComponentProps) || [])"
|
|
160
|
+
:key="String(opt.value)"
|
|
161
|
+
:label="opt.value"
|
|
162
|
+
>
|
|
163
|
+
{{ opt.label }}
|
|
164
|
+
</el-radio>
|
|
165
|
+
</el-radio-group>
|
|
166
|
+
</component>
|
|
163
167
|
</template>
|
|
164
168
|
</el-form-item>
|
|
165
169
|
</template>
|
|
@@ -169,6 +173,7 @@ import { computed, useSlots, h } from 'vue'
|
|
|
169
173
|
import ApiSelect from './ApiSelect.vue'
|
|
170
174
|
import TreeSelect from './TreeSelect.vue'
|
|
171
175
|
import type { ProFormSchema, RenderCallbackParams } from '../types'
|
|
176
|
+
import { normalizeTooltipConfig } from '../utils/tooltip'
|
|
172
177
|
|
|
173
178
|
const BUILT_IN_COMPONENTS: Set<string> = new Set([
|
|
174
179
|
'input', 'select', 'api-select', 'tree-select', 'date-picker', 'date-range', 'input-number',
|
|
@@ -180,6 +185,7 @@ const props = defineProps<{
|
|
|
180
185
|
formModel: Record<string, unknown>
|
|
181
186
|
formDisabled?: boolean
|
|
182
187
|
autoPlaceholder?: boolean
|
|
188
|
+
colon?: boolean
|
|
183
189
|
formActionType?: import('../types').FormActionType
|
|
184
190
|
onFieldChange?: (field: string, value: unknown) => void
|
|
185
191
|
/** 自定义组件映射(由 ProForm 传入) */
|
|
@@ -248,6 +254,17 @@ const effectiveComponentPropsAndListeners = computed(() => {
|
|
|
248
254
|
|
|
249
255
|
const effectiveComponentProps = computed(() => effectiveComponentPropsAndListeners.value.props)
|
|
250
256
|
const effectiveComponentListeners = computed(() => effectiveComponentPropsAndListeners.value.listeners)
|
|
257
|
+
const showColon = computed(() => props.schema.colon ?? props.colon ?? false)
|
|
258
|
+
|
|
259
|
+
const normalizedTooltip = computed(() => {
|
|
260
|
+
const tooltip = props.schema.tooltip
|
|
261
|
+
if (!tooltip) return null
|
|
262
|
+
const resolved = typeof tooltip === 'function' ? tooltip(renderParams.value) : tooltip
|
|
263
|
+
return normalizeTooltipConfig(resolved, props.formModel[props.schema.field])
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
const fieldWrapperComponent = computed(() => normalizedTooltip.value ? 'el-tooltip' : 'span')
|
|
267
|
+
const fieldWrapperProps = computed(() => normalizedTooltip.value || {})
|
|
251
268
|
|
|
252
269
|
const hasSlot = computed(() => !!slots.default)
|
|
253
270
|
|
|
@@ -286,6 +303,10 @@ const renderComponent = computed(() => {
|
|
|
286
303
|
</script>
|
|
287
304
|
|
|
288
305
|
<style scoped>
|
|
306
|
+
.ecp-pro-form-item__colon {
|
|
307
|
+
margin-right: 2px;
|
|
308
|
+
}
|
|
309
|
+
|
|
289
310
|
.ecp-pro-form-item__help-icon {
|
|
290
311
|
margin-left: 4px;
|
|
291
312
|
color: #909399;
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
import { computed } from 'vue'
|
|
85
85
|
import { MessageBox } from 'element-ui'
|
|
86
86
|
import type { TableActionItem } from './types'
|
|
87
|
+
import { normalizeTooltipConfig } from '../utils/tooltip'
|
|
87
88
|
|
|
88
89
|
const props = withDefaults(
|
|
89
90
|
defineProps<{
|
|
@@ -100,11 +101,7 @@ const props = withDefaults(
|
|
|
100
101
|
)
|
|
101
102
|
|
|
102
103
|
const normalizeTooltip = (tooltip?: TableActionItem['tooltip']) => {
|
|
103
|
-
|
|
104
|
-
if (typeof tooltip === 'string') {
|
|
105
|
-
return { content: tooltip }
|
|
106
|
-
}
|
|
107
|
-
return tooltip as Record<string, unknown>
|
|
104
|
+
return normalizeTooltipConfig(tooltip) || {}
|
|
108
105
|
}
|
|
109
106
|
|
|
110
107
|
const getButtonType = (action: TableActionItem) => {
|
package/src/types/index.ts
CHANGED
|
@@ -60,6 +60,7 @@ export interface ProFormProps {
|
|
|
60
60
|
initialValues?: Record<string, unknown>
|
|
61
61
|
labelWidth?: string
|
|
62
62
|
labelPosition?: 'left' | 'right' | 'top'
|
|
63
|
+
colon?: boolean
|
|
63
64
|
gutter?: number
|
|
64
65
|
size?: 'medium' | 'small' | 'large'
|
|
65
66
|
disabled?: boolean
|
|
@@ -108,6 +109,8 @@ export interface ProFormSchema {
|
|
|
108
109
|
label: string
|
|
109
110
|
/** 单个表单项标签宽度,优先级高于 Form 的 labelWidth */
|
|
110
111
|
labelWidth?: string
|
|
112
|
+
/** 是否显示 label 冒号,优先级高于 ProForm 的 colon */
|
|
113
|
+
colon?: boolean
|
|
111
114
|
/**
|
|
112
115
|
* 组件类型:
|
|
113
116
|
* - 内置:'input' | 'select' | 'date-picker' | 'date-range' | 'input-number' | 'switch' | 'cascader' | 'checkbox' | 'radio'
|
|
@@ -147,6 +150,8 @@ export interface ProFormSchema {
|
|
|
147
150
|
helpMessage?: string | string[]
|
|
148
151
|
/** 温馨提示组件的 props */
|
|
149
152
|
helpComponentProps?: Record<string, unknown>
|
|
153
|
+
/** 表单项 value 的 tooltip,true 时默认展示当前值,支持函数动态返回 */
|
|
154
|
+
tooltip?: boolean | string | Record<string, unknown> | ((params: RenderCallbackParams) => boolean | string | Record<string, unknown>)
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
/** ProDescriptions 描述项配置 */
|
|
@@ -195,6 +200,8 @@ export interface DescriptionSchema {
|
|
|
195
200
|
slot?: string
|
|
196
201
|
/** 自定义渲染 */
|
|
197
202
|
render?: (value: unknown, record: Record<string, unknown>) => VNode | string | number | null | undefined
|
|
203
|
+
/** 描述项 value 的 tooltip,true 时默认展示当前值,支持函数动态返回 */
|
|
204
|
+
tooltip?: boolean | string | Record<string, unknown> | ((params: { value: unknown; record: Record<string, unknown>; schema: DescriptionSchema }) => boolean | string | Record<string, unknown>)
|
|
198
205
|
}
|
|
199
206
|
|
|
200
207
|
/** Description Props */
|
|
@@ -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
|
+
}
|