diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index fec7eedf6..d552b7777 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -145,7 +145,6 @@ export class ComponentMeta { } @computed get icon() { - // TODO: 标记下。这块需要康师傅加一下API,页面正常渲染。 // give Slot default icon // if _title is TitleConfig get _title.icon return ( diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 379da3875..022859b0f 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -512,6 +512,10 @@ export class Designer { return meta; } + getComponentMetasMap() { + return this._componentMetasMap; + } + @computed get componentsMap(): { [key: string]: NpmInfo | Component } { const maps: any = {}; const designer = this; diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 4eefd2ff7..404f95dc7 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -347,6 +347,10 @@ export class NodeChildren { return this.children.find(fn); } + reduce(fn: (acc: any, cur: Node) => any, initialValue: any) { + return this.children.reduce(fn, initialValue); + } + mergeChildren( remover: (node: Node, idx: number) => boolean, adder: (children: Node[]) => NodeData[] | null, diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index 60b71fee0..1b585d810 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -15,11 +15,6 @@ import { import { getLogger, Logger } from '@ali/lowcode-utils'; import { ILowCodePluginContext, PluginContextOptions } from './plugin-types'; -/** - * 一些 API 设计约定: - * 1. 事件的命名格式为:on[Will|Did]VerbNoun?,参考 https://code.visualstudio.com/api/references/vscode-api#events - * 2. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数 - */ export default class PluginContext implements ILowCodePluginContext { private readonly [editorSymbol]: Editor; private readonly [designerSymbol]: Designer; diff --git a/packages/shell/src/component-meta.ts b/packages/shell/src/component-meta.ts new file mode 100644 index 000000000..0e7cd79e2 --- /dev/null +++ b/packages/shell/src/component-meta.ts @@ -0,0 +1,75 @@ +import { Editor } from '@ali/lowcode-editor-core'; +import { + DocumentModel as InnerDocumentModel, + Node as InnerNode, + ParentalNode, + IOnChangeOptions as InnerIOnChangeOptions, + PropChangeOptions as InnerPropChangeOptions, + ComponentMeta as InnerComponentMeta, +} from '@ali/lowcode-designer'; +import { TransformStage, RootSchema, NodeSchema, NodeData, GlobalEvent } from '@ali/lowcode-types'; +import Node from './node'; +import Selection from './selection'; +import Detecting from './detecting'; +import History from './history'; +import Project from './project'; +import Prop from './prop'; +import { componentMetaSymbol } from './symbols'; + + +export default class ComponentMeta { + private readonly [componentMetaSymbol]: InnerComponentMeta; + + constructor(componentMeta: InnerComponentMeta) { + this[componentMetaSymbol] = componentMeta; + } + + static create(componentMeta: InnerComponentMeta | null) { + if (!componentMeta) return null; + return new ComponentMeta(componentMeta); + } + + get componentName(): string { + return this[componentMetaSymbol].componentName; + } + + get isContainer(): boolean { + return this[componentMetaSymbol].isContainer; + } + + get isMinimalRenderUnit(): boolean { + return this[componentMetaSymbol].isMinimalRenderUnit; + } + + get isModal(): boolean { + return this[componentMetaSymbol].isModal; + } + + get configure() { + return this[componentMetaSymbol].configure; + } + + get title() { + return this[componentMetaSymbol].title; + } + + get icon() { + return this[componentMetaSymbol].icon; + } + + get npm() { + return this[componentMetaSymbol].npm; + } + + get acceptable(): boolean { + return this[componentMetaSymbol].acceptable; + } + + setNpm(npm: any) { + this[componentMetaSymbol].setNpm(npm); + } + + getMetadata() { + return this[componentMetaSymbol].getMetadata(); + } +} diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index 902296a72..d0bfba04f 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -52,7 +52,7 @@ export default class DocumentModel { * 获取当前文档所属的 project * @returns */ - getProject() { + get project() { return Project.create(this[documentSymbol].project); } @@ -60,7 +60,7 @@ export default class DocumentModel { * 获取文档的根节点 * @returns */ - getRoot() { + get root(): Node | null { return Node.create(this[documentSymbol].getRoot()); } @@ -68,7 +68,7 @@ export default class DocumentModel { * 获取文档下所有节点 * @returns */ - getNodesMap() { + get nodesMap() { const map = new Map(); for (let id in this[documentSymbol].nodesMap.keys()) { map.set(id, this.getNodeById(id)!); @@ -125,6 +125,15 @@ export default class DocumentModel { return Node.create(node); } + /** + * 创建一个节点 + * @param data + * @returns + */ + createNode(data: any) { + return Node.create(this[documentSymbol].createNode(data)); + } + /** * 移除指定节点/节点id * @param idOrNode diff --git a/packages/shell/src/event.ts b/packages/shell/src/event.ts index 04de387ff..781f01254 100644 --- a/packages/shell/src/event.ts +++ b/packages/shell/src/event.ts @@ -2,7 +2,7 @@ import { Editor as InnerEditor } from '@ali/lowcode-editor-core'; import { getLogger } from '@ali/lowcode-utils'; import { editorSymbol } from './symbols'; -const logger = getLogger({ level: 'warn', bizName: 'shell:event:' }); +const logger = getLogger({ level: 'warn', bizName: 'shell:event' }); type EventOptions = { prefix: string; diff --git a/packages/shell/src/index.ts b/packages/shell/src/index.ts index efea86a04..073b62b8c 100644 --- a/packages/shell/src/index.ts +++ b/packages/shell/src/index.ts @@ -13,6 +13,12 @@ import Hotkey from './hotkey'; import Skeleton from './skeleton'; export * from './symbols'; +/** + * 所有 shell 层模型的 API 设计约定: + * 1. 事件的命名格式为:on[Will|Did]VerbNoun?,参考 https://code.visualstudio.com/api/references/vscode-api#events + * 2. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数 + * 3. 对于属性的导出,统一用 .xxx 的 getter 模式,不能使用 .getXxx() + */ export { DocumentModel, Detecting, diff --git a/packages/shell/src/material.ts b/packages/shell/src/material.ts index c50c19ecd..639a712eb 100644 --- a/packages/shell/src/material.ts +++ b/packages/shell/src/material.ts @@ -11,6 +11,7 @@ import { import { AssetsJson } from '@ali/lowcode-utils'; import { ComponentAction } from '@ali/lowcode-types'; import { editorSymbol, designerSymbol } from './symbols'; +import ComponentMeta from './component-meta'; export default class Material { private readonly [editorSymbol]: Editor; @@ -21,6 +22,10 @@ export default class Material { this[designerSymbol] = editor.get('designer')!; } + get componentsMap() { + return this[designerSymbol].componentsMap; + } + setAssets(assets: AssetsJson) { return this[editorSymbol].setAssets(assets); } @@ -46,11 +51,16 @@ export default class Material { } getComponentMeta(componentName: string) { - return this[designerSymbol].getComponentMeta(componentName); + return ComponentMeta.create(this[designerSymbol].getComponentMeta(componentName)); } - getComponentsMap() { - return this[designerSymbol].componentsMap; + getComponentMetasMap() { + const map = new Map(); + const originalMap = this[designerSymbol].getComponentMetasMap(); + for (let componentName in originalMap.keys()) { + map.set(componentName, this.getComponentMeta(componentName)!); + } + return map; } addBuiltinComponentAction(action: ComponentAction) { diff --git a/packages/shell/src/node-children.ts b/packages/shell/src/node-children.ts index 9c1c8f7d0..03733efdf 100644 --- a/packages/shell/src/node-children.ts +++ b/packages/shell/src/node-children.ts @@ -15,7 +15,7 @@ export default class NodeChildren { return new NodeChildren(nodeChldren); } - getOwner() { + get owner(): Node | null { return Node.create(this[nodeChildrenSymbol].owner); } @@ -91,6 +91,12 @@ export default class NodeChildren { ); } + reduce(fn: (acc: any, cur: Node) => any, initialValue: any) { + return this[nodeChildrenSymbol].reduce((acc: any, cur: InnerNode) => { + return fn(acc, Node.create(cur)!); + }, initialValue); + } + mergeChildren( remover: (node: Node, idx: number) => boolean, adder: (children: Node[]) => any, diff --git a/packages/shell/src/node.ts b/packages/shell/src/node.ts index b456197a6..3ae3a502e 100644 --- a/packages/shell/src/node.ts +++ b/packages/shell/src/node.ts @@ -7,6 +7,7 @@ import { CompositeValue, NodeSchema, TransformStage } from '@ali/lowcode-types'; import Prop from './prop'; import DocumentModel from './document-model'; import NodeChildren from './node-children'; +import ComponentMeta from './component-meta'; import { documentSymbol, nodeSymbol } from './symbols'; export default class Node { @@ -30,6 +31,50 @@ export default class Node { return this[nodeSymbol].id; } + get title() { + return this[nodeSymbol].title; + } + + get isContainer() { + return this[nodeSymbol].isContainer(); + } + + get isRoot() { + return this[nodeSymbol].isRoot(); + } + + get isPage() { + return this[nodeSymbol].isPage(); + } + + get isComponent() { + return this[nodeSymbol].isComponent(); + } + + get isSlot() { + return this[nodeSymbol].isSlot(); + } + + get isParental() { + return this[nodeSymbol].isParental(); + } + + get isLeaf() { + return this[nodeSymbol].isLeaf(); + } + + get index() { + return this[nodeSymbol].index; + } + + get icon() { + return this[nodeSymbol].icon; + } + + get zLevel() { + return this[nodeSymbol].zLevel; + } + /** * 返回节点 componentName */ @@ -37,14 +82,70 @@ export default class Node { return this[nodeSymbol].componentName; } + get componentMeta() { + return ComponentMeta.create(this[nodeSymbol].componentMeta); + } + /** * 获取节点所属的文档模型对象 * @returns */ - getDocumentModel() { + get document() { return DocumentModel.create(this[documentSymbol]); } + /** + * 获取当前节点的前一个兄弟节点 + * @returns + */ + get prevSibling(): Node | null { + return Node.create(this[nodeSymbol].prevSibling); + } + + /** + * 获取当前节点的后一个兄弟节点 + * @returns + */ + get nextSibling(): Node | null { + return Node.create(this[nodeSymbol].nextSibling); + } + + /** + * 获取当前节点的父亲节点 + * @returns + */ + get parent(): Node | null { + return Node.create(this[nodeSymbol].parent); + } + + /** + * 获取当前节点的孩子节点模型 + * @returns + */ + get children() { + return NodeChildren.create(this[nodeSymbol].children); + } + + get slots(): Node[] { + return this[nodeSymbol].slots.map((node: InnerNode) => Node.create(node)!); + } + + get slotFor() { + return Prop.create(this[nodeSymbol].slotFor); + } + + hasSlots() { + return this[nodeSymbol].hasSlots(); + } + + hasCondition() { + return this[nodeSymbol].hasCondition(); + } + + hasLoop() { + return this[nodeSymbol].hasLoop(); + } + /** * 获取指定 path 的属性模型实例 * @param path 属性路径,支持 a / a.b / a.0 等格式 @@ -103,38 +204,6 @@ export default class Node { return this.getExtraProp(path)?.setValue(value); } - /** - * 获取当前节点的前一个兄弟节点 - * @returns - */ - getPrevSibling() { - return Node.create(this[nodeSymbol].prevSibling); - } - - /** - * 获取当前节点的后一个兄弟节点 - * @returns - */ - getNextSibling() { - return Node.create(this[nodeSymbol].nextSibling); - } - - /** - * 获取当前节点的父亲节点 - * @returns - */ - getParent() { - return Node.create(this[nodeSymbol].parent); - } - - /** - * 获取当前节点的孩子节点模型 - * @returns - */ - getChildren() { - return NodeChildren.create(this[nodeSymbol].children); - } - /** * 导入节点数据 * @param data diff --git a/packages/shell/src/project.ts b/packages/shell/src/project.ts index 5f338b7b6..faa83c336 100644 --- a/packages/shell/src/project.ts +++ b/packages/shell/src/project.ts @@ -22,6 +22,14 @@ export default class Project { return new Project(project); } + /** + * 获取当前 project 下所有 documents + * @returns + */ + get documents(): DocumentModel[] { + return this[projectSymbol].documents.map((doc) => DocumentModel.create(doc)!); + } + /** * 打开一个 document * @param doc @@ -61,14 +69,6 @@ export default class Project { return DocumentModel.create(this[projectSymbol].getDocument(id)); } - /** - * 获取当前 project 下所有 documents - * @returns - */ - getDocuments(): DocumentModel[] { - return this[projectSymbol].documents.map((doc) => DocumentModel.create(doc)!); - } - /** * 导出 project * @returns diff --git a/packages/shell/src/prop.ts b/packages/shell/src/prop.ts index d339f9993..d929fc953 100644 --- a/packages/shell/src/prop.ts +++ b/packages/shell/src/prop.ts @@ -15,15 +15,15 @@ export default class Prop { return new Prop(prop); } - getId() { + get id() { return this[propSymbol].id; } - getKey() { + get key() { return this[propSymbol].key; } - getNode() { + get node(): Node | null { return Node.create(this[propSymbol].getNode()); } diff --git a/packages/shell/src/selection.ts b/packages/shell/src/selection.ts index 0ce6b0a60..a9fa8c767 100644 --- a/packages/shell/src/selection.ts +++ b/packages/shell/src/selection.ts @@ -15,6 +15,10 @@ export default class Selection { this[selectionSymbol] = document.selection; } + get selected() { + return this[selectionSymbol].selected; + } + select(id: string) { this[selectionSymbol].select(id); } @@ -23,10 +27,6 @@ export default class Selection { this[selectionSymbol].selectAll(ids); } - getSelected() { - return this[selectionSymbol].selected; - } - remove(id: string) { this[selectionSymbol].remove(id); } diff --git a/packages/shell/src/symbols.ts b/packages/shell/src/symbols.ts index cb8ddc6a3..a7724e994 100644 --- a/packages/shell/src/symbols.ts +++ b/packages/shell/src/symbols.ts @@ -13,5 +13,6 @@ export const propSymbol = Symbol('prop'); export const detectingSymbol = Symbol('detecting'); export const selectionSymbol = Symbol('selection'); export const historySymbol = Symbol('history'); +export const componentMetaSymbol = Symbol('componentMeta'); export const simulatorHostSymbol = Symbol('simulatorHost'); export const simulatorRendererSymbol = Symbol('simulatorRenderer'); \ No newline at end of file