@hzab/form-render 1.4.1-beta → 1.5.0-beta

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 CHANGED
@@ -1,6 +1,7 @@
1
- # @hzab/form-render@1.4.1
1
+ # @hzab/form-render@1.5.0
2
2
 
3
- fix: ArrayTable & ArrayCards key nanoid 生成
3
+ feat: 上传组件多模式上传,出参格式配置
4
+ fix: 字符串事件处理(onChange)
4
5
 
5
6
  # @hzab/form-render@1.4.0
6
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/form-render",
3
- "version": "1.4.1-beta",
3
+ "version": "1.5.0-beta",
4
4
  "description": "",
5
5
  "main": "src",
6
6
  "scripts": {
@@ -1,4 +1,14 @@
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
+ /** formily 执行函数作用域相关参数 */
11
+ export const formilyDataKeys = ["$form", "$self", "$observable", "$effect", "$memo", "$props", "$values"];
2
12
 
3
13
  /** 自增容器 */
4
14
  export const arrayList = ["ArrayTable", "ArrayCards"];
@@ -29,8 +39,8 @@ export const bindOnChange = (schema, opt) => {
29
39
  const comProps = item?.["x-component-props"];
30
40
  if (!comProps) {
31
41
  item["x-component-props"] = {};
32
- } else if (isScopeKey(comProps)) {
33
- item["x-component-props"] = getValByScope(comProps, schemaScope) || {};
42
+ } else if (isScopeKey(comProps, schemaScope)) {
43
+ item["x-component-props"] = getScopeKeyVal(comProps, schemaScope) || {};
34
44
  }
35
45
 
36
46
  const bindParams = {
@@ -90,16 +100,24 @@ export const bindOnChange = (schema, opt) => {
90
100
  export const bindCallback = (opt) => {
91
101
  const { target, actionName, schemaScope, formOnChange } = opt || {};
92
102
  const tempFn = target[actionName];
93
- target[actionName] = function (...sourceArgs) {
103
+ if (!schemaScope._$tempData) {
104
+ schemaScope._$tempData = {};
105
+ }
106
+ // 设置一个唯一的函数名,用于从 schema scope 传入 formily 事件执行中
107
+ const fnKey = "fnKey_" + nanoid();
108
+ // 设置 schemaScope 中的唯一函数,获取执行函数作用域 $form, $self, $observable, $effect, $memo, $props, $values 相关参数
109
+ schemaScope._$tempData[fnKey] = function (params, sourceArgs) {
110
+ const { $form, $self, $observable, $effect, $memo, $props, $values } = params;
94
111
  // 处理结果数据,各组件返回数据格式不一致
95
112
  const res = handleChangeValue({
96
113
  ...opt,
97
114
  sourceArgs,
98
115
  });
99
116
  // 触发组件 onChange 事件
100
- if (isScopeKey(tempFn)) {
117
+ if (isRunStr(tempFn)) {
101
118
  // schemaScope 传入方式
102
- const fn = schemaScope && schemaScope[getScopeKey(tempFn)];
119
+ const fn = handleSchemaStrVal(tempFn, { ...params, ...schemaScope });
120
+
103
121
  typeof fn === "function" && fn(...sourceArgs, res);
104
122
  } else if (typeof tempFn === "function") {
105
123
  // 直接传入函数的方式
@@ -107,6 +125,17 @@ export const bindCallback = (opt) => {
107
125
  }
108
126
  formOnChange && formOnChange(res);
109
127
  };
128
+
129
+ // 通过 formily 字符串执行的方式回去函数作用域参数
130
+ target[actionName] = `{{
131
+ function t() {
132
+ // 执行 ${fnKey} 唯一函数,formily 当前函数作用域相关参数
133
+ return _$tempData && _$tempData.${fnKey} && _$tempData.${fnKey}(
134
+ { ${formilyDataKeys.join(", ")} },
135
+ arguments
136
+ );
137
+ }
138
+ }}`;
110
139
  };
111
140
 
112
141
  /**
@@ -114,8 +143,7 @@ export const bindCallback = (opt) => {
114
143
  * @param args
115
144
  */
116
145
  export const handleChangeValue = (opt) => {
117
- const { componentName, formRender, parent, targetKey, actionName, sourceArgs } = opt || {};
118
- console.log("parent", parent);
146
+ const { formRender, targetKey, actionName, sourceArgs } = opt || {};
119
147
  // 自增表格、卡片无法获知当前编辑内容所在的索引,导致无法知道当前值
120
148
  const res = {
121
149
  key: targetKey,
@@ -123,26 +151,16 @@ export const handleChangeValue = (opt) => {
123
151
  formRender,
124
152
  formValues: formRender.values,
125
153
  sourceArgs: sourceArgs,
126
- // value: formRender.getValuesIn(targetKey),
127
- // parent,
128
- // TODO: 自增情况下无法获知索引
129
- // parentValue: formRender.getValuesIn(parent?.name),
130
154
  };
131
155
 
132
- // TODO: 自增返回父级值?
133
- // if (returnParentValue.includes(parent?.["x-component"])) {
134
- // res.value = res.parentValue;
135
- // }
136
-
137
156
  return res;
138
157
  };
139
158
 
140
159
  /**
141
- * 是否是 scope key
142
- * @param strKey
143
- * @returns
160
+ * 是否是可执行字符串,为 {{}} 包裹的字符串
161
+ * @param params
144
162
  */
145
- export const isScopeKey = (strKey) => {
163
+ export const isRunStr = (strKey) => {
146
164
  if (typeof strKey !== "string") {
147
165
  return false;
148
166
  }
@@ -151,12 +169,12 @@ export const isScopeKey = (strKey) => {
151
169
  };
152
170
 
153
171
  /**
154
- * 获取 scope key
155
- * @param strKey
156
- * @returns
172
+ * 获取可执行字符串,返回 {{}} 包裹的字符串
173
+ * @param params
157
174
  */
158
- export const getScopeKey = (strKey) => {
159
- if (!isScopeKey(strKey)) {
175
+ export const getRunStr = (strKey) => {
176
+ const _isRunStr = isRunStr(strKey);
177
+ if (!_isRunStr) {
160
178
  return "";
161
179
  }
162
180
  const key = strKey.trim();
@@ -164,13 +182,50 @@ export const getScopeKey = (strKey) => {
164
182
  };
165
183
 
166
184
  /**
167
- * 通过字符串获取 schemaScope 中的数据
185
+ * 处理 schema 字符串值
186
+ * 1.可执行字符串({{}}包裹的字符串):schema scope 取出对应的值,否则转为可执行函数
187
+ * 2.其他情况直接返回对应数据
168
188
  * @param strKey
169
189
  * @param schemaScope
170
190
  * @returns
171
191
  */
172
- export const getValByScope = (strKey, schemaScope = {}) => {
173
- if (isScopeKey(strKey)) {
174
- return schemaScope && schemaScope[getScopeKey(strKey)];
192
+ export const handleSchemaStrVal = (strKey, schemaScope) => {
193
+ const _str = getRunStr(strKey);
194
+ if (!_str) {
195
+ return strKey;
196
+ }
197
+ let fn = getScopeKeyVal(_str, schemaScope);
198
+ if (fn) {
199
+ return fn;
200
+ }
201
+ return new Function("$root", `with($root) { return (${_str}) }`)(schemaScope);
202
+ };
203
+
204
+ /**
205
+ * 是否是 schema scope key
206
+ * @param strKey
207
+ * @returns
208
+ */
209
+ export const isScopeKey = (strKey, schemaScope) => {
210
+ const key = getRunStr(strKey);
211
+ if (!schemaScope || typeof schemaScope !== "object") {
212
+ throw new Error("请传入正确的 schema scope");
213
+ }
214
+ // 判断是否是 scope 变量名
215
+ if (!schemaScope?.[key]) {
216
+ return false;
217
+ }
218
+ return key;
219
+ };
220
+
221
+ /**
222
+ * 获取 schema scope key
223
+ * @param strKey
224
+ * @returns
225
+ */
226
+ export const getScopeKeyVal = (strKey, schemaScope) => {
227
+ if (!isScopeKey(strKey, schemaScope)) {
228
+ return "";
175
229
  }
230
+ return schemaScope[getRunStr(strKey)];
176
231
  };
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ import 'antd/lib/button/style/index'
2
+ import './style.less'
@@ -1,4 +1,4 @@
1
- import React, { useMemo } from "react";
1
+ import React from "react";
2
2
  import { Card, Empty } from "antd";
3
3
  import { CardProps } from "antd/lib/card";
4
4
  import { ArrayField } from "@formily/core";
@@ -6,8 +6,8 @@ import { useField, observer, useFieldSchema, RecursionField } from "@formily/rea
6
6
  import cls from "classnames";
7
7
  import { ISchema } from "@formily/json-schema";
8
8
  import { usePrefixCls } from "c-formily-antd/lib/__builtins__";
9
- import { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from "c-formily-antd/lib/array-base";
10
- import { nanoid } from "nanoid";
9
+ import { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from "../ArrayBase";
10
+
11
11
  type ComposedArrayCards = React.FC<React.PropsWithChildren<CardProps & IArrayBaseProps>> & ArrayBaseMixins;
12
12
 
13
13
  const isAdditionComponent = (schema: ISchema) => {
@@ -47,19 +47,12 @@ const isOperationComponent = (schema: ISchema) => {
47
47
  export const ArrayCards: ComposedArrayCards = observer((props) => {
48
48
  const field = useField<ArrayField>();
49
49
  const schema = useFieldSchema();
50
+ const dataSource = Array.isArray(field.value) ? field.value : [];
50
51
  const prefixCls = usePrefixCls("formily-array-cards", props);
51
- const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props;
52
- const dataSource = useMemo(() => {
53
- return Array.isArray(field.value)
54
- ? field.value?.map((item) => {
55
- return {
56
- ...item,
57
- _key: item?.id || nanoid(),
58
- };
59
- })
60
- : [];
61
- }, [field.value?.length]);
52
+ const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp, ...cardProps } = props;
53
+
62
54
  if (!schema) throw new Error("can not found schema object");
55
+
63
56
  const renderItems = () => {
64
57
  return dataSource?.map((item, index) => {
65
58
  const items = Array.isArray(schema.items) ? schema.items[index] || schema.items[0] : schema.items;
@@ -91,7 +84,6 @@ export const ArrayCards: ComposedArrayCards = observer((props) => {
91
84
  {props.extra}
92
85
  </span>
93
86
  );
94
-
95
87
  const content = (
96
88
  <RecursionField
97
89
  schema={items}
@@ -104,9 +96,10 @@ export const ArrayCards: ComposedArrayCards = observer((props) => {
104
96
  />
105
97
  );
106
98
  return (
107
- <ArrayBase.Item key={item?._key} index={index} record={() => field.value?.[index]}>
99
+ // ! key 用于排序,必须是序号
100
+ <ArrayBase.Item key={index} index={index} record={() => field.value?.[index]}>
108
101
  <Card
109
- {...props}
102
+ {...cardProps}
110
103
  onChange={() => {}}
111
104
  className={cls(`${prefixCls}-item`, props.className)}
112
105
  title={title}
@@ -132,7 +125,7 @@ export const ArrayCards: ComposedArrayCards = observer((props) => {
132
125
  if (dataSource?.length) return;
133
126
  return (
134
127
  <Card
135
- {...props}
128
+ {...cardProps}
136
129
  onChange={() => {}}
137
130
  className={cls(`${prefixCls}-item`, props.className)}
138
131
  title={props.title || field.title}