UNPKG

jjb-lc-designable

Version:

基于alibaba-designable源码二次封装的表单设计器。

123 lines (116 loc) 3.72 kB
import { ISchema, Schema } from 'jjb-lc-formily/json-schema' import { ITreeNode } from 'jjb-lc-designable/core' import { clone, uid } from 'jjb-lc-designable/shared' export interface ITransformerOptions { designableFieldName?: string designableFormName?: string } export interface IFormilySchema { schema?: ISchema form?: Record<string, any> } const createOptions = (options: ITransformerOptions): ITransformerOptions => { return { designableFieldName: 'Field', designableFormName: 'Form', ...options, } } const findNode = (node: ITreeNode, finder?: (node: ITreeNode) => boolean) => { if (!node) return if (finder(node)) return node if (!node.children) return for (let i = 0; i < node.children.length; i++) { if (findNode(node.children[i])) return node.children[i] } return } export const transformToSchema = ( node: ITreeNode, options?: ITransformerOptions ): IFormilySchema => { const realOptions = createOptions(options) const root = findNode(node, (child) => { return child.componentName === realOptions.designableFormName }) const schema = { type: 'object', properties: {}, } if (!root) return { schema } const createSchema = (node: ITreeNode, schema: ISchema = {}) => { if (node !== root) { Object.assign(schema, clone(node.props)) } schema['x-designable-id'] = node.id if (schema.type === 'array') { if (node.children[0]) { if ( node.children[0].componentName === realOptions.designableFieldName ) { schema.items = createSchema(node.children[0]) schema['x-index'] = 0 } } node.children.slice(1).forEach((child, index) => { if (child.componentName !== realOptions.designableFieldName) return const key = child.props.name || child.id schema.properties = schema.properties || {} schema.properties[key] = createSchema(child) schema.properties[key]['x-index'] = index }) } else { node.children.forEach((child, index) => { if (child.componentName !== realOptions.designableFieldName) return const key = child.props.name || child.id schema.properties = schema.properties || {} schema.properties[key] = createSchema(child) schema.properties[key]['x-index'] = index }) } return schema } return { form: clone(root.props), schema: createSchema(root, schema) } } export const transformToTreeNode = ( formily: IFormilySchema = {}, options?: ITransformerOptions ) => { const realOptions = createOptions(options) const root: ITreeNode = { componentName: realOptions.designableFormName, props: formily.form, children: [], } const schema = new Schema(formily.schema) const cleanProps = (props: any) => { if (props['name'] === props['x-designable-id']) { delete props.name } delete props['version'] delete props['_isJSONSchemaObject'] return props } const appendTreeNode = (parent: ITreeNode, schema: Schema) => { if (!schema) return const current = { id: schema['x-designable-id'] || uid(), componentName: realOptions.designableFieldName, props: cleanProps(schema.toJSON(false)), children: [], } parent.children.push(current) if (schema.items && !Array.isArray(schema.items)) { appendTreeNode(current, schema.items) } schema.mapProperties((schema) => { schema['x-designable-id'] = schema['x-designable-id'] || uid() appendTreeNode(current, schema) }) } schema.mapProperties((schema) => { schema['x-designable-id'] = schema['x-designable-id'] || uid() appendTreeNode(root, schema) }) return root }