diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index e16619b17..e67299b0f 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -8,6 +8,8 @@ import DocumentModel from './document/document-model'; import ActiveTracker from './active-tracker'; import Location, { LocationData, isLocationChildrenDetail } from './location'; import Node, { insertChildren } from './document/node/node'; +import { isRootNode } from './document/node/root-node'; +import { ComponentDescriptionSpec, ComponentConfig } from './document/node/component-config'; export interface DesignerProps { className?: string; @@ -18,6 +20,7 @@ export interface DesignerProps { simulatorComponent?: ComponentType; dragGhostComponent?: ComponentType; suspensed?: boolean; + componentDescriptionSpecs?: ComponentDescriptionSpec[]; onMount?: (designer: Designer) => void; onDragstart?: (e: LocateEvent) => void; onDrag?: (e: LocateEvent) => void; @@ -107,6 +110,32 @@ export default class Designer { this._dropLocation = undefined; } + /** + * 获得合适的插入位置 + */ + getSuitableInsertion() { + const activedDoc = this.project.activedDocuments[0]; + if (!activedDoc) { + return null; + } + const nodes = activedDoc.selection.getNodes(); + let target; + let index: number | undefined; + if (!nodes || nodes.length < 1) { + target = activedDoc.rootNode; + } else { + const node = nodes[0]; + if (isRootNode(node)) { + target = node; + } else { + // FIXME!!, parent maybe null + target = node.parent!; + index = node.index + 1; + } + } + return { target, index }; + } + private props?: DesignerProps; setProps(props: DesignerProps) { if (this.props) { @@ -122,6 +151,9 @@ export default class Designer { if (props.suspensed !== this.props.suspensed && props.suspensed != null) { this.suspensed = props.suspensed; } + if (props.componentDescriptionSpecs !== this.props.componentDescriptionSpecs && props.componentDescriptionSpecs != null) { + this.buildComponentConfigMaps(props.componentDescriptionSpecs); + } } else { // init hotkeys // todo: @@ -136,6 +168,9 @@ export default class Designer { if (props.suspensed != null) { this.suspensed = props.suspensed; } + if (props.componentDescriptionSpecs != null) { + this.buildComponentConfigMaps(props.componentDescriptionSpecs); + } } this.props = props; } @@ -178,6 +213,33 @@ export default class Designer { // todo: } + @obx.val private _componentConfigMaps = new Map(); + + private buildComponentConfigMaps(specs: ComponentDescriptionSpec[]) { + specs.forEach(spec => { + const key = spec.componentName; + const had = this._componentConfigMaps.get(key); + if (had) { + had.spec = spec; + } else { + this._componentConfigMaps.set(key, new ComponentConfig(spec)); + } + }); + } + + getComponentConfig(componentName: string): ComponentConfig { + if (this._componentConfigMaps.has(componentName)) { + return this._componentConfigMaps.get(componentName)!; + } + + const config = new ComponentConfig({ + componentName, + }); + + this._componentConfigMaps.set(componentName, config); + return config; + } + purge() { // todo: } diff --git a/packages/designer/src/designer/project.ts b/packages/designer/src/designer/project.ts index 0d3dd36f9..2b861ba06 100644 --- a/packages/designer/src/designer/project.ts +++ b/packages/designer/src/designer/project.ts @@ -1,4 +1,4 @@ -import { obx } from '@recore/obx'; +import { obx, computed } from '@recore/obx'; import { ProjectSchema } from './schema'; import { EventEmitter } from 'events'; import Designer from './designer'; @@ -22,6 +22,10 @@ export default class Project { }; } + @computed get activedDocuments() { + return this.documents.filter(doc => doc.actived); + } + getDocument(fileName: string): DocumentContext {} addDocument(data: DocumentSchema): DocumentContext { diff --git a/packages/designer/src/designer/simulator-interface.ts b/packages/designer/src/designer/simulator-interface.ts index d38e2aa3b..8bbf7bde6 100644 --- a/packages/designer/src/designer/simulator-interface.ts +++ b/packages/designer/src/designer/simulator-interface.ts @@ -1,5 +1,5 @@ import { NpmInfo } from './schema'; -import { ComponentClass as ReactComponentClass, Component } from 'react'; +import { ComponentClass as ReactComponentClass, Component as ReactComponent, ComponentType } from 'react'; import { LocateEvent, ISensor } from './dragon'; import { Point } from './location'; import Node from './document/node/node'; @@ -10,13 +10,14 @@ export interface SimulatorInterface

extends ISensor { */ readonly bounds: object; - // containerAssets // like react jQuery lodash - // vendorsAssets // antd/fusion - // themeAssets - // componentAssets - // simulatorUrls // - // layout: ComponentName + // dependsAsset // like react jQuery lodash + // themesAsset + // componentsAsset + // simulatorUrl // // utils, dataSource, constants 模拟 + // + // later: + // layout: ComponentName // 获取区块代码, 通过 components 传递,可异步获取 setProps(props: P): void; @@ -78,7 +79,7 @@ export interface SimulatorInterface

extends ISensor { /** * 根据组件信息获取组件类 */ - getComponent(npmInfo: NpmInfo): ComponentClass | any; + getComponent(componentName: string): Component | any; /** * 根据节点获取节点的组件实例 */ @@ -102,8 +103,9 @@ export interface SimulatorInterface

extends ISensor { /** * 组件类定义 */ -export type ComponentClass = ReactComponentClass | object; +export type Component = ComponentType | object; + /** * 组件实例定义 */ -export type ComponentInstance = Element | Component | object; +export type ComponentInstance = Element | ReactComponent | object;