@hzab/form-render 1.6.8-beta → 1.6.8-beta1
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 +2 -1
- package/package.json +1 -2
- package/src/common/formily-utils.ts +119 -7
- package/src/common/schema-handler.ts +0 -8
- package/src/components/PersonnelSelect/index.less +21 -0
- package/src/components/PersonnelSelect/index.module.less +33 -0
- package/src/components/PersonnelSelect/index.tsx +257 -0
- package/src/components/PersonnelSelect/type.ts +0 -0
- package/src/components/index.tsx +1 -0
- package/src/index.less +3 -7
- package/src/index.tsx +1 -5
- package/src/custom-theme.less +0 -488
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hzab/form-render",
|
3
|
-
"version": "1.6.8-
|
3
|
+
"version": "1.6.8-beta1",
|
4
4
|
"description": "",
|
5
5
|
"main": "src",
|
6
6
|
"scripts": {
|
@@ -21,7 +21,6 @@
|
|
21
21
|
"@hzab/data-model": "^1.2.0",
|
22
22
|
"@hzab/permissions": "^0.1.1",
|
23
23
|
"@hzab/webpack-config": "0.0.12",
|
24
|
-
"@hzab/theme-tools": "^0.0.2",
|
25
24
|
"@types/react": "^17.0.62",
|
26
25
|
"@types/react-dom": "^17.0.20",
|
27
26
|
"antd": "^4.24.12",
|
@@ -1,13 +1,125 @@
|
|
1
|
+
import _ from "lodash";
|
2
|
+
|
3
|
+
export interface ISetTargetLevelValOpt {
|
4
|
+
/**
|
5
|
+
* 相对当前的层级数
|
6
|
+
*/
|
7
|
+
level?: number;
|
8
|
+
/**
|
9
|
+
* 目标数据为数组是否使用 push
|
10
|
+
*/
|
11
|
+
isArrPush?: boolean;
|
12
|
+
}
|
13
|
+
|
1
14
|
/**
|
2
|
-
*
|
3
|
-
*
|
4
|
-
* @param field
|
15
|
+
* 获取父级的数据(包括当前项的对象)
|
16
|
+
* @param field formily field 对象 const field: any = useField();
|
5
17
|
* @returns
|
6
18
|
*/
|
7
19
|
export function getParentValue(field) {
|
8
|
-
|
9
|
-
|
10
|
-
|
20
|
+
return getTargetLevelVal(field, -1);
|
21
|
+
}
|
22
|
+
|
23
|
+
/**
|
24
|
+
* 设置当前 field 同层级数据值。
|
25
|
+
* @param field formily field 对象 const field: any = useField();
|
26
|
+
* @param key 目标 key
|
27
|
+
* @param val 目标值
|
28
|
+
* @example
|
29
|
+
* 如当前的 field name 为 test, 设置同层级 testA
|
30
|
+
* // 初始值:
|
31
|
+
* {
|
32
|
+
* test: 1
|
33
|
+
* }
|
34
|
+
* // 设置同层级 key 为 testA 的值为 222
|
35
|
+
* setParentValue(field, 'testA', 222);
|
36
|
+
* // 设置结果
|
37
|
+
* {
|
38
|
+
* test: 1,
|
39
|
+
* testA: 222
|
40
|
+
* }
|
41
|
+
*/
|
42
|
+
export function setParentValue(field, key, val) {
|
43
|
+
setTargetLevelVal(field, key, val, { level: -1 });
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* 获取相对当前层级的数据对象(包括当前项的对象)
|
48
|
+
* @param field formily field 对象 const field: any = useField();
|
49
|
+
* @param key 目标 key
|
50
|
+
* @param val 目标 value
|
51
|
+
* @param level 相对的层级 负数
|
52
|
+
* @returns
|
53
|
+
*/
|
54
|
+
export function getTargetLevelVal(field, level) {
|
55
|
+
if (typeof field !== "object" || !field.form || !field.path) {
|
56
|
+
console.warn("Warn setCurLevelData: field 入参不是一个正确的 formily field 数据");
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
// 设置目标参数的路径
|
60
|
+
let path = [...field.path.segments];
|
61
|
+
// 层级超出路径长度不进行设置
|
62
|
+
if (Math.abs(level) > path.length) {
|
63
|
+
console.info("Info setCurLevelData: level 层级超出路径长度不进行设置");
|
64
|
+
return;
|
65
|
+
}
|
66
|
+
if (typeof level === "number") {
|
67
|
+
path = path.slice(0, level);
|
68
|
+
}
|
69
|
+
// 设置目标数据
|
70
|
+
return _.get(field.form.values, path.join("."));
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* 设置相对当前层级的数据对象(包括当前项的对象)
|
75
|
+
* @param field formily field 对象 const field: any = useField();
|
76
|
+
* @param key 目标 key
|
77
|
+
* @param val 目标 value
|
78
|
+
* @param level 相对的层级
|
79
|
+
* @returns
|
80
|
+
*/
|
81
|
+
export function setTargetLevelVal(
|
82
|
+
field,
|
83
|
+
key,
|
84
|
+
val,
|
85
|
+
opt: ISetTargetLevelValOpt = { level: undefined, isArrPush: false },
|
86
|
+
) {
|
87
|
+
if (typeof field !== "object" || !field.form || !field.path) {
|
88
|
+
console.warn("Warn setCurLevelData: field 入参不是一个正确的 formily field 数据");
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
const {
|
92
|
+
/**
|
93
|
+
* 数组是否进行 push 曹组
|
94
|
+
*/
|
95
|
+
isArrPush,
|
96
|
+
/**
|
97
|
+
* 相对的层级
|
98
|
+
*/
|
99
|
+
level,
|
100
|
+
} = opt || {};
|
101
|
+
// 设置目标参数的路径
|
102
|
+
let path = [...field.path.segments];
|
103
|
+
// 层级超出路径长度不进行设置
|
104
|
+
if (Math.abs(level) > path.length) {
|
105
|
+
console.info("Info setCurLevelData: level 层级超出路径长度不进行设置");
|
106
|
+
return;
|
107
|
+
}
|
108
|
+
if (typeof level === "number") {
|
109
|
+
path = path.slice(0, -Math.abs(level));
|
110
|
+
}
|
111
|
+
const parentPath = path.join(".");
|
112
|
+
const parentType = _.get(field.form.values, path);
|
113
|
+
// 添加目标 key,得到目标完整 path
|
114
|
+
path.push(key);
|
115
|
+
// 克隆 form 数据,用于修改目标数据 ()
|
116
|
+
const data = _.cloneDeep(field.form.values);
|
117
|
+
// 设置目标数据
|
118
|
+
if (isArrPush && Array.isArray(parentType)) {
|
119
|
+
const _d = _.get(data, parentPath);
|
120
|
+
Array.isArray(_d) && _d.push({ [key]: val });
|
121
|
+
} else {
|
122
|
+
_.set(data, path.join("."), val);
|
11
123
|
}
|
12
|
-
|
124
|
+
field.form.setValues(data);
|
13
125
|
}
|
@@ -38,8 +38,6 @@ export const arrayList = ["ArrayTable", "ArrayCards"];
|
|
38
38
|
export const skipBindList = ["FormCollapse", "FormCollapse.CollapsePanel"];
|
39
39
|
/** change 回调返回 parent 数据的组件 */
|
40
40
|
export const returnParentValue = ["ArrayTable", "ArrayCards"];
|
41
|
-
/** 自定义样式中需要为下拉窗口或弹窗添加popupClassName的组件 */
|
42
|
-
export const addPopupClassName = ["Cascader", "TreeSelect", "Select", "TimePicker", "DatePicker", "DatePicker.RangePicker", "TimePicker.RangePicker", "UserSelect"]
|
43
41
|
|
44
42
|
/**
|
45
43
|
* schema 每项添加 onChange,解决无全局 onChange 问题
|
@@ -66,12 +64,6 @@ export const bindOnChange = (schema, opt) => {
|
|
66
64
|
} else if (isScopeKey(comProps, schemaScope)) {
|
67
65
|
item["x-component-props"] = getScopeKeyVal(comProps, schemaScope) || {};
|
68
66
|
}
|
69
|
-
// 为自定义主题时存在弹窗或下拉框的组件添加类名
|
70
|
-
if (opt?.customTheme) {
|
71
|
-
if (addPopupClassName.includes(item["x-component"])) {
|
72
|
-
item["x-component-props"].popupClassName = typeof opt.customTheme === 'string' ? `form-dialog-custom-theme-${opt.customTheme}` : 'form-dialog-custom-theme';
|
73
|
-
}
|
74
|
-
}
|
75
67
|
|
76
68
|
const bindParams = {
|
77
69
|
componentName,
|
@@ -0,0 +1,21 @@
|
|
1
|
+
.abt-user-item {
|
2
|
+
display: flex;
|
3
|
+
align-items: center;
|
4
|
+
padding: 0 16px;
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
.abt-user-item-info {
|
9
|
+
list-style: none;
|
10
|
+
flex: 1;
|
11
|
+
display: flex;
|
12
|
+
flex-direction: column;
|
13
|
+
padding-left: 16px;
|
14
|
+
|
15
|
+
.abt-user-item-info__item {
|
16
|
+
& > span:last-of-type {
|
17
|
+
color: #666;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
.user-select {
|
2
|
+
|
3
|
+
&-option {
|
4
|
+
:global {
|
5
|
+
.ant-select-item-option-content {
|
6
|
+
display: flex;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
|
11
|
+
&__avatar {
|
12
|
+
margin-right: 10px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.user-item {
|
16
|
+
display: flex;
|
17
|
+
flex-direction: column;
|
18
|
+
|
19
|
+
&-name {
|
20
|
+
margin-bottom: 4px;
|
21
|
+
color: #000000d9;
|
22
|
+
font-size: 14px;
|
23
|
+
display: flex;
|
24
|
+
align-items: center;
|
25
|
+
}
|
26
|
+
|
27
|
+
&__idCard {
|
28
|
+
color: #00000073;
|
29
|
+
font-size: 14px;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,257 @@
|
|
1
|
+
import React, { useEffect, useState, useRef, useCallback, useMemo } from "react";
|
2
|
+
import { Select, List, Avatar, Spin } from "antd";
|
3
|
+
import { connect, mapProps } from "@formily/react";
|
4
|
+
import type { SelectProps } from "antd/lib/select";
|
5
|
+
import type { AvatarProps } from "antd/lib/avatar";
|
6
|
+
import { debounce, isObject, uniq } from "lodash";
|
7
|
+
|
8
|
+
import "./index.less";
|
9
|
+
|
10
|
+
export interface Person {
|
11
|
+
id: string | number;
|
12
|
+
name: string;
|
13
|
+
avatar?: string;
|
14
|
+
email?: string;
|
15
|
+
description?: string;
|
16
|
+
disabled?: boolean;
|
17
|
+
[key: string]: any;
|
18
|
+
}
|
19
|
+
|
20
|
+
interface ScrollPagination {
|
21
|
+
pageNum: number;
|
22
|
+
pageSize: number;
|
23
|
+
current?: number;
|
24
|
+
total?: number;
|
25
|
+
}
|
26
|
+
|
27
|
+
type LableValue = {
|
28
|
+
label: string;
|
29
|
+
value: string | number;
|
30
|
+
[key: string]: any;
|
31
|
+
};
|
32
|
+
|
33
|
+
interface RemoteSelectProps extends Omit<SelectProps<any>, "options" | "children"> {
|
34
|
+
loadOptions: (
|
35
|
+
search: string,
|
36
|
+
pagination: ScrollPagination,
|
37
|
+
) => Promise<{ list: Person[]; pagination: ScrollPagination }>;
|
38
|
+
renderItem?: (item: Person) => React.ReactNode;
|
39
|
+
initialPagination?: Partial<ScrollPagination>;
|
40
|
+
avataProps?: AvatarProps;
|
41
|
+
value: LableValue[] | LableValue;
|
42
|
+
listItemConfigs?: { label: string; key: string }[];
|
43
|
+
disabledKey?: string;
|
44
|
+
disabledStyle?: (disabled: boolean) => React.CSSProperties;
|
45
|
+
customItemNode?: React.ReactNode;
|
46
|
+
}
|
47
|
+
|
48
|
+
const defaultListItemConfigs = [
|
49
|
+
{ label: "姓名:", key: "userName" },
|
50
|
+
{ label: "主部门:", key: "orgName" },
|
51
|
+
{ label: "主驻点:", key: "userName" },
|
52
|
+
{ label: "手机号:", key: "phoneNumber" },
|
53
|
+
{ label: "身份证号:", key: "idnumber" },
|
54
|
+
];
|
55
|
+
|
56
|
+
const RemoteSelect: React.FC<RemoteSelectProps> = ({
|
57
|
+
loadOptions,
|
58
|
+
renderItem,
|
59
|
+
listItemConfigs,
|
60
|
+
disabledKey = "disabled",
|
61
|
+
initialPagination = {},
|
62
|
+
avataProps = {},
|
63
|
+
disabledStyle,
|
64
|
+
customItemNode,
|
65
|
+
...selectProps
|
66
|
+
}) => {
|
67
|
+
const [search, setSearch] = useState("");
|
68
|
+
const [loading, setLoading] = useState(false);
|
69
|
+
const [loadingMore, setLoadingMore] = useState(false);
|
70
|
+
const [list, setList] = useState<Person[]>([]);
|
71
|
+
const [pagination, setPagination] = useState<ScrollPagination>({
|
72
|
+
pageNum: 1,
|
73
|
+
pageSize: 10,
|
74
|
+
...initialPagination,
|
75
|
+
});
|
76
|
+
const listRef = useRef<HTMLDivElement>(null);
|
77
|
+
const selectInstance = useRef<any>(null);
|
78
|
+
|
79
|
+
const debounceLoadData = debounce(async (isScrollLoad = false) => {
|
80
|
+
try {
|
81
|
+
isScrollLoad ? setLoadingMore(true) : setLoading(true);
|
82
|
+
|
83
|
+
const result = await loadOptions(search, {
|
84
|
+
...pagination,
|
85
|
+
pageNum: isScrollLoad ? pagination.pageNum + 1 : 1,
|
86
|
+
});
|
87
|
+
const { list } = result;
|
88
|
+
|
89
|
+
setList((prev) => (isScrollLoad ? [...prev, ...list] : list));
|
90
|
+
} finally {
|
91
|
+
isScrollLoad ? setLoadingMore(false) : setLoading(false);
|
92
|
+
}
|
93
|
+
}, 500);
|
94
|
+
const debounceHandleScroll = async (e: React.UIEvent<HTMLDivElement>) => {
|
95
|
+
const { scrollTop, clientHeight, scrollHeight } = e.currentTarget;
|
96
|
+
const isNearBottom = scrollHeight - scrollTop - clientHeight < 30;
|
97
|
+
|
98
|
+
if (isNearBottom && !loadingMore) {
|
99
|
+
await loadData(true);
|
100
|
+
setPagination((pre) => ({ ...pre, pageNum: pagination.pageNum + 1 }));
|
101
|
+
}
|
102
|
+
};
|
103
|
+
|
104
|
+
const loadData = useCallback(debounceLoadData, [search, pagination, loadOptions]);
|
105
|
+
|
106
|
+
// 处理滚动加载
|
107
|
+
const handleScroll = useCallback(debounceHandleScroll, [loadingMore, loadData]);
|
108
|
+
|
109
|
+
// 处理搜索
|
110
|
+
const handleSearch = debounce((value: string) => {
|
111
|
+
setSearch(value);
|
112
|
+
setPagination((prev) => ({ ...prev, pageNum: 1 }));
|
113
|
+
}, 1000);
|
114
|
+
|
115
|
+
useEffect(() => {
|
116
|
+
loadData();
|
117
|
+
}, [search]);
|
118
|
+
|
119
|
+
// 处理选项点击
|
120
|
+
const handleItemClick = (itemId: string | number) => {
|
121
|
+
const currentValue = selectProps.value;
|
122
|
+
const isMultiple = selectProps.mode === "multiple";
|
123
|
+
|
124
|
+
// 更新值
|
125
|
+
if (isMultiple) {
|
126
|
+
const isValueArr = Array.isArray(currentValue);
|
127
|
+
let newValue = null;
|
128
|
+
|
129
|
+
if (isValueArr) {
|
130
|
+
const currentValueIds = currentValue.map((it) => it.value);
|
131
|
+
newValue = currentValueIds.includes(itemId)
|
132
|
+
? currentValueIds.filter((v) => v !== itemId)
|
133
|
+
: uniq([...currentValue, itemId]);
|
134
|
+
} else {
|
135
|
+
newValue = [itemId];
|
136
|
+
}
|
137
|
+
|
138
|
+
selectProps.onChange?.(newValue, currentValue);
|
139
|
+
} else {
|
140
|
+
const newValue = itemId === (currentValue as LableValue)?.value ? undefined : itemId;
|
141
|
+
selectProps.onChange?.(newValue, currentValue);
|
142
|
+
|
143
|
+
// 单选模式下关闭下拉框
|
144
|
+
if (selectInstance.current) {
|
145
|
+
selectInstance.current.blur();
|
146
|
+
}
|
147
|
+
}
|
148
|
+
};
|
149
|
+
|
150
|
+
const itemConfigs = useMemo(() => {
|
151
|
+
if (Array.isArray(listItemConfigs) && listItemConfigs?.length) return listItemConfigs;
|
152
|
+
return defaultListItemConfigs;
|
153
|
+
}, [listItemConfigs]);
|
154
|
+
|
155
|
+
// 默认渲染项(增加选中状态和点击处理)
|
156
|
+
const defaultRenderItem = useCallback(
|
157
|
+
(item: Person) => {
|
158
|
+
let isSelected;
|
159
|
+
|
160
|
+
if (selectProps.mode === "multiple") {
|
161
|
+
isSelected = (selectProps.value || [])
|
162
|
+
.map((it) => (isObject(it) ? it?.value || it?.userId : it))
|
163
|
+
.includes(item.userId);
|
164
|
+
} else {
|
165
|
+
isSelected = isObject(selectProps.value) ? (selectProps.value as LableValue)?.value === item.userId : false;
|
166
|
+
}
|
167
|
+
|
168
|
+
const disabled = item?.[disabledKey] || false;
|
169
|
+
const getDisabledStyle: React.CSSProperties =
|
170
|
+
typeof disabledStyle === "function"
|
171
|
+
? disabledStyle(disabled)
|
172
|
+
: {
|
173
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
174
|
+
backgroundColor: disabled ? "#f0f0f0" : isSelected ? "#e6f7ff" : "inherit",
|
175
|
+
color: disabled ? "#999" : "inherit",
|
176
|
+
filter: disabled ? "grayscale(100%)" : "none",
|
177
|
+
};
|
178
|
+
|
179
|
+
return (
|
180
|
+
<List.Item
|
181
|
+
key={item.userId}
|
182
|
+
onClick={() => (disabled ? null : handleItemClick(item.userId))}
|
183
|
+
style={getDisabledStyle}
|
184
|
+
>
|
185
|
+
{customItemNode ? (
|
186
|
+
customItemNode
|
187
|
+
) : (
|
188
|
+
<div className="abt-user-item">
|
189
|
+
<div className="abt-user-item-avatar">
|
190
|
+
<Avatar alt={item?.userName} size={60} {...avataProps} src={item.avatar} />
|
191
|
+
</div>
|
192
|
+
<ul className="abt-user-item-info">
|
193
|
+
{itemConfigs.map((configItem) => (
|
194
|
+
<li className="abt-user-item-info__item">
|
195
|
+
<span>{configItem.label}</span>
|
196
|
+
<span>{item?.[configItem.key]}</span>
|
197
|
+
</li>
|
198
|
+
))}
|
199
|
+
</ul>
|
200
|
+
</div>
|
201
|
+
)}
|
202
|
+
</List.Item>
|
203
|
+
);
|
204
|
+
},
|
205
|
+
[selectProps.value],
|
206
|
+
);
|
207
|
+
|
208
|
+
// 自定义下拉内容
|
209
|
+
const dropdownRender = (menu: React.ReactNode) => (
|
210
|
+
<div ref={listRef}>
|
211
|
+
<Spin spinning={loading}>
|
212
|
+
<List
|
213
|
+
loading={loadingMore}
|
214
|
+
dataSource={list}
|
215
|
+
renderItem={renderItem ? renderItem : defaultRenderItem}
|
216
|
+
/*@ts-ignore*/
|
217
|
+
onScroll={handleScroll}
|
218
|
+
style={{ maxHeight: 250, overflowY: "auto" }}
|
219
|
+
/>
|
220
|
+
</Spin>
|
221
|
+
</div>
|
222
|
+
);
|
223
|
+
|
224
|
+
return (
|
225
|
+
<Select
|
226
|
+
{...selectProps}
|
227
|
+
ref={selectInstance}
|
228
|
+
showSearch
|
229
|
+
onSearch={handleSearch}
|
230
|
+
filterOption={false}
|
231
|
+
dropdownRender={dropdownRender}
|
232
|
+
placeholder="请选择人员"
|
233
|
+
// 增加虚拟的options用于显示选中标签
|
234
|
+
options={list.map((item) => ({
|
235
|
+
value: item.userId,
|
236
|
+
label: item.userName,
|
237
|
+
}))}
|
238
|
+
/>
|
239
|
+
);
|
240
|
+
};
|
241
|
+
|
242
|
+
// Formily集成
|
243
|
+
const PersonnelSelect = connect(
|
244
|
+
RemoteSelect,
|
245
|
+
mapProps(
|
246
|
+
{
|
247
|
+
loading: true,
|
248
|
+
},
|
249
|
+
(props, field: any) => {
|
250
|
+
return {
|
251
|
+
...props,
|
252
|
+
};
|
253
|
+
},
|
254
|
+
),
|
255
|
+
);
|
256
|
+
|
257
|
+
export { RemoteSelect, PersonnelSelect };
|
File without changes
|
package/src/components/index.tsx
CHANGED
package/src/index.less
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
.form-render {
|
2
|
-
|
3
2
|
&.ant-form-inline,
|
4
|
-
&.ant-form-inline>form,
|
5
|
-
&.ant-form-inline>form
|
3
|
+
&.ant-form-inline > form,
|
4
|
+
&.ant-form-inline > form > .ant-formily-layout {
|
6
5
|
display: inline-flex;
|
7
6
|
flex-wrap: wrap;
|
8
|
-
|
9
7
|
.ant-formily-item-control {
|
10
8
|
min-width: 120px;
|
11
9
|
}
|
12
|
-
|
13
10
|
.ant-picker-range {
|
14
11
|
min-width: 340px;
|
15
12
|
}
|
16
|
-
|
17
13
|
.ant-formily-item-layout-inline {
|
18
14
|
margin-right: 12px;
|
19
15
|
margin-bottom: 12px;
|
20
16
|
}
|
21
17
|
}
|
22
|
-
}
|
18
|
+
}
|
package/src/index.tsx
CHANGED
@@ -37,7 +37,6 @@ import { GlobalPropsContext } from "./common/global-props-context";
|
|
37
37
|
import { bindOnChange } from "./common/schema-handler";
|
38
38
|
|
39
39
|
import "./index.less";
|
40
|
-
import "./custom-theme.less";
|
41
40
|
|
42
41
|
const antdComponents = {
|
43
42
|
Form,
|
@@ -164,16 +163,13 @@ const FormRender = forwardRef((props: any, parentRef) => {
|
|
164
163
|
schemaScope: schemaScopeRef.current,
|
165
164
|
onChange: props.onChange,
|
166
165
|
formRender,
|
167
|
-
customTheme: props.customTheme
|
168
166
|
});
|
169
167
|
}, []);
|
170
168
|
|
171
|
-
const className = props.customTheme === true ? 'form-render-custom-theme' : typeof props.customTheme === 'string' ? `form-render-${props.customTheme}` : '';
|
172
|
-
|
173
169
|
return (
|
174
170
|
<GlobalPropsContext.Provider value={props}>
|
175
171
|
<Form
|
176
|
-
className={`form-render ${props.className}
|
172
|
+
className={`form-render ${props.className}`}
|
177
173
|
layout={props.layout}
|
178
174
|
form={formRender}
|
179
175
|
labelCol={props.schema.form.labelCol}
|
package/src/custom-theme.less
DELETED
@@ -1,488 +0,0 @@
|
|
1
|
-
@primaryColor: var(--form-render-primary-color); // 主题色
|
2
|
-
@textColor: var(--form-render-color); // 字体颜色
|
3
|
-
@bgColor: var(--form-render-bg-color); // 背景颜色
|
4
|
-
@tableBgColor: var(--form-render-table-bg-color); // 表格背景颜色
|
5
|
-
@tableColor: var(--form-render-table-color); // 表格字体颜色
|
6
|
-
@talbeBorderColor: var(--form-render-table-border-color); // 表格边框颜色
|
7
|
-
@tableWrapperBorderColor: var(--form-render-table-wrapper-border-color); // 表格表头下边框颜色
|
8
|
-
@tableCellHoverBgColor: var(--form-render-table-cell-hover-bg-color); // 表格单元格滑过背景颜色
|
9
|
-
@tableCellHoverColor: var(--form-render-table-cell-hover-color); // 表格单元格滑过字体颜色
|
10
|
-
@btnOkColor: var(--form-render-btn-ok-color); // 确认按钮字体颜色
|
11
|
-
@btnOkBgColor: var(--form-render-btn-ok-bg-color); // 确认按钮背景颜色
|
12
|
-
@btnOkBgHoverColor: var(--form-render-btn-ok-bg-hover-color); // 确认按钮滑过字体颜色
|
13
|
-
@btnOkBorderColor: var(--form-render-btn-ok-border-color); // 确认按钮边框颜色
|
14
|
-
@btnDefaultColor: var(--form-render-btn-default-color); // 默认按钮字体颜色
|
15
|
-
@btnDefaultBgColor: var(--form-render-btn-default-bg-color); // 默认按钮背景颜色
|
16
|
-
@btnDefaultBorderColor: var(--form-render-btn-default-border-color); // 默认按钮边框颜色
|
17
|
-
@btnDefaultBgHoverColor: var(--form-render-btn-default-bg-hover-color); // 默认按钮滑过背景颜色
|
18
|
-
@inputColor: var(--form-render-input-color); // 输入框字体颜色
|
19
|
-
@formLabelColor: var(--form-render-form-label-color); // 表单项label字体颜色
|
20
|
-
@formReqiredColor: var(--form-render-form-required-color); // 表单项必填字体颜色
|
21
|
-
@inputHoverColor: var(--form-render-input-hover-color); // 输入框滑过字体颜色
|
22
|
-
@inputBgColor: var(--form-render-input-bg-color); // 输入框背景颜色
|
23
|
-
@inputBorderColor: var(--form-render-input-border-color); // 输入框边框颜色
|
24
|
-
@inputBorderHoverColor: var(--form-render-input-border-hover-color); // 输入框滑过边框颜色
|
25
|
-
@selectColor: var(--form-render-select-color); // 选择器字体颜色
|
26
|
-
@selectHoverColor: var(--form-render-select-hover-color); // 选择器滑过字体颜色
|
27
|
-
@selectBgColor: var(--form-render-select-bg-color); // 选择器背景颜色
|
28
|
-
@selectBgHoverColor: var(--form-render-select-bg-hover-color); // 选择器滑过背景颜色
|
29
|
-
@selectBorderColor: var(--form-render-select-border-color); // 选择器边框颜色
|
30
|
-
@iconColor: var(--form-render-icon-color); // 图标颜色
|
31
|
-
@iconHoverColor: var(--form-render-icon-hover-color); // 图标滑过颜色
|
32
|
-
@iconBgColor: var(--form-render-icon-bg-color); // 图标背景颜色
|
33
|
-
@iconBgHoverColor: var(--form-render-icon-bg-hover-color); // 图标滑过背景颜色
|
34
|
-
@pickerCellDisabled: var(--form-render-picker-cell-disabled); // 时间选择器禁用项字体颜色
|
35
|
-
@pickerRangeStartAEndBgColor: var(--form-render-picker-range-start-or-end-bg-color); // 时间选择器起止项背景颜色
|
36
|
-
@pickerRangeBgStartHoverColor: var(--form-render-picker-range-bg-start-hover-color); // 时间选择器滑过起始项字体颜色
|
37
|
-
@pickerRangeBgHoverColor: var(--form-render-picker-range-bg-hover-color); // 时间选择器选择区间背景颜色
|
38
|
-
@radioCheckedColor: var(--form-render-radio-checked-color); // 单选框选中状态颜色
|
39
|
-
@radioBgColor: var(--form-render-radio-bg-color); // 单选框背景颜色
|
40
|
-
@radioColor: var(--form-render-radio-color); // 单选框字体颜色
|
41
|
-
@checkboxCheckedColor: var(--form-render-checkbox-checked-color); // 复选框选中状态颜色
|
42
|
-
@checkboxBgColor: var(--form-render-checkbox-bg-color); // 复选框背景颜色
|
43
|
-
@checkboxColor: var(--form-render-checkbox-color); // 复选框字体颜色
|
44
|
-
|
45
|
-
// 表单项集合
|
46
|
-
.mixinColor() {
|
47
|
-
.ant-select:not(.ant-select-disabled) {
|
48
|
-
color: @selectColor;
|
49
|
-
|
50
|
-
&:hover {
|
51
|
-
color: @inputHoverColor;
|
52
|
-
}
|
53
|
-
|
54
|
-
.ant-select-selector {
|
55
|
-
background-color: @selectBgColor;
|
56
|
-
|
57
|
-
.ant-btn-icon-only {
|
58
|
-
color: @iconColor;
|
59
|
-
background-color: @selectBgColor;
|
60
|
-
|
61
|
-
&:hover {
|
62
|
-
color: @iconHoverColor;
|
63
|
-
background-color: @inputBgColor;
|
64
|
-
border-color: @inputBorderHoverColor;
|
65
|
-
}
|
66
|
-
}
|
67
|
-
}
|
68
|
-
}
|
69
|
-
|
70
|
-
.ant-select-tree {
|
71
|
-
color: @selectColor;
|
72
|
-
background-color: @selectBgColor;
|
73
|
-
|
74
|
-
.ant-select-tree-node-content-wrapper:hover,
|
75
|
-
.ant-select-tree-node-content-wrapper.ant-select-tree-node-selected {
|
76
|
-
color: @selectHoverColor;
|
77
|
-
background-color: @selectBgHoverColor;
|
78
|
-
}
|
79
|
-
}
|
80
|
-
|
81
|
-
.ant-select-item {
|
82
|
-
color: @selectColor;
|
83
|
-
|
84
|
-
.ant-select-item-option-content {
|
85
|
-
&>div {
|
86
|
-
|
87
|
-
>div,
|
88
|
-
>span {
|
89
|
-
color: @selectColor;
|
90
|
-
}
|
91
|
-
}
|
92
|
-
|
93
|
-
&:hover {
|
94
|
-
>div {
|
95
|
-
|
96
|
-
>div,
|
97
|
-
>span {
|
98
|
-
color: @selectHoverColor;
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
}
|
103
|
-
}
|
104
|
-
|
105
|
-
.ant-select-item.ant-select-item-option-selected,
|
106
|
-
.ant-select-item.ant-select-item-option-active {
|
107
|
-
color: @selectHoverColor;
|
108
|
-
background-color: @selectBgHoverColor;
|
109
|
-
}
|
110
|
-
|
111
|
-
.ant-select-arrow,
|
112
|
-
.ant-select-clear,
|
113
|
-
.ant-picker-suffix,
|
114
|
-
.ant-picker-clear,
|
115
|
-
.ant-collapse-expand-icon,
|
116
|
-
.ant-btn-icon-only,
|
117
|
-
.ant-table-cell button.ant-table-row-expand-icon {
|
118
|
-
color: @iconColor;
|
119
|
-
background-color: @iconBgColor;
|
120
|
-
|
121
|
-
&:hover {
|
122
|
-
color: @iconHoverColor;
|
123
|
-
background-color: @iconBgHoverColor;
|
124
|
-
}
|
125
|
-
}
|
126
|
-
|
127
|
-
.ant-formily-item-label {
|
128
|
-
color: @formLabelColor;
|
129
|
-
|
130
|
-
.ant-formily-item-asterisk {
|
131
|
-
color: @formReqiredColor;
|
132
|
-
}
|
133
|
-
}
|
134
|
-
|
135
|
-
.ant-input-affix-wrapper,
|
136
|
-
.ant-select:not(.ant-select-disabled) .ant-select-selector,
|
137
|
-
.ant-input-number,
|
138
|
-
.ant-upload,
|
139
|
-
.ant-collapse-item,
|
140
|
-
.ant-collapse-content,
|
141
|
-
.ant-card-head,
|
142
|
-
.ant-collapse-header-text,
|
143
|
-
.ant-picker-header,
|
144
|
-
.ant-picker-header button,
|
145
|
-
.ant-input {
|
146
|
-
color: @inputColor;
|
147
|
-
background-color: @inputBgColor;
|
148
|
-
border-color: @inputBorderColor;
|
149
|
-
|
150
|
-
&:not(.ant-card-head):hover {
|
151
|
-
color: @inputHoverColor;
|
152
|
-
border-color: @inputBorderHoverColor;
|
153
|
-
}
|
154
|
-
}
|
155
|
-
|
156
|
-
.ant-picker {
|
157
|
-
color: @inputColor;
|
158
|
-
background-color: @inputBgColor;
|
159
|
-
border-color: @inputBorderColor;
|
160
|
-
|
161
|
-
.ant-picker-input>input {
|
162
|
-
color: @inputColor;
|
163
|
-
|
164
|
-
&:hover {
|
165
|
-
color: @inputHoverColor;
|
166
|
-
}
|
167
|
-
}
|
168
|
-
|
169
|
-
.ant-picker-separator {
|
170
|
-
color: @inputColor;
|
171
|
-
|
172
|
-
&:hover {
|
173
|
-
color: @inputHoverColor;
|
174
|
-
}
|
175
|
-
}
|
176
|
-
}
|
177
|
-
|
178
|
-
.ant-picker-panel {
|
179
|
-
.ant-picker-body {
|
180
|
-
.ant-picker-content {
|
181
|
-
.ant-picker-cell {
|
182
|
-
color: @selectColor;
|
183
|
-
|
184
|
-
&:hover:not(.ant-picker-cell-selected):not(.ant-picker-cell-range-start):not(.ant-picker-cell-range-end):not(.ant-picker-cell-range-hover-start):not(.ant-picker-cell-range-hover-end) {
|
185
|
-
.ant-picker-cell-inner {
|
186
|
-
background-color: @selectBgHoverColor;
|
187
|
-
color: @selectHoverColor;
|
188
|
-
}
|
189
|
-
}
|
190
|
-
|
191
|
-
&:hover:not(.ant-picker-cell-in-view) {
|
192
|
-
.ant-picker-cell-inner {
|
193
|
-
background-color: @selectBgHoverColor;
|
194
|
-
}
|
195
|
-
}
|
196
|
-
|
197
|
-
&.ant-picker-cell-in-view.ant-picker-cell-range-end:not(.ant-picker-cell-range-end-single) {
|
198
|
-
&::before {
|
199
|
-
background-color: @selectBgHoverColor;
|
200
|
-
}
|
201
|
-
}
|
202
|
-
|
203
|
-
&.ant-picker-cell-in-view.ant-picker-cell-in-range {
|
204
|
-
&::before {
|
205
|
-
background-color: @selectBgHoverColor;
|
206
|
-
}
|
207
|
-
|
208
|
-
&.ant-picker-cell-range-hover-start,
|
209
|
-
&.ant-picker-cell-range-hover-end {
|
210
|
-
&::before {
|
211
|
-
background-color: @pickerRangeBgStartHoverColor;
|
212
|
-
}
|
213
|
-
|
214
|
-
.ant-picker-cell-inner {
|
215
|
-
&::after {
|
216
|
-
background-color: @pickerRangeBgStartHoverColor;
|
217
|
-
}
|
218
|
-
}
|
219
|
-
}
|
220
|
-
|
221
|
-
&.ant-picker-cell-range-hover {
|
222
|
-
&::before {
|
223
|
-
background-color: @pickerRangeBgHoverColor;
|
224
|
-
}
|
225
|
-
}
|
226
|
-
|
227
|
-
.ant-picker-cell-inner {
|
228
|
-
color: @selectHoverColor;
|
229
|
-
|
230
|
-
&::after {
|
231
|
-
background-color: @selectBgHoverColor;
|
232
|
-
}
|
233
|
-
}
|
234
|
-
}
|
235
|
-
|
236
|
-
&.ant-picker-cell-in-view {
|
237
|
-
color: @selectHoverColor;
|
238
|
-
|
239
|
-
&.ant-picker-cell-range-start:not(.ant-picker-cell-range-start-single),
|
240
|
-
&.ant-picker-cell-range-end {
|
241
|
-
&::before {
|
242
|
-
background-color: @pickerRangeStartAEndBgColor;
|
243
|
-
}
|
244
|
-
}
|
245
|
-
|
246
|
-
&.ant-picker-cell-selected {
|
247
|
-
.ant-picker-cell-inner {
|
248
|
-
background-color: @pickerRangeStartAEndBgColor;
|
249
|
-
;
|
250
|
-
}
|
251
|
-
}
|
252
|
-
|
253
|
-
&.ant-picker-cell-disabled {
|
254
|
-
color: @pickerCellDisabled;
|
255
|
-
}
|
256
|
-
}
|
257
|
-
}
|
258
|
-
}
|
259
|
-
}
|
260
|
-
}
|
261
|
-
|
262
|
-
.ant-radio-group {
|
263
|
-
.ant-radio-wrapper {
|
264
|
-
.ant-radio+span {
|
265
|
-
color: @radioColor;
|
266
|
-
}
|
267
|
-
|
268
|
-
&.ant-radio-wrapper-checked {
|
269
|
-
.ant-radio.ant-radio-checked {
|
270
|
-
.ant-radio-inner {
|
271
|
-
background-color: @radioBgColor;
|
272
|
-
|
273
|
-
&::after {
|
274
|
-
background-color: @radioCheckedColor;
|
275
|
-
}
|
276
|
-
}
|
277
|
-
}
|
278
|
-
}
|
279
|
-
}
|
280
|
-
}
|
281
|
-
|
282
|
-
.ant-checkbox-group {
|
283
|
-
.ant-checkbox-wrapper {
|
284
|
-
.ant-checkbox+span {
|
285
|
-
color: @checkboxColor;
|
286
|
-
}
|
287
|
-
|
288
|
-
&.ant-checkbox-wrapper-checked {
|
289
|
-
.ant-checkbox.ant-checkbox-checked {
|
290
|
-
.ant-checkbox-inner {
|
291
|
-
background-color: @checkboxBgColor;
|
292
|
-
|
293
|
-
&::after {
|
294
|
-
border-color: @checkboxCheckedColor;
|
295
|
-
}
|
296
|
-
}
|
297
|
-
}
|
298
|
-
}
|
299
|
-
}
|
300
|
-
}
|
301
|
-
|
302
|
-
.ant-upload-list-item-actions {
|
303
|
-
a {
|
304
|
-
color: @iconColor;
|
305
|
-
}
|
306
|
-
}
|
307
|
-
|
308
|
-
.ant-upload-span {
|
309
|
-
color: @inputColor;
|
310
|
-
fill: @inputColor;
|
311
|
-
}
|
312
|
-
|
313
|
-
.ant-switch {
|
314
|
-
background-color: @inputColor;
|
315
|
-
|
316
|
-
&.ant-switch-checked {
|
317
|
-
background-color: @primaryColor;
|
318
|
-
|
319
|
-
&:focus {
|
320
|
-
box-shadow: none;
|
321
|
-
}
|
322
|
-
}
|
323
|
-
}
|
324
|
-
|
325
|
-
|
326
|
-
.ant-cascader-menu-item {
|
327
|
-
&:hover {
|
328
|
-
background-color: @selectBgHoverColor;
|
329
|
-
}
|
330
|
-
|
331
|
-
&.ant-cascader-menu-item-active:not(.ant-cascader-menu-item-disabled) {
|
332
|
-
background-color: @selectBgHoverColor;
|
333
|
-
color: @selectHoverColor;
|
334
|
-
}
|
335
|
-
}
|
336
|
-
|
337
|
-
.ant-btn.ant-btn-primary {
|
338
|
-
color: @btnOkColor;
|
339
|
-
background-color: @btnOkBgColor;
|
340
|
-
border-color: @btnOkBorderColor;
|
341
|
-
|
342
|
-
&:hover,
|
343
|
-
&:focus {
|
344
|
-
border-color: @primaryColor;
|
345
|
-
background-color: @btnOkBgHoverColor;
|
346
|
-
}
|
347
|
-
}
|
348
|
-
|
349
|
-
.ant-btn.ant-btn-default {
|
350
|
-
color: @btnDefaultColor;
|
351
|
-
background-color: @btnDefaultBgColor;
|
352
|
-
border-color: @btnDefaultBorderColor;
|
353
|
-
|
354
|
-
&:hover,
|
355
|
-
&:focus {
|
356
|
-
color: @primaryColor;
|
357
|
-
border-color: @primaryColor;
|
358
|
-
background-color: @btnDefaultBgHoverColor;
|
359
|
-
}
|
360
|
-
}
|
361
|
-
|
362
|
-
.ant-btn.ant-btn-dashed {
|
363
|
-
color: @btnDefaultColor;
|
364
|
-
background-color: @btnDefaultBgColor;
|
365
|
-
border-color: @btnDefaultBorderColor;
|
366
|
-
|
367
|
-
&:hover,
|
368
|
-
&:focus {
|
369
|
-
color: @primaryColor;
|
370
|
-
border-color: @primaryColor;
|
371
|
-
}
|
372
|
-
}
|
373
|
-
}
|
374
|
-
|
375
|
-
.form-render-custom-theme {
|
376
|
-
background-color: @bgColor;
|
377
|
-
color: @textColor;
|
378
|
-
|
379
|
-
.ant-formily-item,
|
380
|
-
.ant-collapse,
|
381
|
-
.ant-card,
|
382
|
-
.ant-formily-array-table .ant-formily-array-table-sort-helper {
|
383
|
-
background-color: @bgColor;
|
384
|
-
color: @textColor;
|
385
|
-
.mixinColor();
|
386
|
-
|
387
|
-
.ant-table-cell {
|
388
|
-
.ant-empty-normal {
|
389
|
-
color: @tableColor;
|
390
|
-
}
|
391
|
-
|
392
|
-
&:hover {
|
393
|
-
background-color: @tableCellHoverBgColor;
|
394
|
-
|
395
|
-
.ant-empty-normal {
|
396
|
-
color: @tableCellHoverColor;
|
397
|
-
}
|
398
|
-
}
|
399
|
-
}
|
400
|
-
}
|
401
|
-
|
402
|
-
.ant-formily-item-control {
|
403
|
-
.ant-table {
|
404
|
-
background-color: @tableBgColor;
|
405
|
-
color: @tableColor;
|
406
|
-
|
407
|
-
.ant-formily-array-table .ant-formily-array-table-sort-helper {
|
408
|
-
background-color: @tableBgColor;
|
409
|
-
}
|
410
|
-
|
411
|
-
.ant-table-thead>tr>th {
|
412
|
-
background-color: @tableBgColor;
|
413
|
-
color: @tableColor;
|
414
|
-
}
|
415
|
-
|
416
|
-
.ant-table-row {
|
417
|
-
|
418
|
-
// 此处原因:会出现弹窗关闭后,鼠标刚好停留在外表格的某一行,导致ant-table-cell-row-hover类名未正常出现,渲染颜色错误
|
419
|
-
&:hover {
|
420
|
-
td {
|
421
|
-
background-color: @tableCellHoverBgColor;
|
422
|
-
color: @tableCellHoverColor;
|
423
|
-
}
|
424
|
-
}
|
425
|
-
|
426
|
-
& .ant-table-cell-row-hover {
|
427
|
-
background-color: @tableCellHoverBgColor;
|
428
|
-
color: @tableCellHoverColor;
|
429
|
-
}
|
430
|
-
}
|
431
|
-
}
|
432
|
-
}
|
433
|
-
}
|
434
|
-
|
435
|
-
.form-dialog-custom-theme {
|
436
|
-
background-color: @selectBgColor;
|
437
|
-
color: @selectColor;
|
438
|
-
.mixinColor();
|
439
|
-
|
440
|
-
.ant-table {
|
441
|
-
background-color: @tableBgColor;
|
442
|
-
color: @tableColor;
|
443
|
-
|
444
|
-
.ant-formily-array-table .ant-formily-array-table-sort-helper {
|
445
|
-
background-color: @tableBgColor;
|
446
|
-
}
|
447
|
-
|
448
|
-
.ant-table-thead>tr>th {
|
449
|
-
background-color: @tableBgColor;
|
450
|
-
color: @tableColor;
|
451
|
-
}
|
452
|
-
|
453
|
-
.ant-table-row {
|
454
|
-
|
455
|
-
// 此处原因:会出现弹窗关闭后,鼠标刚好停留在外表格的某一行,导致ant-table-cell-row-hover类名未正常出现,渲染颜色错误
|
456
|
-
&:hover {
|
457
|
-
td {
|
458
|
-
background-color: @tableCellHoverBgColor;
|
459
|
-
color: @tableCellHoverColor;
|
460
|
-
}
|
461
|
-
}
|
462
|
-
}
|
463
|
-
}
|
464
|
-
|
465
|
-
.ant-picker-panel-container {
|
466
|
-
color: @selectColor;
|
467
|
-
background-color: @selectBgColor;
|
468
|
-
|
469
|
-
.ant-picker-time-panel-cell .ant-picker-time-panel-cell-inner {
|
470
|
-
color: @selectColor;
|
471
|
-
|
472
|
-
&:hover {
|
473
|
-
background-color: @selectBgHoverColor;
|
474
|
-
color: @selectHoverColor;
|
475
|
-
}
|
476
|
-
}
|
477
|
-
|
478
|
-
.ant-picker-time-panel-cell-selected .ant-picker-time-panel-cell-inner {
|
479
|
-
background-color: @selectBgHoverColor;
|
480
|
-
color: @selectHoverColor;
|
481
|
-
}
|
482
|
-
|
483
|
-
}
|
484
|
-
|
485
|
-
.ant-empty-small {
|
486
|
-
color: @selectColor;
|
487
|
-
}
|
488
|
-
}
|