Skip to content

Commit

Permalink
refactor(@uform/react-schema-editor): update (#606)
Browse files Browse the repository at this point in the history
  • Loading branch information
andyforever authored and janryWang committed Jan 13, 2020
1 parent 4136691 commit 179cd62
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 83 deletions.
11 changes: 4 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"markdown-toc": "^1.2.0",
"moment": "^2.24.0",
"monaco-editor": "^0.18.1",
"node-sass": "^4.13.0",
"onchange": "^5.2.0",
"prettier": "^1.18.2",
"pretty-format": "^24.0.0",
Expand All @@ -126,7 +127,9 @@
"unified": "^7.1.0",
"user-event": "^1.4.4",
"wait-for-expect": "^3.0.1",
"webpack": "^4.35.3"
"webpack": "^4.35.3",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2"
},
"config": {
"ghooks": {
Expand All @@ -147,12 +150,6 @@
"git add"
]
},
"dependencies": {
"lodash": "^4.17.15",
"node-sass": "^4.13.0",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2"
},
"collective": {
"type": "opencollective",
"url": "https://opencollective.com/uform"
Expand Down
92 changes: 37 additions & 55 deletions packages/react-schema-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,45 @@ import { SchemaEditor } from './src'

function SchemaEditorDemo() {
const [schema, setSchema] = React.useState({
type: 'object',
title: '我是表单标题',
description: '我是表单描述',
properties: {
fieldA: {
type: 'object',
title: '我是层级嵌套标题',
description: '我是层级嵌套描述',
properties: {
arrayA: {
type: 'array',
title: '动物',
description: '我是字段描述',
component: 'Select',
items: {
type: 'string',
enum: ['Dog', 'Cat', 'Horse']
}
},
arrayB: {
type: 'array',
title: '熊猫',
description: '我是字段描述',
component: 'Select',
items: {
type: 'number',
enum: ['Dog', 'Cat', 'Horse']
}
},
numberB: {
type: 'number',
title: '年龄'
},
objectC: {
type: 'object'
},
input: {
type: 'string',
'x-component': 'Input',
'x-component-props': {
value: 'abc',
onChange: '{{function(){console.log("abcd");}}}'
},
'x-props': {
help: 'test'
},
'x-rules': [
{
required: true,
message: '此项必填'
}
]
}
}
title: '动态表单示例',
type: 'object',
"properties": {
"username": {
"title": "用户名",
"type": "string",
"x-component-props": {
"placeholder": "请输入用户名",
"onChange": "function(value) \n{console.log('input onChange', value, this.field, this.field.getValue('note'))"
}
},
"password": {
"title": "密码",
"type": "string",
"x-component": "Input",
"x-component-props": {
"htmlType": "password",
"placeholder": "请输入密码"
}
},
"note": {
"title": "备注",
"type": "string",
"x-component": "TextArea",
"x-component-props": {
"placeholder": "something"
}
},
"agreement": {
"title": "同意",
"type": "string",
"x-component": "Checkbox",
"x-component-props": {
"disabled": "{{!this.field.getValue('username')}}",
"defaultChecked": true
}
}
})
}
})

return <SchemaEditor schema={schema} onChange={setSchema} />
}
Expand Down
4 changes: 4 additions & 0 deletions packages/react-schema-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"scripts": {
"build": "tsc --declaration"
},
"dependencies": {
"lodash": "^4.17.15",
"@uform/react-schema-renderer": "^1.0.0-beta.5"
},
"devDependencies": {
"node-sass": "^4.13.0",
"typescript": "^3.5.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import * as React from 'react'
import { ISchemaPreviewProps } from '../utils/types'
import {
SchemaForm,
} from '@uform/react-schema-renderer'

export const SchemaPreview: React.FC<ISchemaPreviewProps> = ({ schema }) => {
return <div>SchemaPreview</div>
return <SchemaForm schema={schema}></SchemaForm>
}

SchemaPreview.displayName = 'SchemaPreview';
112 changes: 93 additions & 19 deletions packages/react-schema-editor/src/components/SchemaTree.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,49 @@
import React from 'react'
import { Tree, Icon, Button } from 'antd'
import { Tree, Icon, Menu, Dropdown } from 'antd'
import { ISchemaTreeProps } from '../utils/types'
import { getFieldTypeData } from '../utils/fieldEditorHelpers';
import * as fp from 'lodash/fp'
import _ from 'lodash'

const TreeNode = Tree.TreeNode
const { SubMenu } = Menu;

export const SchemaTree: React.FC<ISchemaTreeProps> = ({
schema,
onChange,
onSelect
}) => {
const addIndex = React.useRef(0)
const selectedKey = React.useRef('');

const handleSelect = React.useCallback((path: string[]) => {
onSelect(path[0])
selectedKey.current = path[0];
onSelect && onSelect(path[0])
}, [])

const handleRightClick = ({node}) => {
handleSelect([node.props.eventKey]);
}

const handleMenuClick = ({ item, key, keyPath, domEvent }) => {
if(selectedKey.current === 'root') return; // 根节点不能进行任何操作
if(keyPath.length > 1) {
if(keyPath[1] == 'node') {// 添加节点
addNode(keyPath[0]);
} else if (keyPath[1] == 'child') { // 添加叶子节点
addChildNode(keyPath[0])
} else {

}
} else {
switch(keyPath[0]) {
case 'delete':
deleteNode()
break;
}
}

}

const handleDrop = React.useCallback(
(info: any) => {
const sourcePath = info.dragNode.props.eventKey
Expand Down Expand Up @@ -95,32 +122,79 @@ export const SchemaTree: React.FC<ISchemaTreeProps> = ({
[schema, onChange]
)

const handleAddNewFormItem = React.useCallback(() => {
const addNode = React.useCallback((type) => {
let newSchema = schema
let pathArr = selectedKey.current.split('.');
pathArr.pop();
pathArr.push('new' + addIndex.current++);
newSchema = fp.set(
pathArr.join('.'),
{ type: type || 'object' },
newSchema
)

onChange(newSchema)
}, [schema, onChange])

const addChildNode = React.useCallback((type) => {
let newSchema = schema
newSchema = fp.set(
['properties', 'new' + addIndex.current++],
{ type: 'object' },
`${selectedKey.current}.properties.new${addIndex.current++}`,
{ type: type || 'object' },
newSchema
)

onChange(newSchema)
}, [schema, onChange])

const deleteNode = React.useCallback(() => {
let newSchema = schema
newSchema = fp.unset(selectedKey.current, newSchema);
onChange(newSchema)
}, [schema, onChange])

const getSubMenus = () => {
const {options} = getFieldTypeData();
return options.map(option => {
return <Menu.Item key={option.value}>{option.label}</Menu.Item>
})
}

const getMenu = () => {
const fieldSchema = fp.get(selectedKey.current, schema);
const disableChildNode = !fieldSchema || fieldSchema.type === 'string'
return (
<Menu onClick={handleMenuClick}>
<SubMenu key='node' title={<><Icon type='plus'></Icon>添加节点 </>}>
{getSubMenus()}
</SubMenu>
<SubMenu key='child' title={<><Icon type='plus'></Icon>添加子节点 </>} disabled={disableChildNode}>
{getSubMenus()}
</SubMenu>
<Menu.Item key='delete'>
<Icon type='delete'></Icon>删除节点
</Menu.Item>
</Menu>
)
}

return (
<>
<Tree
defaultExpandAll
showIcon
showLine
draggable
onSelect={handleSelect}
onDrop={handleDrop}
>
{TreeNodeBySchema({ schema, path: [] })}
</Tree>
<Button onClick={handleAddNewFormItem}>+ FormItem</Button>
</>
<Dropdown overlay={getMenu()} trigger={['contextMenu']}>
<div>
<Tree
defaultExpandAll
showLine
draggable
selectedKeys={[selectedKey.current]}
onSelect={handleSelect}
onDrop={handleDrop}
onRightClick={handleRightClick}
>
{TreeNodeBySchema({ schema, path: [] })}
</Tree>
</div>
</Dropdown>

)
}

Expand Down
6 changes: 5 additions & 1 deletion packages/react-schema-editor/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import _ from 'lodash'
import { SchemaTree } from './components/SchemaTree'
import FieldEditor from './components/FieldEditor'
import { SchemaCode } from './components/SchemaCode'
// import { SchemaPreview } from './components/SchemaPreview'
import { ComponentTypes } from './utils/types'
import {
getDefaultComponentType,
Expand Down Expand Up @@ -121,7 +122,10 @@ export const SchemaEditor: React.FC<{
onChange={handleCodeChange}
></SchemaCode>
</Tabs.TabPane>
<Tabs.TabPane tab="预览" key="3"></Tabs.TabPane>
<Tabs.TabPane tab="预览" key="3">
开发中,敬请期待...
{/* <SchemaPreview schema={schema}></SchemaPreview> */}
</Tabs.TabPane>
</Tabs>
</div>
</div>
Expand Down

0 comments on commit 179cd62

Please sign in to comment.