fx-platform-ui 0.0.2 → 0.0.3
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/CHANGELOG.md +28 -0
- package/lib/fx-platform-ui.mjs +26210 -6477
- package/lib/fx-platform-ui.umd.js +58 -14
- package/lib/packages/components/form/index.d.ts +2 -0
- package/lib/packages/components/form/src/hook/index.d.ts +9 -0
- package/lib/packages/components/form/src/hook/useFormContext.d.ts +3 -0
- package/lib/packages/components/form/src/hook/useFormEvents.d.ts +29 -0
- package/lib/packages/components/form/src/hook/useFormLabel.d.ts +79 -0
- package/lib/packages/components/form/src/hook/useFormMethods.d.ts +13 -0
- package/lib/packages/components/form/src/methods.d.ts +7 -0
- package/lib/packages/components/form/src/plat-form-emits.d.ts +9 -0
- package/lib/packages/components/form/src/types/form.d.ts +70 -0
- package/lib/packages/components/form/src/types/index.d.ts +2 -0
- package/lib/packages/types/global.d.ts +81 -0
- package/lib/packages/types/index.d.ts +27 -0
- package/lib/packages/utils/dateUtil.d.ts +7 -0
- package/lib/packages/utils/index.d.ts +11 -0
- package/lib/packages/utils/is/index.d.ts +22 -0
- package/lib/style.css +1 -1
- package/package.json +5 -2
- package/packages/component.ts +3 -2
- package/packages/components/form/index.tsx +10 -0
- package/packages/components/form/src/components/form-action.vue +131 -0
- package/packages/components/form/src/hook/index.ts +12 -0
- package/packages/components/form/src/hook/useForm.tsx +61 -0
- package/packages/components/form/src/hook/useFormContext.ts +12 -0
- package/packages/components/form/src/hook/useFormEvents.ts +274 -0
- package/packages/components/form/src/hook/useFormLabel.ts +42 -0
- package/packages/components/form/src/hook/useFormMethods.ts +137 -0
- package/packages/components/form/src/hook/useFormState.ts +80 -0
- package/packages/components/form/src/index.vue +124 -0
- package/packages/components/form/src/methods.ts +49 -0
- package/packages/components/form/src/plat-form-emits.ts +13 -0
- package/packages/components/form/src/plat-form-item.vue +421 -0
- package/packages/components/form/src/plat-form-props.ts +108 -0
- package/packages/components/form/src/types/component.ts +167 -0
- package/packages/components/form/src/types/form.ts +130 -0
- package/packages/components/form/src/types/index.ts +2 -0
- package/packages/types/global.d.ts +81 -0
- package/packages/types/index.d.ts +27 -0
- package/packages/utils/dateUtil.ts +24 -0
- package/packages/utils/index.ts +33 -0
- package/packages/utils/is/index.ts +104 -0
- package/lib/packages/component.d.ts +0 -7
- package/packages/utils/className.ts +0 -28
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { unref } from 'vue'
|
|
2
|
+
import { set } from 'lodash-es'
|
|
3
|
+
import { deepMerge } from '../../../../utils'
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import { dateUtil } from '../../../../utils/dateUtil'
|
|
6
|
+
import {
|
|
7
|
+
isFunction,
|
|
8
|
+
isNullOrUnDef,
|
|
9
|
+
isObject,
|
|
10
|
+
isArray,
|
|
11
|
+
isString
|
|
12
|
+
} from '../../../../utils/is'
|
|
13
|
+
import type { FormState } from './useFormState'
|
|
14
|
+
import type { FormSchema } from '../types'
|
|
15
|
+
import type { PlatFormProps } from '../plat-form-props'
|
|
16
|
+
// deepMerge 深度合并
|
|
17
|
+
|
|
18
|
+
export type FormMethods = ReturnType<typeof useFormMethods>
|
|
19
|
+
|
|
20
|
+
type UseFormMethodsContext = FormState
|
|
21
|
+
|
|
22
|
+
export const useFormMethods = (formMethodsContext: UseFormMethodsContext) => {
|
|
23
|
+
const {
|
|
24
|
+
compRefs,
|
|
25
|
+
formModel,
|
|
26
|
+
formPropsRef,
|
|
27
|
+
cacheFormModel,
|
|
28
|
+
defaultFormValues,
|
|
29
|
+
platFormRef,
|
|
30
|
+
getFormProps
|
|
31
|
+
} = formMethodsContext
|
|
32
|
+
|
|
33
|
+
// 将所有的表单组件实例保存起来
|
|
34
|
+
const setItemRef = (formItem: FormSchema) => {
|
|
35
|
+
return (el) => {
|
|
36
|
+
if (el) {
|
|
37
|
+
compRefs[formItem.field] = el
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// todo 设置某个字段的值
|
|
43
|
+
const setFormModel = (key: string, value: any) => {
|
|
44
|
+
formModel[key] = value
|
|
45
|
+
cacheFormModel[key] = value
|
|
46
|
+
console.log('getFormProps', getFormProps)
|
|
47
|
+
const { validateTrigger } = unref(getFormProps)
|
|
48
|
+
if (!validateTrigger || validateTrigger === 'change') {
|
|
49
|
+
platFormRef.value?.validateFields([key])
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 更新表单props
|
|
54
|
+
const setSchemaFormProps = (formProps: Partial<PlatFormProps>) => {
|
|
55
|
+
formPropsRef.value = deepMerge(unref(formPropsRef) || {}, formProps)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Processing form values
|
|
59
|
+
function handleFormValues(values: Recordable) {
|
|
60
|
+
console.log('before', values)
|
|
61
|
+
if (!isObject(values)) {
|
|
62
|
+
return {}
|
|
63
|
+
}
|
|
64
|
+
const res: Recordable = {}
|
|
65
|
+
for (const item of Object.entries(values)) {
|
|
66
|
+
let [, value] = item
|
|
67
|
+
const [key] = item
|
|
68
|
+
if (!key || (isArray(value) && value.length === 0) || isFunction(value)) {
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
const transformDateFunc = unref(getFormProps).transformDateFunc
|
|
72
|
+
if (isObject(value)) {
|
|
73
|
+
value = transformDateFunc?.(value)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (isArray(value) && value[0]?.format && value[1]?.format) {
|
|
77
|
+
value = value.map((item) => transformDateFunc?.(item))
|
|
78
|
+
}
|
|
79
|
+
// Remove spaces
|
|
80
|
+
if (isString(value)) {
|
|
81
|
+
value = value.trim()
|
|
82
|
+
}
|
|
83
|
+
set(res, key, value)
|
|
84
|
+
}
|
|
85
|
+
console.log('time', res)
|
|
86
|
+
return handleRangeTimeValue(res)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @description: Processing time interval parameters
|
|
91
|
+
*/
|
|
92
|
+
function handleRangeTimeValue(values: Recordable) {
|
|
93
|
+
const fieldMapToTime = unref(getFormProps).fieldMapToTime
|
|
94
|
+
|
|
95
|
+
if (!fieldMapToTime || !Array.isArray(fieldMapToTime)) {
|
|
96
|
+
return values
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
for (const [
|
|
100
|
+
field,
|
|
101
|
+
[startTimeKey, endTimeKey],
|
|
102
|
+
format = 'YYYY-MM-DD'
|
|
103
|
+
] of fieldMapToTime) {
|
|
104
|
+
if (!field || !startTimeKey || !endTimeKey || !values[field]) {
|
|
105
|
+
continue
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const [startTime, endTime]: string[] = values[field]
|
|
109
|
+
|
|
110
|
+
values[startTimeKey] = dateUtil(startTime).format(format)
|
|
111
|
+
values[endTimeKey] = dateUtil(endTime).format(format)
|
|
112
|
+
Reflect.deleteProperty(values, field)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return values
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 初始化数据
|
|
119
|
+
const initFormValues = () => {
|
|
120
|
+
unref(formPropsRef).schemas?.forEach((item) => {
|
|
121
|
+
const { defaultValue } = item
|
|
122
|
+
if (!isNullOrUnDef(defaultValue)) {
|
|
123
|
+
formModel[item.field] = defaultValue
|
|
124
|
+
defaultFormValues[item.field] = defaultValue
|
|
125
|
+
cacheFormModel[item.field] = defaultValue
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
setItemRef,
|
|
132
|
+
initFormValues,
|
|
133
|
+
setFormModel,
|
|
134
|
+
setSchemaFormProps,
|
|
135
|
+
handleFormValues
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { computed, reactive, ref, unref } from 'vue'
|
|
2
|
+
import { cloneDeep } from 'lodash-es'
|
|
3
|
+
import type { SetupContext } from 'vue'
|
|
4
|
+
import type { PlatFormProps } from '../plat-form-props'
|
|
5
|
+
import type { FormInstance } from 'ant-design-vue'
|
|
6
|
+
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
export type FormState = ReturnType<typeof useFormState>
|
|
9
|
+
|
|
10
|
+
export type useFormStateParams = {
|
|
11
|
+
props: PlatFormProps
|
|
12
|
+
attrs: SetupContext['attrs']
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const useFormState = ({ props, attrs }: useFormStateParams) => {
|
|
16
|
+
const formPropsRef = ref<PlatFormProps>(cloneDeep(props))
|
|
17
|
+
|
|
18
|
+
// 表单项数据
|
|
19
|
+
const formModel = reactive({ ...props.initialValues })
|
|
20
|
+
// 表单默认数据
|
|
21
|
+
const defaultFormValues = reactive({ ...props.initialValues })
|
|
22
|
+
|
|
23
|
+
// 表单实例
|
|
24
|
+
const platFormRef = ref<FormInstance>()
|
|
25
|
+
|
|
26
|
+
// 缓存的表单值
|
|
27
|
+
const cacheFormModel = reactive({ ...props.initialValues })
|
|
28
|
+
|
|
29
|
+
// 将所有的表单组件实例保存起来
|
|
30
|
+
const compRefs = reactive({})
|
|
31
|
+
|
|
32
|
+
// 展开/收缩配置项
|
|
33
|
+
const advanceState = reactive({
|
|
34
|
+
isAdvanced: true,
|
|
35
|
+
hideAdvanceBtn: false,
|
|
36
|
+
isLoad: false,
|
|
37
|
+
actionSpan: 6
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// 获取表单所有属性
|
|
41
|
+
const getFormProps = computed(() => {
|
|
42
|
+
return {
|
|
43
|
+
...attrs,
|
|
44
|
+
...formPropsRef.value
|
|
45
|
+
} as PlatFormProps
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
// 获取栅栏row配置
|
|
49
|
+
const getRowConfig = computed(() => {
|
|
50
|
+
const { baseRowStyle, rowProps } = unref(getFormProps)
|
|
51
|
+
return {
|
|
52
|
+
style: baseRowStyle,
|
|
53
|
+
...rowProps
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const getFormActionBindProps = computed(() => ({
|
|
58
|
+
...getFormProps.value,
|
|
59
|
+
...advanceState
|
|
60
|
+
}))
|
|
61
|
+
|
|
62
|
+
const formSchemasRef = computed(() => {
|
|
63
|
+
const { schemas } = unref(getFormProps)
|
|
64
|
+
return schemas || []
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
formModel,
|
|
69
|
+
defaultFormValues,
|
|
70
|
+
platFormRef,
|
|
71
|
+
formPropsRef,
|
|
72
|
+
cacheFormModel,
|
|
73
|
+
compRefs,
|
|
74
|
+
getFormProps,
|
|
75
|
+
advanceState,
|
|
76
|
+
getRowConfig,
|
|
77
|
+
getFormActionBindProps,
|
|
78
|
+
formSchemasRef
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Form
|
|
3
|
+
ref="platFormRef"
|
|
4
|
+
v-bind="pick(getFormProps, aFormPropKeys)"
|
|
5
|
+
:model="formModel"
|
|
6
|
+
>
|
|
7
|
+
<Row v-bind="getRowConfig">
|
|
8
|
+
<slot name="formHeader"></slot>
|
|
9
|
+
<template v-for="formSchema in formSchemasRef" :key="formSchema.field">
|
|
10
|
+
<PlatFormItem
|
|
11
|
+
:schema="formSchema"
|
|
12
|
+
:form-model="formModel"
|
|
13
|
+
:set-form-model="setFormModel"
|
|
14
|
+
:set-item-ref="setItemRef(formSchema)"
|
|
15
|
+
>
|
|
16
|
+
<template
|
|
17
|
+
v-for="item in Object.keys($slots)"
|
|
18
|
+
#[item]="data"
|
|
19
|
+
:key="item"
|
|
20
|
+
>
|
|
21
|
+
<slot :name="item" v-bind="data || {}"></slot>
|
|
22
|
+
</template>
|
|
23
|
+
</PlatFormItem>
|
|
24
|
+
</template>
|
|
25
|
+
<FormAction
|
|
26
|
+
v-bind="getFormActionBindProps"
|
|
27
|
+
@toggle-advanced="handleToggleAdvanced"
|
|
28
|
+
>
|
|
29
|
+
<template
|
|
30
|
+
v-for="item in [
|
|
31
|
+
'resetBefore',
|
|
32
|
+
'submitBefore',
|
|
33
|
+
'advanceBefore',
|
|
34
|
+
'advanceAfter'
|
|
35
|
+
]"
|
|
36
|
+
#[item]="data"
|
|
37
|
+
>
|
|
38
|
+
<slot :name="item" v-bind="data || {}"></slot>
|
|
39
|
+
</template>
|
|
40
|
+
</FormAction>
|
|
41
|
+
<slot name="formFooter"></slot>
|
|
42
|
+
</Row>
|
|
43
|
+
</Form>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script lang="ts" setup>
|
|
47
|
+
import { useAttrs, watch } from 'vue'
|
|
48
|
+
import { pick } from 'lodash-es'
|
|
49
|
+
import { Form, Row } from 'ant-design-vue'
|
|
50
|
+
import { platFormEmits } from './plat-form-emits'
|
|
51
|
+
import { platFormProps, aFormPropKeys } from './plat-form-props'
|
|
52
|
+
import {
|
|
53
|
+
useFormState,
|
|
54
|
+
useFormMethods,
|
|
55
|
+
useFormEvents,
|
|
56
|
+
createFormContext
|
|
57
|
+
} from './hook'
|
|
58
|
+
import FormAction from './components/form-action.vue'
|
|
59
|
+
import PlatFormItem from './plat-form-item.vue'
|
|
60
|
+
import type { PlatFormType } from './hook'
|
|
61
|
+
|
|
62
|
+
defineOptions({
|
|
63
|
+
name: 'PlForm'
|
|
64
|
+
})
|
|
65
|
+
const attrs = useAttrs()
|
|
66
|
+
const props = defineProps(platFormProps)
|
|
67
|
+
const emit = defineEmits(platFormEmits)
|
|
68
|
+
useFormState({ props, attrs })
|
|
69
|
+
const platFormState = useFormState({ props, attrs })
|
|
70
|
+
const {
|
|
71
|
+
formModel,
|
|
72
|
+
getRowConfig,
|
|
73
|
+
platFormRef,
|
|
74
|
+
getFormProps,
|
|
75
|
+
getFormActionBindProps,
|
|
76
|
+
formSchemasRef
|
|
77
|
+
} = platFormState
|
|
78
|
+
|
|
79
|
+
// 表单内部方法
|
|
80
|
+
const platFormMethods = useFormMethods({ ...platFormState })
|
|
81
|
+
const {
|
|
82
|
+
initFormValues,
|
|
83
|
+
handleFormValues,
|
|
84
|
+
setFormModel,
|
|
85
|
+
setItemRef,
|
|
86
|
+
setSchemaFormProps
|
|
87
|
+
} = platFormMethods
|
|
88
|
+
|
|
89
|
+
// 初始化表单
|
|
90
|
+
initFormValues()
|
|
91
|
+
|
|
92
|
+
// a-form表单事件二次封装和扩展
|
|
93
|
+
const platFormEvents = useFormEvents({
|
|
94
|
+
...platFormState,
|
|
95
|
+
emit,
|
|
96
|
+
handleFormValues
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// 如果props修改
|
|
100
|
+
// 同步外部对props的修改
|
|
101
|
+
watch(props, () => setSchemaFormProps(props), {
|
|
102
|
+
deep: true,
|
|
103
|
+
immediate: true
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// 当前组件所有的状态和方法
|
|
107
|
+
const instance = {
|
|
108
|
+
...platFormState,
|
|
109
|
+
...platFormEvents,
|
|
110
|
+
...platFormMethods
|
|
111
|
+
} as PlatFormType
|
|
112
|
+
|
|
113
|
+
emit('register', instance)
|
|
114
|
+
|
|
115
|
+
createFormContext(instance)
|
|
116
|
+
|
|
117
|
+
function handleToggleAdvanced() {
|
|
118
|
+
console.log('点击了收缩或展开')
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
defineExpose(instance)
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<style scoped></style>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { isNumber } from '../../../utils/is'
|
|
2
|
+
import type { ComponentMapType } from './types'
|
|
3
|
+
|
|
4
|
+
const DATE_TYPE = ['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker']
|
|
5
|
+
|
|
6
|
+
function genType() {
|
|
7
|
+
return [...DATE_TYPE, 'RangePicker']
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const dateItemType = genType()
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @description: 生成placeholder
|
|
14
|
+
*/
|
|
15
|
+
export function createPlaceholderMessage(
|
|
16
|
+
component: ComponentMapType,
|
|
17
|
+
label = ''
|
|
18
|
+
) {
|
|
19
|
+
if (component.includes('Input') || component.includes('Complete')) {
|
|
20
|
+
return `${label}`
|
|
21
|
+
}
|
|
22
|
+
const chooseTypes: ComponentMapType[] = [
|
|
23
|
+
'Select',
|
|
24
|
+
'Cascader',
|
|
25
|
+
'Checkbox',
|
|
26
|
+
'CheckboxGroup',
|
|
27
|
+
'Switch',
|
|
28
|
+
'TreeSelect'
|
|
29
|
+
]
|
|
30
|
+
if (component.includes('Picker') || chooseTypes.includes(component)) {
|
|
31
|
+
return `${label}`
|
|
32
|
+
}
|
|
33
|
+
return ''
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function handleInputNumberValue(
|
|
37
|
+
component?: ComponentMapType,
|
|
38
|
+
val?: any
|
|
39
|
+
) {
|
|
40
|
+
if (!component) return val
|
|
41
|
+
if (
|
|
42
|
+
['Input', 'InputPassword', 'InputSearch', 'InputTextArea'].includes(
|
|
43
|
+
component
|
|
44
|
+
)
|
|
45
|
+
) {
|
|
46
|
+
return val && isNumber(val) ? `${val}` : val
|
|
47
|
+
}
|
|
48
|
+
return val
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isObject } from '../../../utils/is'
|
|
2
|
+
import type { ComponentInternalInstance } from 'vue'
|
|
3
|
+
|
|
4
|
+
export const platFormEmits = {
|
|
5
|
+
register: (exposed: ComponentInternalInstance['exposed']) =>
|
|
6
|
+
isObject(exposed),
|
|
7
|
+
reset: (formModel: Recordable<any>) => isObject(formModel),
|
|
8
|
+
submit: (formModel: any) => isObject(formModel),
|
|
9
|
+
'advanced-change': () => true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type PlatFormEmits = typeof platFormEmits
|
|
13
|
+
export type PlatFormEmitFn = EmitFn<PlatFormEmits>
|