@hzab/form-render 1.4.1 → 1.5.0-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 +3 -2
- package/package.json +2 -2
- package/src/common/schema-handler.ts +106 -29
- package/src/components/ArrayBase/index.tsx +315 -0
- package/src/components/ArrayBase/style.less +87 -0
- package/src/components/ArrayBase/style.ts +2 -0
- package/src/components/ArrayCards/index.tsx +151 -0
- package/src/components/ArrayCards/style.less +15 -0
- package/src/components/ArrayCards/style.ts +4 -0
- package/src/components/ArrayTable/index.tsx +405 -0
- package/src/components/ArrayTable/style.less +53 -0
- package/src/components/ArrayTable/style.ts +7 -0
- package/src/components/DatePicker/index.tsx +1 -2
- package/src/components/Upload/README.md +28 -20
- package/src/components/Upload/common/customRequest.ts +34 -0
- package/src/components/Upload/common/fileName.ts +62 -0
- package/src/components/Upload/common/handleIOFileList.ts +302 -0
- package/src/components/Upload/common/nanoid.ts +7 -0
- package/src/components/Upload/common/ossUpload.js +9 -13
- package/src/components/Upload/common/utils.js +29 -13
- package/src/components/Upload/components/ItemList/index.tsx +2 -3
- package/src/components/Upload/components/PreviewModal/index.tsx +0 -1
- package/src/components/Upload/index.tsx +23 -2
- package/src/components/Upload/uploader-input.jsx +48 -12
- package/src/components/Upload/uploader.jsx +88 -83
- package/src/components/index.tsx +3 -0
- package/src/index.tsx +11 -8
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
@@ -1,4 +1,36 @@
|
|
1
1
|
import _ from "lodash";
|
2
|
+
import { customAlphabet } from "nanoid";
|
3
|
+
|
4
|
+
/**
|
5
|
+
* 指定 nanoid 字符集合
|
6
|
+
*/
|
7
|
+
export const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
8
|
+
export const nanoid = customAlphabet(alphabet, 20);
|
9
|
+
|
10
|
+
/**
|
11
|
+
* You can use the built-in context variables
|
12
|
+
*
|
13
|
+
* 1. `$self` is the current Field Model
|
14
|
+
*
|
15
|
+
* 2. `$form` is the current Form Model
|
16
|
+
*
|
17
|
+
* 3. `$deps` is the dependencies value
|
18
|
+
*
|
19
|
+
* 4. `$observable` function is used to create an persistent observable state object
|
20
|
+
*
|
21
|
+
* 5. `$memo` function is is used to create a persistent data
|
22
|
+
*
|
23
|
+
* 6. `$effect` function is used to handle side-effect logic
|
24
|
+
*
|
25
|
+
* 7. `$props` function is used to set component props to current field
|
26
|
+
*
|
27
|
+
* Document Links
|
28
|
+
*
|
29
|
+
* https://react.formilyjs.org/api/shared/schema#%E5%86%85%E7%BD%AE%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%BD%9C%E7%94%A8%E5%9F%9F
|
30
|
+
**/
|
31
|
+
|
32
|
+
/** formily 执行函数作用域相关参数 */
|
33
|
+
export const formilyDataKeys = ["$form", "$self", "$observable", "$effect", "$memo", "$props", "$values", "$deps"];
|
2
34
|
|
3
35
|
/** 自增容器 */
|
4
36
|
export const arrayList = ["ArrayTable", "ArrayCards"];
|
@@ -29,8 +61,8 @@ export const bindOnChange = (schema, opt) => {
|
|
29
61
|
const comProps = item?.["x-component-props"];
|
30
62
|
if (!comProps) {
|
31
63
|
item["x-component-props"] = {};
|
32
|
-
} else if (isScopeKey(comProps)) {
|
33
|
-
item["x-component-props"] =
|
64
|
+
} else if (isScopeKey(comProps, schemaScope)) {
|
65
|
+
item["x-component-props"] = getScopeKeyVal(comProps, schemaScope) || {};
|
34
66
|
}
|
35
67
|
|
36
68
|
const bindParams = {
|
@@ -90,16 +122,24 @@ export const bindOnChange = (schema, opt) => {
|
|
90
122
|
export const bindCallback = (opt) => {
|
91
123
|
const { target, actionName, schemaScope, formOnChange } = opt || {};
|
92
124
|
const tempFn = target[actionName];
|
93
|
-
|
125
|
+
if (!schemaScope._$tempData) {
|
126
|
+
schemaScope._$tempData = {};
|
127
|
+
}
|
128
|
+
// 设置一个唯一的函数名,用于从 schema scope 传入 formily 事件执行中
|
129
|
+
const fnKey = "fnKey_" + nanoid();
|
130
|
+
// 设置 schemaScope 中的唯一函数,获取执行函数作用域 $form, $self, $observable, $effect, $memo, $props, $values, $deps 相关参数
|
131
|
+
schemaScope._$tempData[fnKey] = function (params, sourceArgs) {
|
132
|
+
const { $form, $self, $observable, $effect, $memo, $props, $values, $deps } = params;
|
94
133
|
// 处理结果数据,各组件返回数据格式不一致
|
95
134
|
const res = handleChangeValue({
|
96
135
|
...opt,
|
97
136
|
sourceArgs,
|
98
137
|
});
|
99
138
|
// 触发组件 onChange 事件
|
100
|
-
if (
|
139
|
+
if (isRunStr(tempFn)) {
|
101
140
|
// schemaScope 传入方式
|
102
|
-
const fn =
|
141
|
+
const fn = handleSchemaStrVal(tempFn, { ...params, ...schemaScope });
|
142
|
+
|
103
143
|
typeof fn === "function" && fn(...sourceArgs, res);
|
104
144
|
} else if (typeof tempFn === "function") {
|
105
145
|
// 直接传入函数的方式
|
@@ -107,6 +147,17 @@ export const bindCallback = (opt) => {
|
|
107
147
|
}
|
108
148
|
formOnChange && formOnChange(res);
|
109
149
|
};
|
150
|
+
|
151
|
+
// 通过 formily 字符串执行的方式回去函数作用域参数
|
152
|
+
target[actionName] = `{{
|
153
|
+
function t() {
|
154
|
+
// 执行 ${fnKey} 唯一函数,formily 当前函数作用域相关参数
|
155
|
+
return _$tempData && _$tempData.${fnKey} && _$tempData.${fnKey}(
|
156
|
+
{ ${formilyDataKeys.join(", ")} },
|
157
|
+
arguments
|
158
|
+
);
|
159
|
+
}
|
160
|
+
}}`;
|
110
161
|
};
|
111
162
|
|
112
163
|
/**
|
@@ -114,8 +165,7 @@ export const bindCallback = (opt) => {
|
|
114
165
|
* @param args
|
115
166
|
*/
|
116
167
|
export const handleChangeValue = (opt) => {
|
117
|
-
const {
|
118
|
-
console.log("parent", parent);
|
168
|
+
const { formRender, targetKey, actionName, sourceArgs } = opt || {};
|
119
169
|
// 自增表格、卡片无法获知当前编辑内容所在的索引,导致无法知道当前值
|
120
170
|
const res = {
|
121
171
|
key: targetKey,
|
@@ -123,26 +173,16 @@ export const handleChangeValue = (opt) => {
|
|
123
173
|
formRender,
|
124
174
|
formValues: formRender.values,
|
125
175
|
sourceArgs: sourceArgs,
|
126
|
-
// value: formRender.getValuesIn(targetKey),
|
127
|
-
// parent,
|
128
|
-
// TODO: 自增情况下无法获知索引
|
129
|
-
// parentValue: formRender.getValuesIn(parent?.name),
|
130
176
|
};
|
131
177
|
|
132
|
-
// TODO: 自增返回父级值?
|
133
|
-
// if (returnParentValue.includes(parent?.["x-component"])) {
|
134
|
-
// res.value = res.parentValue;
|
135
|
-
// }
|
136
|
-
|
137
178
|
return res;
|
138
179
|
};
|
139
180
|
|
140
181
|
/**
|
141
|
-
*
|
142
|
-
* @param
|
143
|
-
* @returns
|
182
|
+
* 是否是可执行字符串,为 {{}} 包裹的字符串
|
183
|
+
* @param params
|
144
184
|
*/
|
145
|
-
export const
|
185
|
+
export const isRunStr = (strKey) => {
|
146
186
|
if (typeof strKey !== "string") {
|
147
187
|
return false;
|
148
188
|
}
|
@@ -151,12 +191,12 @@ export const isScopeKey = (strKey) => {
|
|
151
191
|
};
|
152
192
|
|
153
193
|
/**
|
154
|
-
*
|
155
|
-
* @param
|
156
|
-
* @returns
|
194
|
+
* 获取可执行字符串,返回 {{}} 包裹的字符串
|
195
|
+
* @param params
|
157
196
|
*/
|
158
|
-
export const
|
159
|
-
|
197
|
+
export const getRunStr = (strKey) => {
|
198
|
+
const _isRunStr = isRunStr(strKey);
|
199
|
+
if (!_isRunStr) {
|
160
200
|
return "";
|
161
201
|
}
|
162
202
|
const key = strKey.trim();
|
@@ -164,13 +204,50 @@ export const getScopeKey = (strKey) => {
|
|
164
204
|
};
|
165
205
|
|
166
206
|
/**
|
167
|
-
*
|
207
|
+
* 处理 schema 字符串值
|
208
|
+
* 1.可执行字符串({{}}包裹的字符串):schema scope 取出对应的值,否则转为可执行函数
|
209
|
+
* 2.其他情况直接返回对应数据
|
168
210
|
* @param strKey
|
169
211
|
* @param schemaScope
|
170
212
|
* @returns
|
171
213
|
*/
|
172
|
-
export const
|
173
|
-
|
174
|
-
|
214
|
+
export const handleSchemaStrVal = (strKey, schemaScope) => {
|
215
|
+
const _str = getRunStr(strKey);
|
216
|
+
if (!_str) {
|
217
|
+
return strKey;
|
218
|
+
}
|
219
|
+
let fn = getScopeKeyVal(_str, schemaScope);
|
220
|
+
if (fn) {
|
221
|
+
return fn;
|
222
|
+
}
|
223
|
+
return new Function("$root", `with($root) { return (${_str}) }`)(schemaScope);
|
224
|
+
};
|
225
|
+
|
226
|
+
/**
|
227
|
+
* 是否是 schema scope key
|
228
|
+
* @param strKey
|
229
|
+
* @returns
|
230
|
+
*/
|
231
|
+
export const isScopeKey = (strKey, schemaScope) => {
|
232
|
+
const key = getRunStr(strKey);
|
233
|
+
if (!schemaScope || typeof schemaScope !== "object") {
|
234
|
+
throw new Error("请传入正确的 schema scope");
|
235
|
+
}
|
236
|
+
// 判断是否是 scope 变量名
|
237
|
+
if (!schemaScope?.[key]) {
|
238
|
+
return false;
|
239
|
+
}
|
240
|
+
return key;
|
241
|
+
};
|
242
|
+
|
243
|
+
/**
|
244
|
+
* 获取 schema scope key
|
245
|
+
* @param strKey
|
246
|
+
* @returns
|
247
|
+
*/
|
248
|
+
export const getScopeKeyVal = (strKey, schemaScope) => {
|
249
|
+
if (!isScopeKey(strKey, schemaScope)) {
|
250
|
+
return "";
|
175
251
|
}
|
252
|
+
return schemaScope[getRunStr(strKey)];
|
176
253
|
};
|
@@ -0,0 +1,315 @@
|
|
1
|
+
import { CopyOutlined, DeleteOutlined, DownOutlined, MenuOutlined, PlusOutlined, UpOutlined } from "@ant-design/icons";
|
2
|
+
import { ArrayField } from "@formily/core";
|
3
|
+
import { JSXComponent, Schema, useField, useFieldSchema } from "@formily/react";
|
4
|
+
import { clone, isUndef, isValid } from "@formily/shared";
|
5
|
+
import { Button } from "antd";
|
6
|
+
import { ButtonProps } from "antd/lib/button";
|
7
|
+
import cls from "classnames";
|
8
|
+
import React, { createContext, useContext } from "react";
|
9
|
+
import { SortableHandle, usePrefixCls } from "c-formily-antd/lib/__builtins__";
|
10
|
+
|
11
|
+
export interface IArrayBaseAdditionProps extends ButtonProps {
|
12
|
+
title?: string;
|
13
|
+
method?: "push" | "unshift";
|
14
|
+
defaultValue?: any;
|
15
|
+
}
|
16
|
+
export interface IArrayBaseOperationProps extends ButtonProps {
|
17
|
+
title?: string;
|
18
|
+
index?: number;
|
19
|
+
ref?: React.Ref<HTMLElement>;
|
20
|
+
}
|
21
|
+
|
22
|
+
export interface IArrayBaseContext {
|
23
|
+
props: IArrayBaseProps;
|
24
|
+
field: ArrayField;
|
25
|
+
schema: Schema;
|
26
|
+
}
|
27
|
+
|
28
|
+
export interface IArrayBaseItemProps {
|
29
|
+
index: number;
|
30
|
+
record: ((index: number) => Record<string, any>) | Record<string, any>;
|
31
|
+
}
|
32
|
+
|
33
|
+
export type ArrayBaseMixins = {
|
34
|
+
Addition?: React.FC<React.PropsWithChildren<IArrayBaseAdditionProps>>;
|
35
|
+
Copy?: React.FC<React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>>;
|
36
|
+
Remove?: React.FC<React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>>;
|
37
|
+
MoveUp?: React.FC<React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>>;
|
38
|
+
MoveDown?: React.FC<React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>>;
|
39
|
+
SortHandle?: React.FC<React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>>;
|
40
|
+
Index?: React.FC;
|
41
|
+
useArray?: () => IArrayBaseContext;
|
42
|
+
useIndex?: (index?: number) => number;
|
43
|
+
useRecord?: (record?: number) => any;
|
44
|
+
};
|
45
|
+
|
46
|
+
export interface IArrayBaseProps {
|
47
|
+
disabled?: boolean;
|
48
|
+
onAdd?: (index: number) => void;
|
49
|
+
onCopy?: (index: number) => void;
|
50
|
+
onRemove?: (index: number) => void;
|
51
|
+
onMoveDown?: (index: number) => void;
|
52
|
+
onMoveUp?: (index: number) => void;
|
53
|
+
}
|
54
|
+
|
55
|
+
type ComposedArrayBase = React.FC<React.PropsWithChildren<IArrayBaseProps>> &
|
56
|
+
ArrayBaseMixins & {
|
57
|
+
Item?: React.FC<React.PropsWithChildren<IArrayBaseItemProps>>;
|
58
|
+
mixin?: <T extends JSXComponent>(target: T) => T & ArrayBaseMixins;
|
59
|
+
};
|
60
|
+
|
61
|
+
const ArrayBaseContext = createContext<IArrayBaseContext>(null);
|
62
|
+
|
63
|
+
const ItemContext = createContext<IArrayBaseItemProps>(null);
|
64
|
+
|
65
|
+
const takeRecord = (val: any, index?: number) => (typeof val === "function" ? val(index) : val);
|
66
|
+
|
67
|
+
const useArray = () => {
|
68
|
+
return useContext(ArrayBaseContext);
|
69
|
+
};
|
70
|
+
|
71
|
+
const useIndex = (index?: number) => {
|
72
|
+
const ctx = useContext(ItemContext);
|
73
|
+
return ctx ? ctx.index : index;
|
74
|
+
};
|
75
|
+
|
76
|
+
const useRecord = (record?: number) => {
|
77
|
+
const ctx = useContext(ItemContext);
|
78
|
+
return takeRecord(ctx ? ctx.record : record, ctx?.index);
|
79
|
+
};
|
80
|
+
|
81
|
+
const getSchemaDefaultValue = (schema: Schema) => {
|
82
|
+
if (schema?.type === "array") return [];
|
83
|
+
if (schema?.type === "object") return {};
|
84
|
+
if (schema?.type === "void") {
|
85
|
+
for (let key in schema.properties) {
|
86
|
+
const value = getSchemaDefaultValue(schema.properties[key]);
|
87
|
+
if (isValid(value)) return value;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
};
|
91
|
+
|
92
|
+
const getDefaultValue = (defaultValue: any, schema: Schema) => {
|
93
|
+
if (isValid(defaultValue)) return clone(defaultValue);
|
94
|
+
if (Array.isArray(schema?.items)) return getSchemaDefaultValue(schema?.items[0]);
|
95
|
+
return getSchemaDefaultValue(schema?.items);
|
96
|
+
};
|
97
|
+
|
98
|
+
export const ArrayBase: ComposedArrayBase = (props) => {
|
99
|
+
const field = useField<ArrayField>();
|
100
|
+
const schema = useFieldSchema();
|
101
|
+
return <ArrayBaseContext.Provider value={{ field, schema, props }}>{props.children}</ArrayBaseContext.Provider>;
|
102
|
+
};
|
103
|
+
|
104
|
+
ArrayBase.Item = ({ children, ...props }) => {
|
105
|
+
return <ItemContext.Provider value={props}>{children}</ItemContext.Provider>;
|
106
|
+
};
|
107
|
+
|
108
|
+
const SortHandle = SortableHandle((props: any) => {
|
109
|
+
const prefixCls = usePrefixCls("formily-array-base");
|
110
|
+
return (
|
111
|
+
<MenuOutlined {...props} className={cls(`${prefixCls}-sort-handle`, props.className)} style={{ ...props.style }} />
|
112
|
+
);
|
113
|
+
}) as any;
|
114
|
+
|
115
|
+
ArrayBase.SortHandle = (props) => {
|
116
|
+
const array = useArray();
|
117
|
+
if (!array) return null;
|
118
|
+
if (array.field?.pattern !== "editable") return null;
|
119
|
+
return <SortHandle {...props} />;
|
120
|
+
};
|
121
|
+
|
122
|
+
ArrayBase.Index = (props) => {
|
123
|
+
const index = useIndex();
|
124
|
+
const prefixCls = usePrefixCls("formily-array-base");
|
125
|
+
return (
|
126
|
+
<span {...props} className={`${prefixCls}-index`}>
|
127
|
+
#{index + 1}.
|
128
|
+
</span>
|
129
|
+
);
|
130
|
+
};
|
131
|
+
|
132
|
+
ArrayBase.Addition = (props) => {
|
133
|
+
const self = useField();
|
134
|
+
const array = useArray();
|
135
|
+
const prefixCls = usePrefixCls("formily-array-base");
|
136
|
+
if (!array) return null;
|
137
|
+
if (array.field?.pattern !== "editable" && array.field?.pattern !== "disabled") return null;
|
138
|
+
return (
|
139
|
+
<Button
|
140
|
+
type="dashed"
|
141
|
+
block
|
142
|
+
{...props}
|
143
|
+
disabled={self?.disabled}
|
144
|
+
className={cls(`${prefixCls}-addition`, props.className)}
|
145
|
+
onClick={(e) => {
|
146
|
+
if (array.props?.disabled) return;
|
147
|
+
if (props.onClick) {
|
148
|
+
props.onClick(e);
|
149
|
+
if (e.defaultPrevented) return;
|
150
|
+
}
|
151
|
+
const defaultValue = getDefaultValue(props.defaultValue, array.schema);
|
152
|
+
if (props.method === "unshift") {
|
153
|
+
array.field?.unshift?.(defaultValue);
|
154
|
+
array.props?.onAdd?.(0);
|
155
|
+
} else {
|
156
|
+
array.field?.push?.(defaultValue);
|
157
|
+
array.props?.onAdd?.(array?.field?.value?.length - 1);
|
158
|
+
}
|
159
|
+
}}
|
160
|
+
icon={isUndef(props.icon) ? <PlusOutlined /> : props.icon}
|
161
|
+
>
|
162
|
+
{props.title || self.title}
|
163
|
+
</Button>
|
164
|
+
);
|
165
|
+
};
|
166
|
+
|
167
|
+
ArrayBase.Copy = React.forwardRef((props, ref) => {
|
168
|
+
const self = useField();
|
169
|
+
const array = useArray();
|
170
|
+
const index = useIndex(props.index);
|
171
|
+
const prefixCls = usePrefixCls("formily-array-base");
|
172
|
+
if (!array) return null;
|
173
|
+
if (array.field?.pattern !== "editable") return null;
|
174
|
+
return (
|
175
|
+
<Button
|
176
|
+
type="text"
|
177
|
+
{...props}
|
178
|
+
disabled={self?.disabled}
|
179
|
+
className={cls(`${prefixCls}-copy`, self?.disabled ? `${prefixCls}-copy-disabled` : "", props.className)}
|
180
|
+
ref={ref}
|
181
|
+
onClick={(e) => {
|
182
|
+
if (self?.disabled) return;
|
183
|
+
e.stopPropagation();
|
184
|
+
if (array.props?.disabled) return;
|
185
|
+
if (props.onClick) {
|
186
|
+
props.onClick(e);
|
187
|
+
if (e.defaultPrevented) return;
|
188
|
+
}
|
189
|
+
const value = clone(array?.field?.value[index]);
|
190
|
+
const distIndex = index + 1;
|
191
|
+
array.field?.insert?.(distIndex, value);
|
192
|
+
array.props?.onCopy?.(distIndex);
|
193
|
+
}}
|
194
|
+
icon={isUndef(props.icon) ? <CopyOutlined /> : props.icon}
|
195
|
+
>
|
196
|
+
{props.title || self.title}
|
197
|
+
</Button>
|
198
|
+
);
|
199
|
+
});
|
200
|
+
|
201
|
+
ArrayBase.Remove = React.forwardRef((props, ref) => {
|
202
|
+
const index = useIndex(props.index);
|
203
|
+
const self = useField();
|
204
|
+
const array = useArray();
|
205
|
+
const prefixCls = usePrefixCls("formily-array-base");
|
206
|
+
if (!array) return null;
|
207
|
+
if (array.field?.pattern !== "editable") return null;
|
208
|
+
return (
|
209
|
+
<Button
|
210
|
+
type="text"
|
211
|
+
{...props}
|
212
|
+
disabled={self?.disabled}
|
213
|
+
className={cls(`${prefixCls}-remove`, self?.disabled ? `${prefixCls}-remove-disabled` : "", props.className)}
|
214
|
+
ref={ref}
|
215
|
+
onClick={(e) => {
|
216
|
+
if (self?.disabled) return;
|
217
|
+
e.stopPropagation();
|
218
|
+
if (props.onClick) {
|
219
|
+
props.onClick(e);
|
220
|
+
if (e.defaultPrevented) return;
|
221
|
+
}
|
222
|
+
array.field?.remove?.(index);
|
223
|
+
array.props?.onRemove?.(index);
|
224
|
+
}}
|
225
|
+
icon={isUndef(props.icon) ? <DeleteOutlined /> : props.icon}
|
226
|
+
>
|
227
|
+
{props.title || self.title}
|
228
|
+
</Button>
|
229
|
+
);
|
230
|
+
});
|
231
|
+
|
232
|
+
ArrayBase.MoveDown = React.forwardRef((props, ref) => {
|
233
|
+
const index = useIndex(props.index);
|
234
|
+
const self = useField();
|
235
|
+
const array = useArray();
|
236
|
+
const prefixCls = usePrefixCls("formily-array-base");
|
237
|
+
if (!array) return null;
|
238
|
+
if (array.field?.pattern !== "editable") return null;
|
239
|
+
return (
|
240
|
+
<Button
|
241
|
+
type="text"
|
242
|
+
{...props}
|
243
|
+
disabled={self?.disabled}
|
244
|
+
className={cls(
|
245
|
+
`${prefixCls}-move-down`,
|
246
|
+
self?.disabled ? `${prefixCls}-move-down-disabled` : "",
|
247
|
+
props.className,
|
248
|
+
)}
|
249
|
+
ref={ref}
|
250
|
+
onClick={(e) => {
|
251
|
+
if (self?.disabled) return;
|
252
|
+
e.stopPropagation();
|
253
|
+
if (props.onClick) {
|
254
|
+
props.onClick(e);
|
255
|
+
if (e.defaultPrevented) return;
|
256
|
+
}
|
257
|
+
array.field?.moveDown?.(index);
|
258
|
+
array.props?.onMoveDown?.(index);
|
259
|
+
}}
|
260
|
+
icon={isUndef(props.icon) ? <DownOutlined /> : props.icon}
|
261
|
+
>
|
262
|
+
{props.title || self.title}
|
263
|
+
</Button>
|
264
|
+
);
|
265
|
+
});
|
266
|
+
|
267
|
+
ArrayBase.MoveUp = React.forwardRef((props, ref) => {
|
268
|
+
const index = useIndex(props.index);
|
269
|
+
const self = useField();
|
270
|
+
const array = useArray();
|
271
|
+
const prefixCls = usePrefixCls("formily-array-base");
|
272
|
+
if (!array) return null;
|
273
|
+
if (array.field?.pattern !== "editable") return null;
|
274
|
+
return (
|
275
|
+
<Button
|
276
|
+
type="text"
|
277
|
+
{...props}
|
278
|
+
disabled={self?.disabled}
|
279
|
+
className={cls(`${prefixCls}-move-up`, self?.disabled ? `${prefixCls}-move-up-disabled` : "", props.className)}
|
280
|
+
ref={ref}
|
281
|
+
onClick={(e) => {
|
282
|
+
if (self?.disabled) return;
|
283
|
+
e.stopPropagation();
|
284
|
+
if (props.onClick) {
|
285
|
+
props.onClick(e);
|
286
|
+
if (e.defaultPrevented) return;
|
287
|
+
}
|
288
|
+
array?.field?.moveUp(index);
|
289
|
+
array?.props?.onMoveUp?.(index);
|
290
|
+
}}
|
291
|
+
icon={isUndef(props.icon) ? <UpOutlined /> : props.icon}
|
292
|
+
>
|
293
|
+
{props.title || self.title}
|
294
|
+
</Button>
|
295
|
+
);
|
296
|
+
});
|
297
|
+
|
298
|
+
ArrayBase.useArray = useArray;
|
299
|
+
ArrayBase.useIndex = useIndex;
|
300
|
+
ArrayBase.useRecord = useRecord;
|
301
|
+
ArrayBase.mixin = (target: any) => {
|
302
|
+
target.Index = ArrayBase.Index;
|
303
|
+
target.SortHandle = ArrayBase.SortHandle;
|
304
|
+
target.Addition = ArrayBase.Addition;
|
305
|
+
target.Copy = ArrayBase.Copy;
|
306
|
+
target.Remove = ArrayBase.Remove;
|
307
|
+
target.MoveDown = ArrayBase.MoveDown;
|
308
|
+
target.MoveUp = ArrayBase.MoveUp;
|
309
|
+
target.useArray = ArrayBase.useArray;
|
310
|
+
target.useIndex = ArrayBase.useIndex;
|
311
|
+
target.useRecord = ArrayBase.useRecord;
|
312
|
+
return target;
|
313
|
+
};
|
314
|
+
|
315
|
+
export default ArrayBase;
|
@@ -0,0 +1,87 @@
|
|
1
|
+
@root-entry-name: 'default';
|
2
|
+
@import (reference) '~antd/es/style/themes/index.less';
|
3
|
+
|
4
|
+
@array-base-prefix-cls: ~'@{ant-prefix}-formily-array-base';
|
5
|
+
|
6
|
+
.@{array-base-prefix-cls}-remove,
|
7
|
+
.@{array-base-prefix-cls}-copy {
|
8
|
+
transition: all 0.25s ease-in-out;
|
9
|
+
color: @text-color;
|
10
|
+
font-size: 14px;
|
11
|
+
margin-left: 6px;
|
12
|
+
padding: 0;
|
13
|
+
border: none;
|
14
|
+
width: auto;
|
15
|
+
height: auto;
|
16
|
+
|
17
|
+
&:hover {
|
18
|
+
color: @primary-5;
|
19
|
+
}
|
20
|
+
|
21
|
+
&-disabled {
|
22
|
+
color: @disabled-color;
|
23
|
+
cursor: not-allowed !important;
|
24
|
+
&:hover {
|
25
|
+
color: @disabled-color;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
.@{array-base-prefix-cls}-sort-handle {
|
31
|
+
cursor: move;
|
32
|
+
color: #888 !important;
|
33
|
+
// overrid iconfont.less .anticon[tabindex] cursor
|
34
|
+
&.anticon[tabindex] {
|
35
|
+
cursor: move;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
.@{array-base-prefix-cls}-addition {
|
40
|
+
transition: all 0.25s ease-in-out;
|
41
|
+
}
|
42
|
+
|
43
|
+
.@{array-base-prefix-cls}-move-down {
|
44
|
+
transition: all 0.25s ease-in-out;
|
45
|
+
color: @text-color;
|
46
|
+
font-size: 14px;
|
47
|
+
margin-left: 6px;
|
48
|
+
padding: 0;
|
49
|
+
border: none;
|
50
|
+
width: auto;
|
51
|
+
height: auto;
|
52
|
+
|
53
|
+
&:hover {
|
54
|
+
color: @primary-5;
|
55
|
+
}
|
56
|
+
|
57
|
+
&-disabled {
|
58
|
+
color: @disabled-color;
|
59
|
+
cursor: not-allowed !important;
|
60
|
+
&:hover {
|
61
|
+
color: @disabled-color;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
.@{array-base-prefix-cls}-move-up {
|
67
|
+
transition: all 0.25s ease-in-out;
|
68
|
+
color: @text-color;
|
69
|
+
font-size: 14px;
|
70
|
+
margin-left: 6px;
|
71
|
+
padding: 0;
|
72
|
+
border: none;
|
73
|
+
width: auto;
|
74
|
+
height: auto;
|
75
|
+
|
76
|
+
&:hover {
|
77
|
+
color: @primary-5;
|
78
|
+
}
|
79
|
+
|
80
|
+
&-disabled {
|
81
|
+
color: @disabled-color;
|
82
|
+
cursor: not-allowed !important;
|
83
|
+
&:hover {
|
84
|
+
color: @disabled-color;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|