Skip to content

Commit 8a1e249

Browse files
committed
Merge branch 'master' of https://github.com/alibaba/x-render
2 parents c9dda9c + 8add06f commit 8a1e249

22 files changed

Lines changed: 482 additions & 97 deletions

File tree

docs/form-render/advanced/display.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ export default Demo;
373373

374374
### 主题设置
375375

376-
对于嵌套类型的表单,我们内置了三种主题,分别为 `collapse | card | tile `, 默认为 `collapse` 主题
376+
对于嵌套类型的表单,我们内置了四种主题,分别为 `collapse | card | tile | flex`, 默认为 `collapse` 主题
377377

378378
1. 默认样式:`theme: 'collapse'` ,支持`无边框模式: 'collapse:pure'``幽灵模式:'collapse:ghost'`
379379

@@ -612,3 +612,64 @@ const Demo = () => {
612612

613613
export default Demo;
614614
```
615+
616+
4. 弹性布局模式:`theme: 'flex'`,支持通过 style 属性配置相关样式
617+
618+
```jsx
619+
import React from 'react';
620+
import Form from '../demo/display';
621+
const schema = {
622+
type: 'object',
623+
displayType: 'row',
624+
properties: {
625+
objectName2: {
626+
title: '弹性布局',
627+
description: '这是一个对象类型',
628+
type: 'object',
629+
theme: 'flex',
630+
props: {
631+
style: {
632+
flexDirection: 'column',
633+
flexWrap: 'wrap',
634+
margin: '0 0 0 0',
635+
padding: '0 0 0 0',
636+
justifyContent: 'flex-start',
637+
alignItems: 'flex-start',
638+
alignContent: 'flex-start',
639+
},
640+
},
641+
properties: {
642+
input1: {
643+
title: '简单输入框',
644+
type: 'string',
645+
required: true,
646+
width: '30%',
647+
},
648+
select1: {
649+
title: '单选',
650+
type: 'string',
651+
enum: ['a', 'b', 'c'],
652+
enumNames: ['', '', ''],
653+
width: '30%',
654+
},
655+
date: {
656+
title: '时间选择',
657+
type: 'string',
658+
format: 'date',
659+
width: '30%',
660+
},
661+
},
662+
},
663+
},
664+
};
665+
666+
const Demo = () => {
667+
return (
668+
<div>
669+
<Form schema={schema} />
670+
</div>
671+
);
672+
};
673+
674+
export default Demo;
675+
```

docs/form-render/api/schema.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ label 的宽度,数字值单位为 px,也可使用 `'20%'/'2rem'` 等,写
111111
### theme
112112

113113
- 类型:`string`
114-
- 值: `default | card | tile`,详见[这里](/form-render/advanced/display#主题设置)
114+
- 值: `default | card | tile | flex`,详见[这里](/form-render/advanced/display#主题设置)
115115

116116
设置嵌套表单的主题样式
117117

docs/playground/json/simplest.json

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@
1313
}
1414
]
1515
},
16-
"select": {
17-
"title": "单选",
18-
"type": "string",
19-
"enum": ["a", "b", "c"],
20-
"enumNames": ["选项1", "选项2", "选项3"],
21-
"widget": "radio"
16+
"$void_1": {
17+
"type": "object",
18+
"title": "void test",
19+
"properties": {
20+
"input2": {
21+
"title": "简单输入框",
22+
"type": "string",
23+
"min": 6,
24+
"rules": [
25+
{
26+
"pattern": "^[A-Za-z0-9]+$",
27+
"message": "只允许填写英文字母和数字"
28+
}
29+
]
30+
}
31+
}
2232
},
2333
"listName2": {
2434
"title": "对象数组",

packages/form-render/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## 1.14.0
4+
5+
- [+]`object` 类型添加 `flex` 主题
6+
- [+] 优化 `widgets` 下的组件路径
7+
- [+] 增加 `void` 支持
8+
- [!] 修复 `object` 宽度设置
9+
310
## 1.13.21
411

512
- [!] 修复 `tableList``drawerList` 表头无法正常显示的问题
@@ -8,6 +15,10 @@
815

916
- [+] 删除 `formData` 中的 `index`
1017

18+
## 1.13.18
19+
20+
- [!] 修复 `cardList` 组件无法新增的 bug
21+
1122
## 1.13.17
1223

1324
- [+] `simpleList``cardList` 支持自定义新增按钮

packages/form-render/src/form-render-core/src/core/RenderField/ExtendedWidget.js

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Suspense } from 'react';
1+
import React, { memo, Suspense } from 'react';
22
import { transformProps } from '../../createWidget';
33
import { useStore, useTools } from '../../hooks';
44
import { extraSchemaList, getWidgetName } from '../../mapping';
@@ -162,43 +162,41 @@ const ExtendedWidget = ({
162162
const finalProps = transformProps(widgetProps);
163163
return (
164164
<Suspense fallback={<div></div>}>
165-
<div className="fr-item-wrapper">
166-
<Widget {...finalProps} />
167-
</div>
165+
<Widget {...finalProps} />
168166
</Suspense>
169167
);
170168
};
171169

172-
// const areEqual = (prev, current) => {
173-
// if (prev.schema && current.schema) {
174-
// if (prev.schema.$id === '#') {
175-
// return false;
176-
// }
177-
// if (prev.schema.hidden && current.schema.hidden) {
178-
// return true;
179-
// }
180-
// }
181-
// if (prev.readOnly !== current.readOnly) {
182-
// return false;
183-
// }
184-
// if (prev.disabled !== current.disabled) {
185-
// return false;
186-
// }
187-
// if (
188-
// JSON.stringify(prev.dependValues) !== JSON.stringify(current.dependValues)
189-
// ) {
190-
// return false;
191-
// }
192-
// if (isObjType(prev.schema) && isObjType(current.schema)) {
193-
// return false;
194-
// }
195-
// if (
196-
// JSON.stringify(prev.value) === JSON.stringify(current.value) &&
197-
// JSON.stringify(prev.schema) === JSON.stringify(current.schema)
198-
// ) {
199-
// return true;
200-
// }
201-
// return false;
202-
// };
203-
204-
export default ExtendedWidget;
170+
const areEqual = (prev, current) => {
171+
if (prev.schema && current.schema) {
172+
if (prev.schema.$id === '#') {
173+
return false;
174+
}
175+
if (prev.schema.hidden && current.schema.hidden) {
176+
return true;
177+
}
178+
}
179+
if (prev.readOnly !== current.readOnly) {
180+
return false;
181+
}
182+
if (prev.disabled !== current.disabled) {
183+
return false;
184+
}
185+
if (
186+
JSON.stringify(prev.dependValues) !== JSON.stringify(current.dependValues)
187+
) {
188+
return false;
189+
}
190+
if (isObjType(prev.schema) && isObjType(current.schema)) {
191+
return false;
192+
}
193+
if (
194+
JSON.stringify(prev.value) === JSON.stringify(current.value) &&
195+
JSON.stringify(prev.schema) === JSON.stringify(current.schema)
196+
) {
197+
return true;
198+
}
199+
return false;
200+
};
201+
202+
export default memo(ExtendedWidget, areEqual);

packages/form-render/src/form-render-core/src/core/RenderField/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ const RenderField = props => {
232232
);
233233
} else if (isBlockType(_schema)) {
234234
return (
235-
<div datapath={dataPath}>
235+
<div className={contentClass} style={contentStyle} datapath={dataPath}>
236236
<ExtendedWidget {...widgetProps} />
237237
</div>
238238
);

packages/form-render/src/form-render-core/src/core/index.js

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,26 @@ const CoreRender = ({
207207
if (schema.hidden) {
208208
columnStyle.display = 'none';
209209
}
210-
// if (!isComplex) {
211-
// }
212-
if (!isObj) {
213-
if (width) {
214-
columnStyle.width = width;
215-
columnStyle.paddingRight = 8;
216-
} else if (column > 1) {
217-
columnStyle.width = `calc(100% /${column})`;
218-
columnStyle.paddingRight = 8;
210+
211+
if (width) {
212+
columnStyle.width = width;
213+
} else if (column > 1) {
214+
columnStyle.width = `calc(100% /${column})`;
215+
}
216+
217+
// 如果传入自定义样式则覆盖使用,object 外层样式使用 schema.style,内层样式使用 schema.props.style
218+
if ('object' === typeof schema?.style) {
219+
columnStyle = {
220+
...columnStyle,
221+
...schema.style
219222
}
220223
}
221224

222225
const _labelWidth = isLooselyNumber(effectiveLabelWidth)
223226
? Number(effectiveLabelWidth)
224227
: isCssLength(effectiveLabelWidth)
225-
? effectiveLabelWidth
226-
: 110; // 默认是 110px 的长度
228+
? effectiveLabelWidth
229+
: 110; // 默认是 110px 的长度
227230

228231
let labelStyle = { width: _labelWidth };
229232
if (isComplex || _displayType === 'column') {
@@ -259,17 +262,15 @@ const CoreRender = ({
259262
};
260263

261264
const objChildren = (
262-
<div className={`flex flex-wrap fr-core-obj`}>
263-
<RenderObject
264-
dataIndex={dataIndex}
265-
errorFields={errorFields}
266-
displayType={_displayType}
267-
labelAlign={_labelAlign}
268-
hideTitle={hideTitle}
269-
>
270-
{item.children}
271-
</RenderObject>
272-
</div>
265+
<RenderObject
266+
dataIndex={dataIndex}
267+
errorFields={errorFields}
268+
displayType={_displayType}
269+
labelAlign={_labelAlign}
270+
hideTitle={hideTitle}
271+
>
272+
{item.children}
273+
</RenderObject>
273274
);
274275

275276
const listChildren = (

packages/form-render/src/form-render-core/src/processData.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@ import {
66
removeEmptyItemFromList,
77
removeHiddenFromResult,
88
} from './utils';
9+
import { removeVoidFromResult } from './void';
910
// 提交前需要先处理formData的逻辑
1011
export const processData = (data, flatten, removeHiddenData) => {
1112
let _data = clone(data);
1213
// 1. 去掉 hidden = true 的元素
1314
if (removeHiddenData) {
1415
_data = removeHiddenFromResult(data, flatten);
1516
}
17+
18+
// 1.5. 去掉 void 元素
19+
_data = removeVoidFromResult(_data);
20+
1621
// 2. bind 的处理
1722
_data = transformDataWithBind(_data, flatten);
1823

@@ -21,7 +26,6 @@ export const processData = (data, flatten, removeHiddenData) => {
2126

2227
// 4. 去掉所有的 undefined
2328
_data = cleanEmpty(_data);
24-
2529
return _data;
2630
};
2731

packages/form-render/src/form-render-core/src/utils.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { cloneDeep, get, isEmpty, set } from 'lodash-es';
2+
import { getRealDataPath } from './void';
23

34
export function getParamByName(name, url = window.location.href) {
45
name = name.replace(/[\[\]]/g, '\\$&');
@@ -51,7 +52,8 @@ export function getValueByPath(formData, path) {
5152
if (path === '#' || !path) {
5253
return formData || {};
5354
} else if (typeof path === 'string') {
54-
return get(formData, path);
55+
const realPath = getRealDataPath(path);
56+
return realPath && get(formData, realPath);
5557
} else {
5658
console.error('path has to be a string');
5759
}
@@ -97,7 +99,7 @@ export function getDataPath(id, dataIndex) {
9799
_id = _id.replace(/\[\]/, `[${item}]`);
98100
});
99101
}
100-
return removeBrackets(_id);
102+
return removeBrackets(getRealDataPath(_id));
101103
}
102104

103105
export function isObjType(schema) {

packages/form-render/src/form-render-core/src/validator.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from './utils';
1515
import { defaultValidateMessages } from './validateMessage';
1616
import { defaultValidateMessagesCN } from './validateMessageCN';
17+
import { getRealDataFlatten } from './void';
1718

1819
export const parseSchemaExpression = (schema, formData, path) => {
1920
if (!isObject(schema)) return schema;
@@ -72,6 +73,8 @@ export const validateField = ({
7273
}) => {
7374
const paths = getRelatedPaths(path, flatten);
7475
// console.log('all relevant paths:', paths);
76+
77+
flatten = getRealDataFlatten(flatten);
7578
const promiseArray = paths.map(path => {
7679
const { id, dataIndex } = destructDataPath(path);
7780
if (flatten[id] || flatten[`${id}[]`]) {

0 commit comments

Comments
 (0)