From 6dd1063148fa5dfdadd29006368060574abf8c56 Mon Sep 17 00:00:00 2001 From: "mario.gk" Date: Thu, 28 May 2020 12:36:02 +0800 Subject: [PATCH] support lowcode component --- .../designer/src/builtin-simulator/host.ts | 6 ++- .../src/builtin-simulator/renderer.ts | 2 + packages/designer/src/designer/designer.ts | 17 +++++--- packages/designer/src/simulator.ts | 6 ++- .../src/bundle/upgrade-metadata.ts | 9 ++++- .../react-simulator-renderer/src/renderer.ts | 39 +++++++++++++++++-- packages/types/src/metadata.ts | 3 +- 7 files changed, 68 insertions(+), 14 deletions(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index e216a16e2..cf0394314 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -22,7 +22,7 @@ import { CanvasPoint, } from '../designer'; import { parseMetadata } from './utils/parse-metadata'; -import { ComponentMetadata } from '@ali/lowcode-types'; +import { ComponentMetadata, ComponentSchema } from '@ali/lowcode-types'; import { BuiltinSimulatorRenderer } from './renderer'; import clipboard from '../designer/clipboard'; import { LiveEditing } from './live-editing/live-editing'; @@ -440,6 +440,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost(); setInstance(id: string, instances: ComponentInstance[] | null) { if (instances == null) { diff --git a/packages/designer/src/builtin-simulator/renderer.ts b/packages/designer/src/builtin-simulator/renderer.ts index 13db7bcd4..3994d67c4 100644 --- a/packages/designer/src/builtin-simulator/renderer.ts +++ b/packages/designer/src/builtin-simulator/renderer.ts @@ -1,7 +1,9 @@ import { ComponentInstance, NodeInstance, Component } from '../simulator'; +import { ComponentSchema } from '@ali/lowcode-types'; export interface BuiltinSimulatorRenderer { readonly isSimulatorRenderer: true; + createComponent(schema: ComponentSchema): Component | null; getComponent(componentName: string): Component; getComponentInstances(id: string): ComponentInstance[] | null; getClosestNodeInstance(from: ComponentInstance, nodeId?: string): NodeInstance | null; diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 066e2a481..4bb1a0d9f 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -228,7 +228,7 @@ export class Designer { touchOffsetObserver() { this.clearOobxList(true); - this.oobxList.forEach(item => item.compute()); + this.oobxList.forEach((item) => item.compute()); } createSettingEntry(editor: IEditor, nodes: Node[]) { @@ -392,11 +392,16 @@ export class Designer { @computed get componentsMap(): { [key: string]: NpmInfo | Component } { const maps: any = {}; this._componentMetasMap.forEach((config, key) => { - const view = config.getMetadata().experimental?.view; - if (view) { - maps[key] = view; - } else if (config.npm) { - maps[key] = config.npm; + const metaData = config.getMetadata(); + if (metaData.devMode === 'lowcode') { + maps[key] = this.currentDocument?.simulator?.createComponent(metaData.schema); + } else { + const view = metaData.experimental?.view; + if (view) { + maps[key] = view; + } else if (config.npm) { + maps[key] = config.npm; + } } }); return maps; diff --git a/packages/designer/src/simulator.ts b/packages/designer/src/simulator.ts index 0979ce40e..f051bc1f8 100644 --- a/packages/designer/src/simulator.ts +++ b/packages/designer/src/simulator.ts @@ -1,5 +1,5 @@ import { Component as ReactComponent, ComponentType } from 'react'; -import { ComponentMetadata } from '@ali/lowcode-types'; +import { ComponentMetadata, ComponentSchema } from '@ali/lowcode-types'; import { ISensor, Point, ScrollTarget, IScrollable } from './designer'; import { Node } from './document'; @@ -126,6 +126,10 @@ export interface ISimulatorHost

extends ISensor { * 根据节点获取节点的组件实例 */ getComponentInstances(node: Node): ComponentInstance[] | null; + /** + * 根据低代码组件 schema 创建组件类 + */ + createComponent(schema: ComponentSchema): Component | null; /** * 根据节点获取节点的组件运行上下文 */ diff --git a/packages/editor-preset-vision/src/bundle/upgrade-metadata.ts b/packages/editor-preset-vision/src/bundle/upgrade-metadata.ts index 79adb6db3..a718776d8 100644 --- a/packages/editor-preset-vision/src/bundle/upgrade-metadata.ts +++ b/packages/editor-preset-vision/src/bundle/upgrade-metadata.ts @@ -1,6 +1,6 @@ import { ComponentType, ReactElement, isValidElement, ComponentClass } from 'react'; import { isPlainObject } from '@ali/lowcode-utils'; -import { isI18nData, SettingTarget, InitialItem, FilterItem, isJSSlot, isJSExpression } from '@ali/lowcode-types'; +import { isI18nData, SettingTarget, InitialItem, FilterItem, isJSSlot, ProjectSchema } from '@ali/lowcode-types'; type Field = SettingTarget; @@ -166,6 +166,8 @@ export interface OldPrototypeConfig { onResizeStart?: (e: MouseEvent, triggerDirection: string, dragment: Node) => void; onResize?: (e: MouseEvent, triggerDirection: string, dragment: Node, moveX: number, moveY: number) => void; onResizeEnd?: (e: MouseEvent, triggerDirection: string, dragment: Node) => void; + devMode?: string; + schema?: ProjectSchema; } export interface ISetterConfig { @@ -585,6 +587,8 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { onResizeStart, // onResizeStart onResize, // onResize onResizeEnd, // onResizeEnd + devMode, + schema, } = oldConfig; const meta: any = { @@ -592,7 +596,8 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { title, icon, docUrl, - devMode: 'procode', + devMode: devMode || 'procode', + schema: schema?.componentsTree[0], }; if (category) { diff --git a/packages/react-simulator-renderer/src/renderer.ts b/packages/react-simulator-renderer/src/renderer.ts index a5bee9da7..29c07b69a 100644 --- a/packages/react-simulator-renderer/src/renderer.ts +++ b/packages/react-simulator-renderer/src/renderer.ts @@ -1,4 +1,4 @@ -import { createElement, ReactInstance, ComponentType } from 'react'; +import React, { createElement, ReactInstance, ComponentType, ReactElement } from 'react'; import { render as reactRender } from 'react-dom'; import { host } from './host'; import SimulatorRendererView from './renderer-view'; @@ -8,9 +8,9 @@ import { getClientRects } from './utils/get-client-rects'; import loader from './utils/loader'; import { reactFindDOMNodes, FIBER_KEY } from './utils/react-find-dom-nodes'; import { isESModule, isElement, cursor, setNativeSelection } from '@ali/lowcode-utils'; -import { RootSchema, NpmInfo } from '@ali/lowcode-types'; +import { RootSchema, NpmInfo, ComponentSchema } from '@ali/lowcode-types'; // just use types -import { BuiltinSimulatorRenderer, NodeInstance } from '@ali/lowcode-designer'; +import { BuiltinSimulatorRenderer, NodeInstance, Component, TransformStage } from '@ali/lowcode-designer'; import Slot from './builtin-components/slot'; import Leaf from './builtin-components/leaf'; @@ -210,6 +210,39 @@ export class SimulatorRenderer implements BuiltinSimulatorRenderer { return this.instancesMap.get(id) || null; } + createComponent(schema: ComponentSchema): Component | null { + const _schema = { + ...schema, + }; + _schema.methods = {}; + _schema.lifeCycles = {}; + + const getElement = (componentsMap: any, schema: any): ReactElement => { + const Com = componentsMap[schema.componentName]; + let children = null; + if (schema.children && schema.children.length > 0) { + children = schema.children.map((item: any) => getElement(componentsMap, item)); + } + const _leaf = host.document.designer.currentDocument?.createNode(schema); + const props = host.document.designer.transformProps(schema.props || {}, host.document.createNode(schema), TransformStage.Render); + return createElement(Com, {...props, _leaf}, children); + } + + const renderer = this; + class Com extends React.Component { + render() { + const componentsMap = renderer.componentsMap; + let children = null; + if (_schema.children && Array.isArray(_schema.children)) { + children = _schema.children?.map((item:any) => getElement(componentsMap, item)); + } + return createElement(React.Fragment, {}, children); + } + } + + return Com; + } + getClosestNodeInstance(from: ReactInstance, nodeId?: string): NodeInstance | null { return getClosestNodeInstance(from, nodeId); } diff --git a/packages/types/src/metadata.ts b/packages/types/src/metadata.ts index ac3bee227..95323fa04 100644 --- a/packages/types/src/metadata.ts +++ b/packages/types/src/metadata.ts @@ -5,7 +5,7 @@ import { TitleContent } from './title'; import { PropConfig } from './prop-config'; import { NpmInfo } from './npm'; import { FieldConfig } from './field-config'; -import { NodeSchema, NodeData } from './schema'; +import { NodeSchema, NodeData, ComponentSchema } from './schema'; import { SettingTarget } from './setting-target'; export type NestingFilter = (testNode: any, currentNode: any) => boolean; @@ -158,6 +158,7 @@ export interface ComponentMetadata { props?: PropConfig[]; configure?: FieldConfig[] | Configure; experimental?: Experimental; + schema?: ComponentSchema; } export interface TransformedComponentMetadata extends ComponentMetadata {