This commit is contained in:
chenos 2021-07-06 00:15:19 +08:00
parent eb31861b54
commit b7a2d5d3e5
11 changed files with 444 additions and 585 deletions

View File

@ -11,11 +11,18 @@ group:
# AddNew - 新增
可用于新增区块 AddNew 或表单项 AddNew.FormItem支持常规布局也支持 Grid 布局。
包括两部分
- AddNew.BlockItem 新增区块项
- AddNew.FormItem 新增表单项
支持常规布局也支持 Grid 布局
## 代码演示
### 基本使用
### AddNew.BlockItem
如果需要支持拖拽,需要将 AddNew.BlockItem 组件放于 DragAndDrop 组件中。
```tsx
import React from 'react';
@ -32,7 +39,7 @@ const schema: ISchema = {
properties: {
[uid()]: {
type: 'void',
'x-component': 'AddNew',
'x-component': 'AddNew.BlockItem',
}
}
},
@ -44,7 +51,39 @@ export default () => {
}
```
### Grid 布局的 AddNew
### AddNew.FormItem
如果需要支持拖拽,需要将 AddNew.FormItem 组件放于 DragAndDrop 组件中。
```tsx
import React from 'react';
import { ISchema } from '@formily/react';
import { uid } from '@formily/shared';
import { SchemaRenderer } from '../';
const schema: ISchema = {
type: 'object',
properties: {
[uid()]: {
type: 'void',
'x-component': 'DragAndDrop',
properties: {
[uid()]: {
type: 'void',
'x-component': 'AddNew.FormItem',
}
}
},
},
};
export default () => {
return <SchemaRenderer schema={schema} />
}
```
### Grid 布局中的 AddNew.BlockItem
```tsx
import React from 'react';
@ -64,13 +103,10 @@ const schema: ISchema = {
[`col_${uid()}`]: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
width: 30,
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'AddNew',
'x-component': 'AddNew.BlockItem',
},
},
},
@ -104,9 +140,6 @@ const schema: ISchema = {
[`col_${uid()}`]: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
width: 30,
},
properties: {
[uid()]: {
type: 'void',

View File

@ -82,7 +82,9 @@ const isGridBlock = (schema: Schema) => {
return true;
};
export const AddNew: any = observer((props: any) => {
export const AddNew = () => null;
AddNew.BlockItem = observer((props: any) => {
const { ghost, defaultAction } = props;
const { schema, insertBefore, insertAfter } = useDesignable();
const path = useSchemaPath();

View File

@ -139,7 +139,7 @@ BlockItem.DesignableBar = () => {
className={classNames('designable-bar-actions', { active: visible })}
>
<Space size={'small'}>
<AddNew defaultAction={'insertAfter'} ghost />
<AddNew.BlockItem defaultAction={'insertAfter'} ghost />
{dragRef && <DragOutlined ref={dragRef} />}
<Dropdown
trigger={['click']}

View File

@ -11,6 +11,52 @@ group:
# DatabaseField - 数据表字段
```tsx
import React from 'react';
import { createForm } from '@formily/core';
import { SchemaRenderer } from '../';
import { observer, connect, useField } from '@formily/react';
const schema = {
type: 'object',
properties: {
array: {
type: 'array',
'x-component': 'DatabaseField',
default: [
{
id: 1,
interface: 'string',
type: 'string',
name: 'title',
},
{
id: 2,
type: 'text',
interface: 'textarea',
name: 'content',
},
],
},
// input: {
// type: 'string',
// 'x-component': 'Input',
// },
},
};
const form = createForm();
export default observer(() => {
return (
<div>
{JSON.stringify(form.values, null, 2)}
<SchemaRenderer form={form} schema={schema} />
</div>
)
})
```
```tsx
import React from 'react';
import { SchemaRenderer } from '../';
@ -21,7 +67,7 @@ const schema = {
array: {
type: 'array',
// title: '数据表字段',
'x-component': 'DatabaseField.ArrayCollapse',
'x-component': 'ArrayCollapse',
'x-component-props': {
accordion: true,
},
@ -29,14 +75,14 @@ const schema = {
'x-decorator': 'FormItem',
items: {
type: 'object',
'x-component': 'DatabaseField.ArrayCollapse.CollapsePanel',
'x-component': 'ArrayCollapse.CollapsePanel',
'x-component-props': {
header: '字段',
},
properties: {
index: {
type: 'void',
'x-component': 'DatabaseField.ArrayCollapse.Index',
'x-component': 'ArrayCollapse.Index',
},
input: {
type: 'string',
@ -47,15 +93,15 @@ const schema = {
},
remove: {
type: 'void',
'x-component': 'DatabaseField.ArrayCollapse.Remove',
'x-component': 'ArrayCollapse.Remove',
},
moveUp: {
type: 'void',
'x-component': 'DatabaseField.ArrayCollapse.MoveUp',
'x-component': 'ArrayCollapse.MoveUp',
},
moveDown: {
type: 'void',
'x-component': 'DatabaseField.ArrayCollapse.MoveDown',
'x-component': 'ArrayCollapse.MoveDown',
},
},
},
@ -63,7 +109,7 @@ const schema = {
addition: {
type: 'void',
title: '添加字段',
'x-component': 'DatabaseField.ArrayCollapse.Addition',
'x-component': 'ArrayCollapse.Addition',
},
},
},

View File

@ -1,9 +1,180 @@
import { observer, connect } from '@formily/react';
import React from 'react';
import React, { useState } from 'react';
import {
observer,
connect,
useField,
RecursionField,
ISchema,
Schema,
useFieldSchema,
} from '@formily/react';
import { ArrayCollapse } from '@formily/antd';
import { uid } from '@formily/shared';
import '@formily/antd/lib/form-tab/style';
import { Collapse, Button } from 'antd';
export const DatabaseField: any = () => null;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
DatabaseField.ArrayCollapse = ArrayCollapse;
const interfaces = new Map<string, ISchema>();
interfaces.set('string', {
type: 'object',
default: {
type: 'string',
// name,
ui: {
type: 'string',
// title,
'x-component': 'Input',
} as ISchema,
},
properties: {
type: {
type: 'string',
title: '数据类型',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Select',
enum: [
{ label: 'String', value: 'string' },
{ label: 'Text', value: 'text' },
],
},
name: {
type: 'string',
title: '字段标识',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
},
'ui.title': {
type: 'string',
title: '字段名称',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
},
'ui.required': {
type: 'string',
title: '必填',
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
},
},
});
interfaces.set('textarea', {
type: 'object',
default: {
type: 'text',
// name,
ui: {
type: 'string',
// title,
'x-component': 'Input.TextArea',
} as ISchema,
},
properties: {
type: {
type: 'string',
title: '数据类型',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Select',
enum: [
{ label: 'String', value: 'string' },
{ label: 'Text', value: 'text' },
],
},
name: {
type: 'string',
required: true,
title: '字段标识',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
},
'ui.title': {
type: 'string',
required: true,
title: '字段名称',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
'ui.required': {
type: 'string',
title: '必填',
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
},
},
});
export const DatabaseField: any = observer((props) => {
const field = useField<Formily.Core.Models.ArrayField>();
console.log('DatabaseField', field.componentProps);
return (
<div>
<Collapse
// activeKey={field.componentProps.activeKey}
{...props}
onChange={(key) => {
field.setComponentProps({
activeKey: key,
});
}}
accordion
>
{field.value?.map((item, index) => {
const schema = interfaces.get(item.interface);
console.log({ schema });
return (
<Collapse.Panel
extra={[
<Button onClick={() => field.moveUp(index)}>Up</Button>,
<Button
onClick={() => {
field.remove(index);
field.insert(index, {
...item,
interface: 'textarea',
});
}}
>
Update
</Button>,
]}
header={item.name}
key={item.id}
>
<RecursionField
key={`${item.id}_${index}`}
name={index}
schema={new Schema(schema)}
/>
</Collapse.Panel>
);
})}
</Collapse>
<Button
block
type={'dashed'}
style={{ marginTop: 10 }}
onClick={() => {
field.push({
id: uid(),
type: 'string',
interface: 'string',
name: uid(),
});
console.log('field.value', field.value);
}}
>
</Button>
</div>
);
});

View File

@ -20,30 +20,26 @@ import React from 'react';
import { SchemaRenderer } from '../';
const schema = {
name: 'form',
type: 'object',
'x-component': 'Form',
properties: {
form: {
type: 'object',
'x-component': 'Form',
properties: {
username: {
type: 'string',
title: '用户名',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
},
password: {
type: 'string',
title: '密码',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Password',
},
}
}
},
}
username: {
type: 'string',
title: '用户名',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
},
password: {
type: 'string',
title: '密码',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Password',
},
}
};
export default () => {
return (

View File

@ -1,436 +1,147 @@
import { ISchema } from '@formily/json-schema';
import { uid } from '@formily/shared';
export default {
type: 'object',
properties: {
grid: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
properties: {
row1: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Row',
properties: {
col1: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
},
properties: {
block11: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block11',
},
'x-decorator': 'BlockItem',
'x-component': 'Form',
properties: {
form1: {
[uid()]: {
type: 'void',
name: 'item3',
'x-decorator': 'Card',
'x-component': 'Form',
'x-component': 'Grid',
properties: {
grid: {
[uid()]: {
type: 'void',
title: 'aa',
'x-component': 'Grid',
'x-component': 'Grid.Row',
properties: {
row1: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Row',
'x-component': 'Grid.Col',
properties: {
col1: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
},
properties: {
block11: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block11',
},
properties: {
field1: {
type: 'string',
required: true,
title: '字段1',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
col2: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
isLast: true,
},
properties: {
block21: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block21',
},
properties: {
field2: {
type: 'string',
required: true,
title: '字段2',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
[uid()]: {
type: 'string',
required: true,
title: '字段1',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
row2: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Row',
'x-component': 'Grid.Col',
properties: {
col21: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 3,
},
properties: {
block211: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block211',
},
properties: {
field3: {
type: 'string',
required: true,
title: '字段3',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
col22: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 2 / 3,
isLast: true,
},
properties: {
block221: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block221',
},
properties: {
field4: {
type: 'string',
required: true,
title: '字段4',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
},
},
row3: {
type: 'void',
'x-component': 'Grid.Row',
"x-component-props": {
isLast: true,
},
properties: {
col31: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1,
isLast: true,
},
properties: {
block311: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block311',
},
properties: {
field5: {
type: 'string',
required: true,
title: '字段5',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
[uid()]: {
type: 'string',
required: true,
title: '字段2',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
actions: {
[uid()]: {
type: 'void',
// 'x-decorator': 'Div',
'x-component': 'Space',
'x-component': 'Grid.Row',
properties: {
submit: {
[uid()]: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
// block: true,
type: 'primary',
useAction: '{{ useLogin }}',
style: {
// width: '100%',
'x-component': 'Grid.Col',
properties: {
[uid()]: {
type: 'string',
required: true,
title: '字段3',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
title: '提交',
},
reset: {
[uid()]: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
// block: true,
useAction: '{{ useLogin }}',
style: {
// width: '100%',
'x-component': 'Grid.Col',
properties: {
[uid()]: {
type: 'string',
required: true,
title: '字段4',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
[uid()]: {
type: 'void',
'x-component': 'Grid.Row',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
[uid()]: {
type: 'string',
required: true,
title: '字段5',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
title: '重置',
},
},
},
},
},
},
},
},
},
col2: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
isLast: true,
},
properties: {
block21: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block21',
},
properties: {
form2: {
actions: {
type: 'void',
name: 'item3',
'x-decorator': 'Card',
'x-component': 'Form',
// 'x-decorator': 'Div',
'x-component': 'Space',
properties: {
grid: {
submit: {
type: 'void',
title: 'aa',
'x-component': 'Grid',
properties: {
row1: {
type: 'void',
'x-component': 'Grid.Row',
properties: {
col1: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
},
properties: {
block11: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block11',
},
properties: {
field1: {
type: 'string',
required: true,
title: '字段1',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
col2: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
isLast: true,
},
properties: {
block21: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block21',
},
properties: {
field2: {
type: 'string',
required: true,
title: '字段2',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
},
},
row2: {
type: 'void',
'x-component': 'Grid.Row',
properties: {
col21: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 3,
},
properties: {
block211: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block211',
},
properties: {
field3: {
type: 'string',
required: true,
title: '字段3',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
col22: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 2 / 3,
isLast: true,
},
properties: {
block221: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block221',
},
properties: {
field4: {
type: 'string',
required: true,
title: '字段4',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
},
},
row3: {
type: 'void',
'x-component': 'Grid.Row',
"x-component-props": {
isLast: true,
},
properties: {
col31: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1,
isLast: true,
},
properties: {
block311: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block311',
},
properties: {
field5: {
type: 'string',
required: true,
title: '字段5',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
},
},
},
},
'x-component': 'Action',
'x-component-props': {
// block: true,
type: 'primary',
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '提交',
},
actions: {
reset: {
type: 'void',
// 'x-decorator': 'Div',
'x-component': 'Space',
properties: {
submit: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
// block: true,
type: 'primary',
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '提交',
},
reset: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
// block: true,
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '重置',
'x-component': 'Action',
'x-component-props': {
// block: true,
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '重置',
},
},
},
@ -443,4 +154,4 @@ export default {
},
},
},
}
} as ISchema;

View File

@ -4,31 +4,22 @@ import { uid } from '@formily/shared';
export default {
type: 'object',
properties: {
[`g_${uid()}`]: {
[uid()]: {
type: 'void',
'x-decorator': 'Card',
'x-component': 'Grid',
properties: {
[`gr_${uid()}`]: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Row',
properties: {
[`gc_${uid()}`]: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1,
},
properties: {
[`gb_${uid()}`]: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Block',
properties: {
[`gbn_${uid()}`]: {
type: 'void',
'x-component': 'AddNew',
},
},
'x-component': 'AddNew.BlockItem',
},
},
},

View File

@ -1,35 +1,27 @@
import { uid } from '@formily/shared';
const schema = {
type: 'void',
name: `form_${uid()}`,
'x-decorator': 'Card',
'x-component': 'Form',
type: 'object',
properties: {
grid: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component': 'Form',
properties: {
row1: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Row',
'x-decorator': 'Card',
'x-component': 'Grid',
properties: {
col1: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
},
'x-component': 'Grid.Row',
properties: {
block11: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block11',
},
'x-designable-bar': 'FormItem.DesignableBar',
'x-component': 'Grid.Col',
properties: {
field1: {
[uid()]: {
type: 'string',
required: true,
title: '字段1',
@ -38,25 +30,11 @@ const schema = {
},
},
},
},
},
col2: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 2,
isLast: true,
},
properties: {
block21: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block21',
},
'x-designable-bar': 'FormItem.DesignableBar',
'x-component': 'Grid.Col',
properties: {
field2: {
[uid()]: {
type: 'string',
required: true,
title: '字段2',
@ -67,28 +45,16 @@ const schema = {
},
},
},
},
},
row2: {
type: 'void',
'x-component': 'Grid.Row',
properties: {
col21: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1 / 3,
},
'x-component': 'Grid.Row',
properties: {
block211: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block211',
},
'x-designable-bar': 'FormItem.DesignableBar',
'x-component': 'Grid.Col',
properties: {
field3: {
[uid()]: {
type: 'string',
required: true,
title: '字段3',
@ -97,25 +63,11 @@ const schema = {
},
},
},
},
},
col22: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 2 / 3,
isLast: true,
},
properties: {
block221: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block221',
},
'x-designable-bar': 'FormItem.DesignableBar',
'x-component': 'Grid.Col',
properties: {
field4: {
[uid()]: {
type: 'string',
required: true,
title: '字段4',
@ -126,31 +78,15 @@ const schema = {
},
},
},
},
},
row3: {
type: 'void',
'x-component': 'Grid.Row',
"x-component-props": {
isLast: true,
},
properties: {
col31: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
'x-component-props': {
size: 1,
isLast: true,
},
'x-component': 'Grid.Row',
properties: {
block311: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
title: 'block311',
},
'x-component': 'Grid.Col',
properties: {
field5: {
[uid()]: {
type: 'string',
required: true,
title: '字段5',
@ -163,65 +99,40 @@ const schema = {
},
},
},
[`gr_${uid()}`]: {
actions: {
type: 'void',
'x-component': 'Grid.Row',
// 'x-decorator': 'Div',
'x-component': 'Space',
properties: {
[`gc_${uid()}`]: {
submit: {
type: 'void',
'x-component': 'Grid.Col',
'x-component': 'Action',
'x-component-props': {
size: 1,
},
properties: {
[`gb_${uid()}`]: {
type: 'void',
'x-component': 'Grid.Block',
properties: {
[`gbn_${uid()}`]: {
type: 'void',
'x-component': 'AddNew.FormItem',
},
},
// block: true,
type: 'primary',
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '提交',
},
reset: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
// block: true,
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '重置',
},
},
},
},
},
actions: {
type: 'void',
// 'x-decorator': 'Div',
'x-component': 'Space',
properties: {
submit: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
// block: true,
type: 'primary',
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '提交',
},
reset: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
// block: true,
useAction: '{{ useLogin }}',
style: {
// width: '100%',
},
},
title: '重置',
},
},
},
},
};

View File

@ -73,4 +73,4 @@ export default {
},
},
},
}
}

View File

@ -10,7 +10,5 @@ group:
path: /client
---
<!-- <code src="./demos/demo1.tsx"/> -->
<code src="./demos/demo1.tsx"/>