diff --git a/atom.css b/atom.css index d2fb0664f..dd9555bb8 100644 --- a/atom.css +++ b/atom.css @@ -371,3 +371,4 @@ .fr-wrapper .truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .fr-wrapper .bg-white { background-color: #fff; } +.fr-wrapper .pointer:hover { cursor: pointer; } diff --git a/src/base/asField.jsx b/src/base/asField.jsx index f54ee0289..136d2a23e 100644 --- a/src/base/asField.jsx +++ b/src/base/asField.jsx @@ -91,9 +91,14 @@ export const asField = ({ FieldUI, Widget }) => { if (isDependShow({ formData, dependShow })) { return null; } - const isComplex = + + let isComplex = _schema.type === 'object' || (_schema.type === 'array' && _schema.enum === undefined); + const isModal = options && (options.modal || options.drawer); + if (isModal) { + isComplex = false; + } const validateText = getValidateText(_rest); // 必填*,label,描述,竖排时的校验语,只要存在一个,label就不为空 @@ -179,15 +184,18 @@ export const DefaultFieldUI = ({ enum: _enum, description = '', 'ui:widget': widget, + 'ui:options': options, } = schema; const isCheckbox = type === 'boolean' && widget !== 'switch'; - + const isModal = options && (options.modal || options.drawer); let fieldClass = `fr-field w-100 ${isComplex ? 'fr-field-complex' : ''}`; let labelClass = 'fr-label mb2'; let contentClass = 'fr-content'; - switch (type) { case 'object': + if (isModal) { + break; + } if (title) { labelClass += ' fr-label-object bb b--black-20 pb1 mt2 mb3'; // fr-label-object 无默认style,只是占位用于使用者样式覆盖 } @@ -199,6 +207,9 @@ export const DefaultFieldUI = ({ } break; case 'array': + if (isModal) { + break; + } if (title && !_enum) { labelClass += ' fr-label-array mt2 mb3'; } diff --git a/src/base/utils.js b/src/base/utils.js index 4cb7368f1..154114242 100644 --- a/src/base/utils.js +++ b/src/base/utils.js @@ -207,3 +207,10 @@ export function isFunctionSchema(schema) { } }); } + +function stringContains(str, text) { + return str.indexOf(text) > -1; +} + +export const isObj = a => + stringContains(Object.prototype.toString.call(a), 'Object'); diff --git a/src/components/listHoc.jsx b/src/components/listHoc.jsx index 2333c9760..1a52657ac 100644 --- a/src/components/listHoc.jsx +++ b/src/components/listHoc.jsx @@ -188,7 +188,7 @@ const fieldListHoc = ButtonComponent => { /> ))} {!readonly && ( -
+
{canAdd && ( 新增 diff --git a/src/components/map.jsx b/src/components/map.jsx index 8b94ab5ac..c65cd19d1 100644 --- a/src/components/map.jsx +++ b/src/components/map.jsx @@ -1,10 +1,16 @@ import React from 'react'; export default function map(p) { + let className = 'fr-map '; + const { options = {} } = p || {}; + const isModal = options.modal || options.drawer; + try { + className += isModal ? 'fr-wrapper' : ''; // 因为modal跳出fr的dom层级了,需要重新加个顶层的className + } catch (error) {} return ( -
- {Object.keys(p.value).map(name => - p.getSubField({ +
+ {Object.keys(p.value).map(name => { + return p.getSubField({ name, value: p.value[name], onChange(key, val, objValue) { @@ -33,8 +39,8 @@ export default function map(p) { p.onChange(p.name, value); }, rootValue: p.value, - }) - )} + }); + })}
); } diff --git a/src/widgets/antd/list.jsx b/src/widgets/antd/list.jsx index d86a226f7..e09d8ed83 100644 --- a/src/widgets/antd/list.jsx +++ b/src/widgets/antd/list.jsx @@ -3,11 +3,11 @@ * 数组组件 */ -import React from 'react'; +import React, { useState } from 'react'; import listHoc from '../../components/listHoc'; import * as Icons from '@ant-design/icons'; - -import { Button } from 'antd'; +import { isObj } from '../../base/utils'; +import { Button, Modal, Drawer } from 'antd'; function FrButton({ icon, children, ...rest }) { let iconName; @@ -25,12 +25,71 @@ function FrButton({ icon, children, ...rest }) { const IconComponent = Icons[iconName]; if (IconComponent) { return ( - ); } - return ; + return ( + + ); } -export default listHoc(FrButton); +const List = listHoc(FrButton); + +const ListWithModal = props => { + const { options, schema } = props || {}; + const [show, setShow] = useState(false); + const toggle = () => setShow(o => !o); + if (options && options.modal) { + const config = isObj(options.modal) ? options.modal : {}; + const { text } = config; + return ( +
+ + {text && typeof text === 'string' ? '+ ' + text : '+ 配置'} + + +
+ +
+
+
+ ); + } + if (options && options.drawer) { + const config = isObj(options.drawer) ? options.drawer : {}; + const { text } = config; + return ( +
+ + {text && typeof text === 'string' ? '+ ' + text : '+ 配置'} + + +
+ +
+
+
+ ); + } + return ; +}; + +export default ListWithModal; diff --git a/src/widgets/antd/map.jsx b/src/widgets/antd/map.jsx index 7f4689d65..9f344127c 100644 --- a/src/widgets/antd/map.jsx +++ b/src/widgets/antd/map.jsx @@ -1,2 +1,55 @@ -import map from '../../components/map'; -export default map; +import React, { useState } from 'react'; +import { Modal, Drawer } from 'antd'; +import { isObj } from '../../base/utils'; +import Map from '../../components/map'; + +const MapWithModal = props => { + const { options = {}, schema } = props || {}; + const [show, setShow] = useState(false); + const toggle = () => setShow(o => !o); + if (options && options.modal) { + const config = isObj(options.modal) ? options.modal : {}; + const { text } = config; + return ( + + ); + } + if (options && options.drawer) { + const config = isObj(options.drawer) ? options.drawer : {}; + const { text } = config; + return ( + + ); + } + return ; +}; + +export default MapWithModal; diff --git a/src/widgets/fusion/list.jsx b/src/widgets/fusion/list.jsx index ed3c0f62c..b7b53c74f 100644 --- a/src/widgets/fusion/list.jsx +++ b/src/widgets/fusion/list.jsx @@ -1,6 +1,7 @@ -import React from 'react'; -import { Button, Icon } from '@alifd/next'; +import React, { useState } from 'react'; +import { Button, Icon, Dialog as Modal, Drawer } from '@alifd/next'; import listHoc from '../../components/listHoc'; +import { isObj } from '../../base/utils'; function FrButton({ icon, children, type, ...rest }) { let iconName; @@ -23,4 +24,58 @@ function FrButton({ icon, children, type, ...rest }) { ); } -export default listHoc(FrButton); +const List = listHoc(FrButton); + +const ListWithModal = props => { + const { options, schema } = props || {}; + const [show, setShow] = useState(false); + const toggle = () => setShow(o => !o); + if (options && options.modal) { + const config = isObj(options.modal) ? options.modal : {}; + const { text } = config; + return ( + + ); + } + if (options && options.drawer) { + const config = isObj(options.drawer) ? options.drawer : {}; + const { text } = config; + return ( + + ); + } + return ; +}; + +export default ListWithModal; diff --git a/src/widgets/fusion/map.jsx b/src/widgets/fusion/map.jsx index 7f4689d65..117f8c9e0 100644 --- a/src/widgets/fusion/map.jsx +++ b/src/widgets/fusion/map.jsx @@ -1,2 +1,54 @@ -import map from '../../components/map'; -export default map; +import React, { useState } from 'react'; +import { Dialog as Modal, Drawer } from '@alifd/next'; +import { isObj } from '../../base/utils'; +import Map from '../../components/map'; + +const MapWithModal = props => { + const { options = {}, schema } = props || {}; + const [show, setShow] = useState(false); + const toggle = () => setShow(o => !o); + if (options && options.modal) { + const config = isObj(options.modal) ? options.modal : {}; + const { text } = config; + return ( + + ); + } + if (options && options.drawer) { + const config = isObj(options.drawer) ? options.drawer : {}; + const { text } = config; + return ( + + ); + } + return ; +}; + +export default MapWithModal;