diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index 47a1592534b..a39257803a5 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -30,4 +30,5 @@
- [](./API/FormCard.md)
- [](./API/FormBlock.md)
- [](./API/FormItemGrid.md)
- - [](./API/FormSlot.md)
\ No newline at end of file
+ - [](./API/FormSlot.md)
+- [PlayGround](../packages/builder-next/lib/index.js)
\ No newline at end of file
diff --git a/packages/builder-next/.npmignore b/packages/builder-next/.npmignore
new file mode 100644
index 00000000000..b423fb999cb
--- /dev/null
+++ b/packages/builder-next/.npmignore
@@ -0,0 +1,3 @@
+node_modules
+*.log
+build
diff --git a/packages/builder-next/LICENSE.md b/packages/builder-next/LICENSE.md
new file mode 100644
index 00000000000..2bd9316cd51
--- /dev/null
+++ b/packages/builder-next/LICENSE.md
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/packages/builder-next/README.md b/packages/builder-next/README.md
new file mode 100644
index 00000000000..9d2412db39e
--- /dev/null
+++ b/packages/builder-next/README.md
@@ -0,0 +1,2 @@
+# @uform/builder-next
+> UForm 可视化配置 next实现
\ No newline at end of file
diff --git a/packages/builder-next/package.json b/packages/builder-next/package.json
new file mode 100644
index 00000000000..43e769750fd
--- /dev/null
+++ b/packages/builder-next/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "@uform/builder-next",
+ "version": "0.1.0-beta.15",
+ "license": "MIT",
+ "main": "lib/index.js",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/alibaba/uform.git"
+ },
+ "bugs": {
+ "url": "https://github.com/alibaba/uform/issues"
+ },
+ "homepage": "https://github.com/alibaba/uform#readme",
+ "engines": {
+ "npm": ">=3.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ },
+ "dependencies": {
+ "@alifd/next": "^1.13.1",
+ "@uform/builder": "^0.1.0-beta.14"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "gitHead": "f513fc2dcca781b3f7aa588c4419bce20cba2d8b"
+}
\ No newline at end of file
diff --git a/packages/builder-next/src/index.js b/packages/builder-next/src/index.js
new file mode 100644
index 00000000000..2a8e83f8e9a
--- /dev/null
+++ b/packages/builder-next/src/index.js
@@ -0,0 +1,142 @@
+import React from 'react'
+import SchemaForm, { FormButtonGroup, Submit, Reset } from '@uform/next'
+import Builder from '@uform/builder'
+
+import {
+ Button,
+ Collapse,
+ Message,
+ Upload,
+ Input,
+ Select,
+ DatePicker,
+ Icon,
+ Checkbox,
+ NumberPicker,
+ TimePicker,
+ Radio,
+ Form,
+ Tab
+} from '@alifd/next'
+
+// style
+import '@alifd/next/dist/next.css'
+
+SchemaForm.FormButtonGroup = FormButtonGroup
+SchemaForm.Submit = Submit
+SchemaForm.Reset = Reset
+
+const renderSchema = {}
+
+const props = {
+ UI: {
+ version: '1.x',
+ Button,
+ Accordion: Collapse,
+ Toast: Message,
+ Upload,
+ Input,
+ Select,
+ Icon,
+ DatePicker,
+ TimePicker,
+ Checkbox,
+ NumberPicker,
+ Radio,
+ RadioGroup: Radio.Group,
+ TabPane: Tab.Item,
+ Form,
+ Tab
+ },
+ // 主题: dark/light,默认dark
+ themeStyle: 'dark',
+ // 是否展示布局组件,默认为false
+ showLayoutField: true,
+ // 是否展示预览按钮,默认为true
+ showPreviewBtn: true,
+ // 是否展示源码按钮
+ showSourceCodeBtn: true,
+ // 控制返回按钮点击事件
+ onBackBtnClick: () => {
+ alert('点击了返回')
+ },
+ // 额外全局按钮
+ globalButtonList: [
+ // {
+ // key: 'submit',
+ // title: '自定义保存',
+ // render: (props) => {
+ // return {props.children}
+ // },
+ // props: {
+ // // loading: true,
+ // },
+ // }, {
+ // key: 'cancel',
+ // title: '取消',
+ // props: {
+ // onClick: () => {
+ // alert('点击取消');
+ // }
+ // },
+ // }
+ ],
+ // 是否展示全局配置
+ showGlobalCfg: true,
+ // 全局配置额外项
+ extraGlobalCfgList: [
+ {
+ name: 'labelCol',
+ title: 'label宽度占比',
+ type: 'string'
+ },
+ {
+ name: 'wrapperCol',
+ title: 'wrapper宽度占比',
+ type: 'string'
+ }
+ ],
+ globalCfg: {},
+ supportFieldList: [],
+ includeFieldListKeyList: [
+ 'input',
+ 'multipleInput',
+ 'number',
+ 'radio',
+ 'checkbox',
+ 'date',
+ 'month',
+ 'daterange',
+ 'time'
+ ],
+
+ // 渲染引擎
+ renderEngine: SchemaForm,
+
+ schema: renderSchema,
+ // onChange: (data) => {
+ // console.info('index onChange data', data);
+ // },
+ onSubmit: data => {
+ console.info('index onSubmit data', data)
+ }
+}
+
+class Component extends React.Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ schema: renderSchema
+ }
+ }
+
+ render() {
+ return (
+
+
+
+ )
+ }
+}
+
+export default Component
diff --git a/packages/builder/package.json b/packages/builder/package.json
index acbe8fc9869..c21e43e8d65 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -43,7 +43,8 @@
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0",
"styled-components": "^4.1.2",
- "uuid": "^3.2.1"
+ "uuid": "^3.2.1",
+ "react-dnd": "^7.4.1"
},
"publishConfig": {
"access": "public"
diff --git a/packages/builder/src/App.js b/packages/builder/src/App.js
index 0546111588f..e9ec1332d28 100644
--- a/packages/builder/src/App.js
+++ b/packages/builder/src/App.js
@@ -1,7 +1,6 @@
import React, { Component } from 'react'
import cls from 'classnames'
import PropTypes from 'prop-types'
-import { SchemaForm } from './utils/baseForm'
import { connect } from 'react-redux'
import {
changePreview,
@@ -19,17 +18,85 @@ import AppStyle from './style'
// components
import FieldList from './components/fields/index'
import Preview from './components/preview/index'
-import AccordionList from './components/props/accordList'
import generateGlobalBtnList from './components/globalBtnList/index'
+import PropsSetting from './components/props/propsSetting'
+import { SchemaForm, Field } from './utils/baseForm'
+import defaultGlobalCfgList from './configs/supportGlobalCfgList'
+
const noop = () => {}
class App extends Component {
constructor(props) {
super(props)
this.state = {
- systemError: false
+ systemError: false,
+ accordionList: []
+ }
+ }
+
+ generateGlobalCfgList = () => {
+ // Merge custom form global property configuration
+ const globalCfgList = [
+ ...defaultGlobalCfgList,
+ ...this.props.extraGlobalCfgList
+ ]
+ const _globalCfgList = []
+ for (let i = globalCfgList.length - 1; i >= 0; i--) {
+ if (
+ !_globalCfgList.find(cfgItem => cfgItem.name === globalCfgList[i].name)
+ ) {
+ _globalCfgList.unshift(globalCfgList[i])
+ }
+ }
+ return _globalCfgList
+ }
+
+ // global config
+ renderGlobalConfig = () => {
+ const globalCfgList = this.generateGlobalCfgList()
+
+ const content = (
+ {
+ this.props.changeGbConfig(value)
+ }}
+ defaultValue={this.props.gbConfig}
+ labelAlign='left'
+ labelTextAlign='right'
+ >
+ {globalCfgList.map(props => (
+
+ ))}
+
+ )
+
+ return content
+ }
+
+ getAccordionList = () => {
+ const list = [
+ {
+ title: '组件配置',
+ content: (
+
+ ),
+ expanded: true
+ }
+ ]
+
+ if (this.props.showGlobalCfg) {
+ list.unshift({
+ title: '全局配置',
+ content: this.renderGlobalConfig(),
+ expanded: true
+ })
}
+ return list
}
componentWillMount() {
@@ -44,6 +111,12 @@ class App extends Component {
_initSchema(schema)
}
+ componentDidMount() {
+ this.setState({
+ accordionList: this.getAccordionList()
+ })
+ }
+
componentWillUnmount() {
// Clear the selected componentId with the selected component
this.props.changeComponent()
@@ -138,6 +211,7 @@ class App extends Component {
render() {
const { initSchemaData, renderEngine } = this.props
+ const { Accordion, version: UIVersion } = this.props.UI
const contentHeight = window.innerHeight - 64
@@ -169,10 +243,28 @@ class App extends Component {
/>
-
+ {UIVersion === '1.x' ? (
+
+ ) : (
+
{
+ this.setState({
+ accordionList: list
+ })
+ }}
+ />
+ )}
{this.getEditorTpl()}
diff --git a/packages/builder/src/__tests__/reducers/index.spec.js b/packages/builder/src/__tests__/reducers/index.spec.js
index d180b8fccfa..1820e75ae50 100644
--- a/packages/builder/src/__tests__/reducers/index.spec.js
+++ b/packages/builder/src/__tests__/reducers/index.spec.js
@@ -66,9 +66,8 @@ describe('reducers', () => {
name: '__id__',
title: '唯一标识',
type: 'string',
- description: '发起请求时带过去的参数字段',
- required: true,
- value: '11111'
+ description: '唯一标识:发起请求时带上的参数id,必填,全局保证唯一。',
+ required: true
},
{ name: 'description', title: '提示文案', type: 'string' },
{
@@ -215,11 +214,14 @@ describe('reducers', () => {
test('gbConfig reducers return initial state', () => {
expect(gbConfigReducer(undefined, {})).toEqual({
labelAlign: 'left',
- labelTextAlign: 'left',
+ labelTextAlign: 'right',
autoAddColon: true,
needFormButtonGroup: false,
inline: false,
- size: 'medium'
+ size: 'medium',
+ labelCol: 8,
+ wrapperCol: 16,
+ editable: true
})
})
test('gbConfig reducers return custom state', () => {
@@ -229,7 +231,9 @@ describe('reducers', () => {
autoAddColon: true,
needFormButtonGroup: false,
inline: false,
- size: 'small'
+ size: 'small',
+ labelCol: 8,
+ wrapperCol: 16
}
const action = {
@@ -248,7 +252,10 @@ describe('reducers', () => {
needFormButtonGroup: false,
inline: true,
size: 'large',
- extra: 'extra'
+ extra: 'extra',
+ labelCol: 8,
+ wrapperCol: 16,
+ editable: true
}
expect(gbConfigReducer(beforeState, action)).toEqual(afterState)
@@ -480,8 +487,7 @@ describe('reducers', () => {
title: '单行文本框',
placeholder: '请输入',
'x-index': 0,
- id: '111',
- __id__: '111'
+ id: '111'
}
}
}
@@ -491,7 +497,7 @@ describe('reducers', () => {
'111': {
type: 'object',
id: '111',
- __id__: '111',
+ 'x-index': 0,
'x-component': 'layout',
properties: {},
'x-props': {
@@ -533,8 +539,7 @@ describe('reducers', () => {
title: '单行文本框',
placeholder: '请输入',
'x-index': 0,
- id: '222',
- __id__: '222'
+ id: '222'
}
}
}
@@ -547,8 +552,7 @@ describe('reducers', () => {
type: 'string',
title: '111',
'x-index': 0,
- id: '111',
- __id__: '111'
+ id: '111'
},
'222': {
key: 'input',
@@ -560,15 +564,13 @@ describe('reducers', () => {
title: '单行文本框',
placeholder: '请输入',
'x-index': 1,
- id: '222',
- __id__: '222'
+ id: '222'
},
'333': {
type: 'string',
title: '333',
'x-index': 2,
- id: '333',
- __id__: '333'
+ id: '333'
}
}
}
diff --git a/packages/builder/src/actions/index.js b/packages/builder/src/actions/index.js
index d46c5dc5688..a2f4640bf88 100644
--- a/packages/builder/src/actions/index.js
+++ b/packages/builder/src/actions/index.js
@@ -28,7 +28,11 @@ export const addComponentAndEdit = (
dispatch(addComponent(component, existId, id, type, containerId))
dispatch(changeComponent(id))
dispatch(showComponentProps(id, component, containerId))
- dispatch(changeLayoutId(containerId))
+
+ if (component.__key__ === 'layout') {
+ dispatch(changeLayoutId(id))
+ }
+
dispatch(
editComponent(
id,
diff --git a/packages/builder/src/components/fields/index.js b/packages/builder/src/components/fields/index.js
index 73a2bf5e427..75cba201334 100644
--- a/packages/builder/src/components/fields/index.js
+++ b/packages/builder/src/components/fields/index.js
@@ -63,7 +63,8 @@ class FieldList extends Component {
: fieldItem
renderFieldList() {
- const _addComponent = this.props.addComponentAndEdit
+ const _addComponentAndEdit = this.props.addComponentAndEdit
+
return (
{this.fieldList.map((fieldItem, i) => {
@@ -80,7 +81,7 @@ class FieldList extends Component {
draggable
onDragStart={ev => this.onDragStart(ev, newFieldItem)}
onClick={() => {
- _addComponent && _addComponent(newFieldItem)
+ _addComponentAndEdit && _addComponentAndEdit(newFieldItem)
}}
>
({})
+const mapStateToProps = state => state
const mapDispatchToProps = dispatch => ({
addComponent: component => dispatch(addComponent(component)),
@@ -122,7 +123,8 @@ const mapDispatchToProps = dispatch => ({
dispatch(editComponent(id, propsData, containerId)),
showComponentProps: (id, comp) => dispatch(showComponentProps(id, comp)),
changeComponent: componentId => dispatch(changeComponent(componentId)),
- addComponentAndEdit: component => dispatch(addComponentAndEdit(component))
+ addComponentAndEdit: (component, existId, type, containerId) =>
+ dispatch(addComponentAndEdit(component, existId, type, containerId))
})
class StyledFieldListComp extends React.Component {
diff --git a/packages/builder/src/components/fields/layout.js b/packages/builder/src/components/fields/layout.js
index 88e31ff7ad0..65f4f816247 100644
--- a/packages/builder/src/components/fields/layout.js
+++ b/packages/builder/src/components/fields/layout.js
@@ -33,7 +33,10 @@ class Component extends React.Component {
// eslint-disable-next-line
key={i}
onClick={() => {
- _addComponentAndEdit && _addComponentAndEdit(item)
+ _addComponentAndEdit &&
+ _addComponentAndEdit(
+ item
+ )
}}
>
{title}
@@ -57,10 +60,11 @@ class Component extends React.Component {
}
}
-const mapStateToProps = () => ({})
+const mapStateToProps = state => state
const mapDispatchToProps = dispatch => ({
- addComponentAndEdit: component => dispatch(addComponentAndEdit(component))
+ addComponentAndEdit: (component, existId, type, containerId) =>
+ dispatch(addComponentAndEdit(component, existId, type, containerId))
})
class StyledLayoutListComp extends React.Component {
diff --git a/packages/builder/src/components/preview/fieldMiddleware.js b/packages/builder/src/components/preview/fieldMiddleware.js
index 516ba53bf7c..07864b8bf43 100644
--- a/packages/builder/src/components/preview/fieldMiddleware.js
+++ b/packages/builder/src/components/preview/fieldMiddleware.js
@@ -7,11 +7,14 @@ export default (FormConsumer, that) => {
if (hasRegisted) {
return false
}
+ const { UI } = that.props
window.__hasRegisted__ = true
registerFieldMiddleware(Field => props =>
React.createElement(FormConsumer, {}, (obj = {}) => {
const { type } = obj
- if (props.path.length === 0 || type !== 'preview') { return React.createElement(Field, props) }
+ if (props.path.length === 0 || type !== 'preview') {
+ return React.createElement(Field, props)
+ }
const { title = '', active = false } = props.schema
const id = props.path[0]
const comp = {
@@ -49,15 +52,7 @@ export default (FormConsumer, that) => {
className='preview-line-layer-layout'
title='编辑'
>
- {
- React.createElement(Field, {
- 'x-component': 'Icon',
- 'x-props': {
- type: 'edit',
- size: 'small'
- }
- })
- }
+
{
}}
title='删除'
>
- {
- React.createElement(Field, {
- 'x-component': 'Icon',
- 'x-props': {
- type: 'ashbin',
- size: 'small'
- }
- })
- }
+
diff --git a/packages/builder/src/components/preview/index.js b/packages/builder/src/components/preview/index.js
index abe5f93f822..ea363f36704 100644
--- a/packages/builder/src/components/preview/index.js
+++ b/packages/builder/src/components/preview/index.js
@@ -143,11 +143,15 @@ class Preview extends Component {
)
const globalCfg = pick(gbConfig, [
+ 'labelCol',
+ 'wrapperCol',
+ 'action',
'labelAlign',
'labelTextAlign',
'autoAddColon',
'inline',
- 'size'
+ 'size',
+ 'editable'
])
return (
diff --git a/packages/builder/src/components/props/accordList.js b/packages/builder/src/components/props/accordList.js
deleted file mode 100644
index c27fdd7d70a..00000000000
--- a/packages/builder/src/components/props/accordList.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import React from 'react'
-import PropsSetting from './propsSetting'
-import { SchemaForm, Field } from '../../utils/baseForm'
-import defaultGlobalCfgList from '../../configs/supportGlobalCfgList'
-
-export default class extends React.Component {
- constructor(props) {
- super(props)
- this.state = {
- accordionList: this.getAccordionList()
- }
- }
-
- componentDidMount() {
- // this.setState({
- // accordionList: this.getAccordionList()
- // })
- }
-
- generateGlobalCfgList = () => {
- // Merge custom form global property configuration
- const globalCfgList = [
- ...defaultGlobalCfgList,
- ...this.props.extraGlobalCfgList
- ]
- const _globalCfgList = []
- for (let i = globalCfgList.length - 1; i >= 0; i--) {
- if (
- !_globalCfgList.find(cfgItem => cfgItem.name === globalCfgList[i].name)
- ) {
- _globalCfgList.unshift(globalCfgList[i])
- }
- }
- return _globalCfgList
- }
-
- // global config
- renderGlobalConfig = () => {
- const globalCfgList = this.generateGlobalCfgList()
-
- const content = (
- {
- this.props.changeGbConfig(value)
- }}
- defaultValue={this.props.gbConfig}
- labelAlign='left'
- labelTextAlign='left'
- >
- {globalCfgList.map(props => (
-
- ))}
-
- )
-
- return content
- }
-
- getAccordionList() {
- const list = [
- {
- title: '组件配置',
- content: (
-
- ),
- expanded: true
- }
- ]
-
- if (this.props.showGlobalCfg) {
- list.unshift({
- title: '全局配置',
- content: this.renderGlobalConfig(),
- expanded: true
- })
- }
- return list
- }
-
- render() {
- const { Accordion, version: UIVersion } = this.props.UI
-
- return UIVersion === '1.x' ? (
-
- ) : (
- {
- this.setState({
- accordionList: list
- })
- }}
- />
- )
- }
-}
diff --git a/packages/builder/src/components/props/colsDetail.js b/packages/builder/src/components/props/colsDetail.js
new file mode 100644
index 00000000000..c969bd83f0d
--- /dev/null
+++ b/packages/builder/src/components/props/colsDetail.js
@@ -0,0 +1,53 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+
+class ColsDetail extends React.Component {
+ static propTypes = {
+ value: PropTypes.arrayOf(PropTypes.any),
+ onChange: PropTypes.func
+ }
+
+ handleChange = (idx, val) => {
+ const { UI } = this.props
+ if (!val) {
+ UI.Toast.error('请确保列宽是有效整数')
+ return false
+ }
+ const { onChange, value } = this.props
+ let newValue = [...value]
+ const diff = val - newValue[idx]
+
+ if (diff >= newValue[newValue.length - 1]) {
+ UI.Toast.error('请确保4列宽度加起来等于24')
+ return false
+ }
+
+ newValue = newValue.map((_val, i) => {
+ if (i === idx) {
+ return val
+ }
+ if (i === newValue.length - 1) {
+ return _val - diff
+ }
+ if (i < idx) {
+ return _val
+ }
+ return _val
+ })
+
+ onChange(newValue)
+ }
+
+ render() {
+ const { value = [], UI } = this.props
+ return value.map((item, idx) => (
+ this.handleChange(idx, val)}
+ />
+ ))
+ }
+}
+
+export default ColsDetail
diff --git a/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateDefaultEditor.js b/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateDefaultEditor.js
index 1f8eada249c..46376d97ebc 100644
--- a/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateDefaultEditor.js
+++ b/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateDefaultEditor.js
@@ -69,7 +69,7 @@ class Editor extends Component {
}}
/>
),
- specify:
+ specify:
}}
/>
)
diff --git a/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateTimeDefaultEditor.js b/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateTimeDefaultEditor.js
index c071f92ba66..a818e1c69d4 100644
--- a/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateTimeDefaultEditor.js
+++ b/packages/builder/src/components/props/editors/fieldAttrEditors/defaultValueEditor/dateTimeDefaultEditor.js
@@ -17,20 +17,24 @@ const ds = [
]
const DatePickerDefault = props => (
- {
- props.onChange(vStr)
+ if (vStr) {
+ props.onChange(vStr)
+ } else {
+ props.onChange(v.format('HH:mm:ss'))
+ }
}}
style={{
verticalAlign: 'top',
- marginLeft: 20
+ marginLeft: 5
}}
/>
)
class Editor extends Component {
render() {
+ const { UI } = this.props
return (
,
- specify:
+ specify:
}}
/>
)
diff --git a/packages/builder/src/components/props/propsSetting.js b/packages/builder/src/components/props/propsSetting.js
index 947c55f9ffc..7eb414e492f 100644
--- a/packages/builder/src/components/props/propsSetting.js
+++ b/packages/builder/src/components/props/propsSetting.js
@@ -1,6 +1,10 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
-import { SchemaForm } from '../../utils/baseForm'
+import {
+ SchemaForm,
+ registerFormFields,
+ connect as formConnect
+} from '../../utils/baseForm'
import { connect } from 'react-redux'
import {
showComponentProps,
@@ -16,6 +20,7 @@ import FileSetting from './fileSetting'
import './defaultValueCascader/index'
import './dataSourceEditor/index'
+import ColsDetail from './colsDetail'
import pickBy from 'lodash.pickby'
@@ -28,6 +33,17 @@ class PropsSetting extends Component {
componentProps: PropTypes.object
}
+ constructor(props) {
+ super(props)
+ registerFormFields({
+ colsDetail: formConnect({
+ defaultProps: {
+ UI: this.props.UI
+ }
+ })(ColsDetail)
+ })
+ }
+
onChangeHandler = formdata => {
const { componentId = '' } = this.props
if (!componentId) return false
@@ -156,7 +172,9 @@ class PropsSetting extends Component {
renderConfigList() {
const { componentId = '' } = this.props
- if (!componentId) { return 请选择待编辑的表单字段
}
+ if (!componentId) {
+ return 请选择待编辑的表单字段
+ }
return (
@@ -190,7 +208,7 @@ class PropsSetting extends Component {
onChange={this.onChangeHandler}
schema={this.generatePropsSchema()}
labelAlign='left'
- labelTextAlign='left'
+ labelTextAlign='right'
labelCol={8}
>
{' '}
diff --git a/packages/builder/src/configs/supportConfigList.js b/packages/builder/src/configs/supportConfigList.js
index c9befdd2dc6..dd1644b7140 100644
--- a/packages/builder/src/configs/supportConfigList.js
+++ b/packages/builder/src/configs/supportConfigList.js
@@ -4,7 +4,7 @@ const FIELDLIST = {
name: '__id__',
title: '唯一标识',
type: 'string',
- description: '发起请求时带过去的参数字段',
+ description: '唯一标识:发起请求时带上的参数id,必填,全局保证唯一。',
required: true
},
PLACEHOLDER: {
@@ -133,6 +133,9 @@ export const getPropsByKey = key => {
'PLACEHOLDER'
])
case 'date':
+ case 'month':
+ case 'daterange':
+ case 'time':
return generateProps(
[
'ID',
@@ -215,6 +218,27 @@ export const getPropsByKey = key => {
}
]
)
+ case 'wrapper_card':
+ return generateProps(
+ ['ID'],
+ [
+ {
+ name: 'x-props.title',
+ title: '标题',
+ type: 'string'
+ },
+ {
+ name: 'x-props.subTitle',
+ title: '副标题',
+ type: 'string'
+ },
+ {
+ name: 'x-props.showHeadDivider',
+ title: '是否展示标题底部横线',
+ type: 'boolean'
+ }
+ ]
+ )
default:
return defaultProps
}
diff --git a/packages/builder/src/configs/supportGlobalCfgList.js b/packages/builder/src/configs/supportGlobalCfgList.js
index 59c8ed3feb2..10fbdd98475 100644
--- a/packages/builder/src/configs/supportGlobalCfgList.js
+++ b/packages/builder/src/configs/supportGlobalCfgList.js
@@ -23,11 +23,14 @@ const sizeEnum = [
// 默认全局配置值
export const defaultGlobalCfgValue = {
labelAlign: 'left',
- labelTextAlign: 'left',
+ labelTextAlign: 'right',
autoAddColon: true,
needFormButtonGroup: false,
inline: false,
- size: 'medium'
+ size: 'medium',
+ labelCol: 8,
+ wrapperCol: 16,
+ editable: true
}
// 默认全局配置属性列表
diff --git a/packages/builder/src/configs/supportLayoutList.js b/packages/builder/src/configs/supportLayoutList.js
index ca0972a8022..7059efeb77f 100644
--- a/packages/builder/src/configs/supportLayoutList.js
+++ b/packages/builder/src/configs/supportLayoutList.js
@@ -25,5 +25,19 @@ export default [
gutter: 20
}
}
+ },
+ {
+ key: 'wrapper_card',
+ icon: 'clock-circle-o',
+ type: 'object',
+ title: 'FormCard卡片式布局',
+ __key__: 'layout',
+ __key__data__: {
+ 'x-component': 'card',
+ 'x-props': {
+ title: '卡片式布局',
+ showHeadDivider: true
+ }
+ }
}
]
diff --git a/packages/builder/src/demo/index-1-x.js b/packages/builder/src/demo/index-1-x.js
index efb169f5004..56b53af8b1d 100644
--- a/packages/builder/src/demo/index-1-x.js
+++ b/packages/builder/src/demo/index-1-x.js
@@ -1,5 +1,5 @@
import React from 'react'
-import SchemaForm from '@uform/next'
+import SchemaForm, { FormButtonGroup, Submit, Reset } from '@uform/next'
import Index from '../index'
import {
Button,
@@ -12,6 +12,7 @@ import {
Icon,
Checkbox,
NumberPicker,
+ TimePicker,
Radio,
Form,
Tab
@@ -20,6 +21,10 @@ import {
// style
import '@alifd/next/dist/next.css'
+SchemaForm.FormButtonGroup = FormButtonGroup
+SchemaForm.Submit = Submit
+SchemaForm.Reset = Reset
+
const renderSchema = {}
const props = {
@@ -33,6 +38,7 @@ const props = {
Select,
Icon,
DatePicker,
+ TimePicker,
Checkbox,
NumberPicker,
Radio,
@@ -44,7 +50,7 @@ const props = {
// 主题: dark/light,默认dark
// themeStyle: 'light',
// 是否展示布局组件,默认为false
- showLayoutField: false,
+ showLayoutField: true,
showPreviewBtn: true,
showSourceCodeBtn: true,
// 控制返回按钮点击事件
@@ -75,10 +81,37 @@ const props = {
// 是否展示全局配置
showGlobalCfg: true,
// 全局配置额外项
- extraGlobalCfgList: [],
+ extraGlobalCfgList: [
+ {
+ name: 'labelCol',
+ title: 'label宽度占比',
+ type: 'string'
+ },
+ {
+ name: 'wrapperCol',
+ title: 'wrapper宽度占比',
+ type: 'string'
+ },
+ {
+ name: 'editable',
+ title: '表单是否可编辑',
+ description: '若设置为false,则可快速搭建出表单详情页,只需设置每个组件的默认值',
+ type: 'boolean'
+ }
+ ],
globalCfg: {},
supportFieldList: [],
- includeFieldListKeyList: ['input', 'multipleInput', 'number', 'radio', 'checkbox', 'date', 'month', 'daterange', 'time'],
+ includeFieldListKeyList: [
+ 'input',
+ 'multipleInput',
+ 'number',
+ 'radio',
+ 'checkbox',
+ 'date',
+ 'month',
+ 'daterange',
+ 'time'
+ ],
// 渲染引擎
renderEngine: SchemaForm,
diff --git a/packages/builder/src/demo/index.js b/packages/builder/src/demo/index.js
index fd40670ddef..4e922b43647 100644
--- a/packages/builder/src/demo/index.js
+++ b/packages/builder/src/demo/index.js
@@ -4,7 +4,7 @@ import Index from '../index'
import {
Button,
Accordion,
- Message,
+ Feedback,
Upload,
Input,
Select,
@@ -17,8 +17,6 @@ import {
Tab
} from '@alife/next'
-// style
-// import '@alifd/next/dist/next.css'
import '@alife/next/dist/next.min.css'
const renderSchema = {}
@@ -28,7 +26,7 @@ const props = {
version: '0.x',
Button,
Accordion,
- Toast: Message,
+ Toast: Feedback.toast,
Upload,
Input,
Select,
diff --git a/packages/builder/src/index.js b/packages/builder/src/index.js
index 79291168d4a..c6f589dee19 100644
--- a/packages/builder/src/index.js
+++ b/packages/builder/src/index.js
@@ -26,8 +26,11 @@ const initialState = {
codemode: false,
componentProps: {},
gbConfig: {
+ action: '',
+ labelCol: 8,
+ wrapperCol: 8,
labelAlign: 'left',
- labelTextAlign: 'left',
+ labelTextAlign: 'right',
autoAddColon: true,
needFormButtonGroup: false,
inline: false,
diff --git a/packages/builder/src/reducers/componentProps.js b/packages/builder/src/reducers/componentProps.js
index 460ddcf8946..8bcb1f360f9 100644
--- a/packages/builder/src/reducers/componentProps.js
+++ b/packages/builder/src/reducers/componentProps.js
@@ -13,11 +13,6 @@ export default (state = {}, action) => {
return Object.assign(
{},
item,
- name === '__id__'
- ? {
- value: id
- }
- : {},
comp[name]
? {
value: comp[name]
diff --git a/packages/builder/src/reducers/initSchemaData.js b/packages/builder/src/reducers/initSchemaData.js
index 6f9b83324bf..17b75c8f10a 100644
--- a/packages/builder/src/reducers/initSchemaData.js
+++ b/packages/builder/src/reducers/initSchemaData.js
@@ -75,21 +75,21 @@ export default (state = {}, action) => {
}
return newState
case 'ADD_COMPONENT':
- if (component.__key__ === 'layout') {
- // 判断是否布局组件特殊处理
- newState.properties[id] = {
- type: 'object',
- id,
- __id__: id,
- ...component.__key__data__,
- properties: {},
- 'x-props': {
- ...component.__key__data__['x-props'],
- _extra: component
+ const _component_ =
+ component.__key__ === 'layout'
+ ? {
+ type: 'object',
+ id,
+ ...component.__key__data__,
+ properties: {},
+ 'x-props': {
+ ...component.__key__data__['x-props'],
+ _extra: component
+ }
+ }
+ : {
+ ...component
}
- }
- return newState
- }
const propertiesList1 =
addType === 'layout'
@@ -108,14 +108,14 @@ export default (state = {}, action) => {
}
}
propertiesList1[idx] = {
- ...component,
+ ..._component_,
id,
'x-index': idx
}
} else {
// 在最后插入新的组件
propertiesList1[propertiesList1.length] = {
- ...component,
+ ..._component_,
id,
'x-index': propertiesList1.length
}
@@ -124,8 +124,7 @@ export default (state = {}, action) => {
const _properties1 = {}
propertiesList1.forEach(item => {
_properties1[item.id] = {
- ...item,
- __id__: item.id
+ ...item
}
})
diff --git a/packages/builder/src/style.js b/packages/builder/src/style.js
index 6ccb1fbde2b..2a9c4ebdb3f 100644
--- a/packages/builder/src/style.js
+++ b/packages/builder/src/style.js
@@ -10,6 +10,9 @@ export default styled.div`
.next-checkbox-label {
color: ${props => props.theme.whiteColor};
}
+ .preview-main .next-checkbox-label {
+ color: #333;
+ }
.schemaform-header {
position: relative;
height: 64px;
@@ -38,7 +41,8 @@ export default styled.div`
top: 24px;
width: 9px;
height: 17px;
- background: url('${props => props.theme.backIconUrl}') no-repeat center center;
+ background: url('${props =>
+ props.theme.backIconUrl}') no-repeat center center;
background-size: 9px 17px;
}
&::after {
diff --git a/packages/builder/src/utils/lang.js b/packages/builder/src/utils/lang.js
index c508906bb89..1265165a7b4 100644
--- a/packages/builder/src/utils/lang.js
+++ b/packages/builder/src/utils/lang.js
@@ -18,7 +18,7 @@ export const isNum = isType('Number')
export const isIter = obj => isArr(obj) || isObj(obj)
const replaceSingleDefault = v => {
- if (!isFlagValue(v)) return v
+ if (!isFlagValue(v)) return ''
const { type, flag, value } = v
@@ -41,7 +41,7 @@ const replaceSingleDefault = v => {
if (type === 'specify') {
return value
} else if (type === 'now') {
- return now.format('YYYY-MM-DD HH:MM:SS')
+ return now.format('HH:MM:SS')
} else if (type === 'url') {
return params[value]
}
diff --git a/packages/builder/src/utils/util.js b/packages/builder/src/utils/util.js
index ad3d7d4d94d..042ac79659d 100644
--- a/packages/builder/src/utils/util.js
+++ b/packages/builder/src/utils/util.js
@@ -142,7 +142,7 @@ export const wrapSubmitSchema = (schema, keepAll = false) => {
/**
* 根据schema获取有顺序的properties
* @param {Object} schema
- * @param {Boolean} needFormat 是否需要转换返回数组,默认是
+ * @param {String} containerId 相对容器id
*/
export const getOrderProperties = (schema = {}) => {
const { properties = {} } = schema
@@ -166,7 +166,8 @@ export const getOrderProperties = (schema = {}) => {
const index = item['x-index']
if (typeof index === 'number') {
if (!newProperties[index]) {
- const _key = index > newProperties.length + 1 ? newProperties.length : index
+ const _key =
+ index > newProperties.length + 1 ? newProperties.length : index
newProperties[_key] = {
...item,
id: key