jjb-lc-designable
Version:
基于alibaba-designable源码二次封装的表单设计器。
135 lines • 4.79 kB
JavaScript
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React from 'react';
import { FormPath } from 'jjb-lc-formily/core';
import { toJS } from 'jjb-lc-formily/reactive';
import { ArrayField, Field as InternalField, ObjectField, VoidField, observer, Schema } from 'jjb-lc-formily/react';
import { FormItem } from 'jjb-lc-formily/antd';
import { each, reduce } from 'jjb-lc-formily/shared';
import { createBehavior } from 'jjb-lc-designable/core';
import { useDesigner, useTreeNode, useComponents } from 'jjb-lc-designable/react';
import { isArr, isStr } from 'jjb-lc-designable/shared';
import { Container } from '../../common/Container';
import { AllLocales } from '../../locales';
Schema.silent(true);
const SchemaStateMap = {
title: 'title',
description: 'description',
default: 'value',
enum: 'dataSource',
readOnly: 'readOnly',
writeOnly: 'editable',
required: 'required',
'x-content': 'content',
'x-value': 'value',
'x-editable': 'editable',
'x-disabled': 'disabled',
'x-read-pretty': 'readPretty',
'x-read-only': 'readOnly',
'x-visible': 'visible',
'x-hidden': 'hidden',
'x-display': 'display',
'x-pattern': 'pattern'
};
const NeedShownExpression = {
title: true,
description: true,
default: true,
'x-content': true,
'x-value': true
};
const isExpression = val => isStr(val) && /^\{\{.*\}\}$/.test(val);
const filterExpression = val => {
if (typeof val === 'object') {
const isArray = isArr(val);
const results = reduce(val, (buf, value, key) => {
if (isExpression(value)) {
return buf;
} else {
const results = filterExpression(value);
if (results === undefined || results === null) return buf;
if (isArray) {
return buf.concat([results]);
}
buf[key] = results;
return buf;
}
}, isArray ? [] : {});
return results;
}
if (isExpression(val)) {
return;
}
return val;
};
const toDesignableFieldProps = (schema, components, nodeIdAttrName, id) => {
const results = {};
each(SchemaStateMap, (fieldKey, schemaKey) => {
const value = schema[schemaKey];
if (isExpression(value)) {
if (!NeedShownExpression[schemaKey]) return;
if (value) {
results[fieldKey] = value;
return;
}
} else if (value) {
results[fieldKey] = filterExpression(value);
}
});
if (!components['FormItem']) {
components['FormItem'] = FormItem;
}
const decorator = schema['x-decorator'] && FormPath.getIn(components, schema['x-decorator']);
const component = schema['x-component'] && FormPath.getIn(components, schema['x-component']);
const decoratorProps = schema['x-decorator-props'] || {};
const componentProps = schema['x-component-props'] || {};
if (decorator) {
results.decorator = [decorator, toJS(decoratorProps)];
}
if (component) {
results.component = [component, toJS(componentProps)];
}
if (decorator) {
FormPath.setIn(results['decorator'][1], nodeIdAttrName, id);
} else if (component) {
FormPath.setIn(results['component'][1], nodeIdAttrName, id);
}
results.title = results.title && /*#__PURE__*/React.createElement("span", {
"data-content-editable": "title"
}, results.title);
results.description = results.description && /*#__PURE__*/React.createElement("span", {
"data-content-editable": "description"
}, results.description);
return results;
};
export const Field = observer(props => {
const designer = useDesigner();
const components = useComponents();
const node = useTreeNode();
if (!node) return null;
const fieldProps = toDesignableFieldProps(props, components, designer.props.nodeIdAttrName, node.id);
if (props.type === 'object') {
return (
/*#__PURE__*/
// @ts-ignore
React.createElement(Container, null, /*#__PURE__*/React.createElement(ObjectField, _extends({}, fieldProps, {
name: node.id
}), props.children))
);
} else if (props.type === 'array') {
return /*#__PURE__*/React.createElement(ArrayField, _extends({}, fieldProps, {
name: node.id
}));
} else if (node.props.type === 'void') {
return /*#__PURE__*/React.createElement(VoidField, _extends({}, fieldProps, {
name: node.id
}), props.children);
}
return /*#__PURE__*/React.createElement(InternalField, _extends({}, fieldProps, {
name: node.id
}));
});
Field.Behavior = createBehavior({
name: 'Field',
selector: 'Field',
designerLocales: AllLocales.Field
});