From d8014c9d1ab310317ad6fafb8fbba2c475d0491d Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 27 Feb 2023 19:59:54 +0800 Subject: [PATCH] fix: fix some ts error --- .eslintrc.js | 2 +- packages/designer/src/component-meta.ts | 3 +- packages/designer/src/designer/designer.ts | 11 +- packages/designer/src/designer/detecting.ts | 7 +- packages/designer/src/designer/location.ts | 9 +- .../src/designer/setting/setting-top-entry.ts | 20 +- .../designer/src/document/document-model.ts | 181 +++++++++++------- .../src/document/node/modal-nodes-manager.ts | 10 +- .../src/document/node/node-children.ts | 41 ++-- packages/designer/src/document/node/node.ts | 129 ++++++++----- .../designer/src/document/node/props/prop.ts | 8 +- .../designer/src/document/node/props/props.ts | 16 +- packages/designer/src/document/selection.ts | 20 +- packages/designer/src/project/project.ts | 26 ++- packages/designer/src/simulator.ts | 12 +- packages/shell/src/model/document-model.ts | 5 +- packages/shell/src/model/node.ts | 6 +- packages/shell/src/model/selection.ts | 4 +- .../types/src/shell/model/component-meta.ts | 10 +- packages/types/src/shell/model/detecting.ts | 6 +- .../types/src/shell/model/document-model.ts | 59 +++--- .../src/shell/model/modal-nodes-manager.ts | 10 +- .../types/src/shell/model/node-children.ts | 40 ++-- packages/types/src/shell/model/node.ts | 44 +++-- packages/types/src/shell/model/props.ts | 12 +- packages/types/src/shell/model/selection.ts | 10 +- .../types/src/shell/type/drag-node-object.ts | 4 +- packages/types/src/shell/type/field-config.ts | 2 +- .../types/src/shell/type/field-extra-props.ts | 4 +- packages/types/src/shell/type/metadata.ts | 22 +-- .../types/src/shell/type/setter-config.ts | 11 ++ .../check-types/is-drag-node-data-object.ts | 4 +- .../src/check-types/is-drag-node-object.ts | 4 +- packages/utils/src/check-types/is-node.ts | 4 +- 34 files changed, 454 insertions(+), 302 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1ec3834e6..f3ebedbbe 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,7 +20,7 @@ module.exports = { 'no-await-in-loop': 0, 'no-plusplus': 0, '@typescript-eslint/no-parameter-properties': 0, - '@typescript-eslint/no-unused-vars': 1, + 'no-restricted-exports': ['error'], 'no-multi-assign': 1, 'no-dupe-class-members': 1, 'react/no-deprecated': 1, diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index c361b21c9..2691a8971 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -56,7 +56,8 @@ export function buildFilter(rule?: string | string[] | RegExp | IPublicTypeNesti return (testNode: Node | IPublicTypeNodeSchema) => list.includes(testNode.componentName); } -export interface IComponentMeta extends IPublicModelComponentMeta { +export interface IComponentMeta extends IPublicModelComponentMeta { + prototype?: any; } export class ComponentMeta implements IComponentMeta { diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index c39e439aa..d40082d82 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -30,7 +30,7 @@ import { ActiveTracker, IActiveTracker } from './active-tracker'; import { Detecting } from './detecting'; import { DropLocation } from './location'; import { OffsetObserver, createOffsetObserver } from './offset-observer'; -import { SettingTopEntry } from './setting'; +import { ISettingTopEntry, SettingTopEntry } from './setting'; import { BemToolsManager } from '../builtin-simulator/bem-tools/manager'; import { ComponentActions } from '../component-actions'; @@ -61,6 +61,7 @@ export interface DesignerProps { } export interface IDesigner { + readonly shellModelFactory: IShellModelFactory; get dragon(): IPublicModelDragon; @@ -91,6 +92,12 @@ export interface IDesigner { getComponentMetasMap(): Map; addPropsReducer(reducer: IPublicTypePropsTransducer, stage: IPublicEnumTransformStage): void; + + postEvent(event: string, ...args: any[]): void; + + transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage): IPublicTypeCompositeObject | IPublicTypePropsList; + + createSettingEntry(nodes: INode[]): ISettingTopEntry; } export class Designer implements IDesigner { @@ -331,7 +338,7 @@ export class Designer implements IDesigner { this.oobxList.forEach((item) => item.compute()); } - createSettingEntry(nodes: Node[]) { + createSettingEntry(nodes: INode[]): ISettingTopEntry { return new SettingTopEntry(this.editor, nodes); } diff --git a/packages/designer/src/designer/detecting.ts b/packages/designer/src/designer/detecting.ts index 3a6082d5c..568639c37 100644 --- a/packages/designer/src/designer/detecting.ts +++ b/packages/designer/src/designer/detecting.ts @@ -4,8 +4,11 @@ import { IDocumentModel } from '../document/document-model'; import { INode } from '../document/node/node'; const DETECTING_CHANGE_EVENT = 'detectingChange'; -export interface IDetecting extends Omit< IPublicModelDetecting, 'capture' | 'release' | 'leave' > { - +export interface IDetecting extends Omit< IPublicModelDetecting, + 'capture' | + 'release' | + 'leave' +> { capture(node: INode | null): void; release(node: INode | null): void; diff --git a/packages/designer/src/designer/location.ts b/packages/designer/src/designer/location.ts index 08c168091..ccf26e325 100644 --- a/packages/designer/src/designer/location.ts +++ b/packages/designer/src/designer/location.ts @@ -1,7 +1,6 @@ -import { INode } from '../document'; +import { IDocumentModel, INode } from '../document'; import { ILocateEvent } from './dragon'; import { - IPublicModelDocumentModel, IPublicModelDropLocation, IPublicTypeLocationDetailType, IPublicTypeRect, @@ -105,7 +104,7 @@ export interface IDropLocation extends Omit< IPublicModelDropLocation, 'target' get target(): INode; - get document(): IPublicModelDocumentModel; + get document(): IDocumentModel | null; clone(event: IPublicModelLocateEvent): IDropLocation; } @@ -119,7 +118,7 @@ export class DropLocation implements IDropLocation { readonly source: string; - get document(): IPublicModelDocumentModel { + get document(): IDocumentModel | null { return this.target.document; } @@ -159,7 +158,7 @@ export class DropLocation implements IDropLocation { if (this.detail.index <= 0) { return null; } - return this.target.children.get(this.detail.index - 1); + return this.target.children?.get(this.detail.index - 1); } return (this.detail as any)?.near?.node; } diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 16a80dbc4..1c36f8e1b 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -4,19 +4,22 @@ import { computed, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor import { SettingEntry } from './setting-entry'; import { SettingField } from './setting-field'; import { SettingPropEntry } from './setting-prop-entry'; -import { Node } from '../../document'; +import { INode } from '../../document'; import { ComponentMeta } from '../../component-meta'; -import { Designer } from '../designer'; +import { IDesigner } from '../designer'; import { Setters } from '@alilc/lowcode-shell'; -function generateSessionId(nodes: Node[]) { +function generateSessionId(nodes: INode[]) { return nodes .map((node) => node.id) .sort() .join(','); } -export class SettingTopEntry implements SettingEntry { +export interface ISettingTopEntry extends SettingEntry { +} + +export class SettingTopEntry implements ISettingTopEntry { private emitter: IEventBus = createModuleEventBus('SettingTopEntry'); private _items: Array = []; @@ -68,21 +71,21 @@ export class SettingTopEntry implements SettingEntry { readonly id: string; - readonly first: Node; + readonly first: INode; - readonly designer: Designer; + readonly designer: IDesigner | undefined; readonly setters: Setters; disposeFunctions: any[] = []; - constructor(readonly editor: IPublicModelEditor, readonly nodes: Node[]) { + constructor(readonly editor: IPublicModelEditor, readonly nodes: INode[]) { if (!Array.isArray(nodes) || nodes.length < 1) { throw new ReferenceError('nodes should not be empty'); } this.id = generateSessionId(nodes); this.first = nodes[0]; - this.designer = this.first.document.designer; + this.designer = this.first.document?.designer; this.setters = editor.get('setters') as Setters; // setups @@ -229,7 +232,6 @@ export class SettingTopEntry implements SettingEntry { this.disposeFunctions = []; } - getProp(propName: string | number) { return this.get(propName); } diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 9600e8008..63fe094db 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -1,4 +1,13 @@ -import { makeObservable, obx, engineConfig, action, runWithGlobalEventOff, wrapWithEventSwitch, createModuleEventBus, IEventBus } from '@alilc/lowcode-editor-core'; +import { + makeObservable, + obx, + engineConfig, + action, + runWithGlobalEventOff, + wrapWithEventSwitch, + createModuleEventBus, + IEventBus, +} from '@alilc/lowcode-editor-core'; import { IPublicTypeNodeData, IPublicTypeNodeSchema, @@ -8,20 +17,32 @@ import { IPublicTypeDragNodeObject, IPublicTypeDragNodeDataObject, IPublicModelDocumentModel, - IPublicModelHistory, - IPublicModelNode, IPublicEnumTransformStage, IPublicTypeOnChangeOptions, + IPublicTypeDisposable, } from '@alilc/lowcode-types'; +import { + IDropLocation, +} from '@alilc/lowcode-designer'; +import { + uniqueId, + isPlainObject, + compatStage, + isJSExpression, + isDOMText, + isNodeSchema, + isDragNodeObject, + isDragNodeDataObject, + isNode, +} from '@alilc/lowcode-utils'; import { IProject, Project } from '../project'; import { ISimulatorHost } from '../simulator'; -import { ComponentMeta } from '../component-meta'; -import { IDropLocation, Designer, IHistory } from '../designer'; -import { Node, insertChildren, insertChild, RootNode, INode } from './node/node'; +import { IComponentMeta } from '../component-meta'; +import { IDesigner, IHistory } from '../designer'; +import { insertChildren, insertChild, RootNode, INode } from './node/node'; import { Selection, ISelection } from './selection'; import { History } from './history'; -import { IModalNodesManager, ModalNodesManager } from './node'; -import { uniqueId, isPlainObject, compatStage, isJSExpression, isDOMText, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isNode } from '@alilc/lowcode-utils'; +import { IModalNodesManager, ModalNodesManager, Node } from './node'; import { EDITOR_EVENT } from '../types'; export type GetDataType = T extends undefined @@ -32,21 +53,39 @@ export type GetDataType = T extends undefined : any : T; -export interface IDocumentModel extends Omit< IPublicModelDocumentModel, 'selection' | 'checkNesting' > { +export interface IDocumentModel extends Omit< IPublicModelDocumentModel< + ISelection, + IHistory, + INode | RootNode, + IDropLocation, + IModalNodesManager, + IProject +>, + 'detecting' | + 'checkNesting' | + 'getNodeById' | + // 以下属性在内部的 document 中不存在 + 'exportSchema' | + 'importSchema' | + 'onAddNode' | + 'onRemoveNode' | + 'onChangeDetecting' | + 'onChangeSelection' | + 'onMountNode' | + 'onChangeNodeProp' | + 'onImportSchema' | + 'isDetectingNode' | + 'onFocusNodeChanged' | + 'onDropLocationChanged' +> { - readonly designer: Designer; + readonly designer: IDesigner; - /** - * 选区控制 - */ - readonly selection: ISelection; + get rootNode(): INode | null; - readonly project: IProject; + get simulator(): ISimulatorHost | null; - /** - * 模态节点管理 - */ - readonly modalNodesManager: IModalNodesManager; + get active(): boolean; /** * 根据 id 获取节点 @@ -55,16 +94,26 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel, 'select getHistory(): IHistory; - get focusNode(): INode | null; - - get rootNode(): INode | null; - checkNesting( dropTarget: INode, dragObject: IPublicTypeDragNodeObject | IPublicTypeNodeSchema | INode | IPublicTypeDragNodeDataObject, ): boolean; getNodeCount(): number; + + nextId(possibleId: string | undefined): string; + + import(schema: IPublicTypeRootSchema, checkId?: boolean): void; + + export(stage: IPublicEnumTransformStage): IPublicTypeRootSchema | undefined; + + onNodeCreate(func: (node: INode) => void): IPublicTypeDisposable; + + onNodeDestroy(func: (node: INode) => void): IPublicTypeDisposable; + + onChangeNodeVisible(fn: (node: INode, visible: boolean) => void): IPublicTypeDisposable; + + addWillPurge(node: INode): void; } export class DocumentModel implements IDocumentModel { @@ -86,20 +135,20 @@ export class DocumentModel implements IDocumentModel { /** * 操作记录控制 */ - readonly history: IPublicModelHistory; + readonly history: IHistory; /** * 模态节点管理 */ - readonly modalNodesManager: IModalNodesManager; + modalNodesManager: IModalNodesManager; - private _nodesMap = new Map(); + private _nodesMap = new Map(); readonly project: IProject; - readonly designer: Designer; + readonly designer: IDesigner; - @obx.shallow private nodes = new Set(); + @obx.shallow private nodes = new Set(); private seqId = 0; @@ -119,7 +168,7 @@ export class DocumentModel implements IDocumentModel { return this.project.simulator; } - get nodesMap(): Map { + get nodesMap(): Map { return this._nodesMap; } @@ -131,7 +180,7 @@ export class DocumentModel implements IDocumentModel { this.rootNode?.getExtraProp('fileName', true)?.setValue(fileName); } - get focusNode(): INode { + get focusNode(): INode | null { if (this._drillDownNode) { return this._drillDownNode; } @@ -142,7 +191,7 @@ export class DocumentModel implements IDocumentModel { return this.rootNode; } - @obx.ref private _drillDownNode: Node | null = null; + @obx.ref private _drillDownNode: INode | null = null; private _modalNode?: INode; @@ -150,7 +199,7 @@ export class DocumentModel implements IDocumentModel { private inited = false; - @obx.shallow private willPurgeSpace: Node[] = []; + @obx.shallow private willPurgeSpace: INode[] = []; get modalNode() { return this._modalNode; @@ -160,7 +209,7 @@ export class DocumentModel implements IDocumentModel { return this.modalNode || this.focusNode; } - @obx.shallow private activeNodes?: Node[]; + @obx.shallow private activeNodes?: INode[]; @obx.ref private _dropLocation: IDropLocation | null = null; @@ -236,7 +285,7 @@ export class DocumentModel implements IDocumentModel { // 兼容 vision this.id = project.getSchema()?.id || this.id; - this.rootNode = this.createNode( + this.rootNode = this.createNode( schema || { componentName: 'Page', id: 'root', @@ -257,11 +306,11 @@ export class DocumentModel implements IDocumentModel { this.inited = true; } - drillDown(node: Node | null) { + drillDown(node: INode | null) { this._drillDownNode = node; } - onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): () => void { + onChangeNodeVisible(fn: (node: INode, visible: boolean) => void): IPublicTypeDisposable { this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_CHILDREN_CHANGE, fn); return () => { @@ -269,7 +318,7 @@ export class DocumentModel implements IDocumentModel { }; } - onChangeNodeChildren(fn: (info: IPublicTypeOnChangeOptions) => void): () => void { + onChangeNodeChildren(fn: (info: IPublicTypeOnChangeOptions) => void): IPublicTypeDisposable { this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_VISIBLE_CHANGE, fn); return () => { @@ -277,11 +326,11 @@ export class DocumentModel implements IDocumentModel { }; } - addWillPurge(node: Node) { + addWillPurge(node: INode) { this.willPurgeSpace.push(node); } - removeWillPurge(node: Node) { + removeWillPurge(node: INode) { const i = this.willPurgeSpace.indexOf(node); if (i > -1) { this.willPurgeSpace.splice(i, 1); @@ -295,7 +344,7 @@ export class DocumentModel implements IDocumentModel { /** * 生成唯一 id */ - nextId(possibleId: string | undefined) { + nextId(possibleId: string | undefined): string { let id = possibleId; while (!id || this.nodesMap.get(id)) { id = `node_${(String(this.id).slice(-10) + (++this.seqId).toString(36)).toLocaleLowerCase()}`; @@ -330,7 +379,7 @@ export class DocumentModel implements IDocumentModel { * 根据 schema 创建一个节点 */ @action - createNode(data: GetDataType, checkId: boolean = true): T { + createNode(data: GetDataType, checkId: boolean = true): T { let schema: any; if (isDOMText(data) || isJSExpression(data)) { schema = { @@ -341,7 +390,7 @@ export class DocumentModel implements IDocumentModel { schema = data; } - let node: Node | null = null; + let node: INode | null = null; if (this.hasNode(schema?.id)) { schema.id = null; } @@ -373,30 +422,30 @@ export class DocumentModel implements IDocumentModel { return node as any; } - public destroyNode(node: Node) { + public destroyNode(node: INode) { this.emitter.emit('nodedestroy', node); } /** * 插入一个节点 */ - insertNode(parent: INode, thing: Node | IPublicTypeNodeData, at?: number | null, copy?: boolean): Node { + insertNode(parent: INode, thing: INode | IPublicTypeNodeData, at?: number | null, copy?: boolean): INode { return insertChild(parent, thing, at, copy); } /** * 插入多个节点 */ - insertNodes(parent: INode, thing: Node[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean) { + insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean) { return insertChildren(parent, thing, at, copy); } /** * 移除一个节点 */ - removeNode(idOrNode: string | Node) { + removeNode(idOrNode: string | INode) { let id: string; - let node: Node | null; + let node: INode | null; if (typeof idOrNode === 'string') { id = idOrNode; node = this.getNode(id); @@ -413,14 +462,14 @@ export class DocumentModel implements IDocumentModel { /** * 内部方法,请勿调用 */ - internalRemoveAndPurgeNode(node: Node, useMutator = false) { + internalRemoveAndPurgeNode(node: INode, useMutator = false) { if (!this.nodes.has(node)) { return; } node.remove(useMutator); } - unlinkNode(node: Node) { + unlinkNode(node: INode) { this.nodes.delete(node); this._nodesMap.delete(node.id); } @@ -428,7 +477,7 @@ export class DocumentModel implements IDocumentModel { /** * 包裹当前选区中的节点 */ - wrapWith(schema: IPublicTypeNodeSchema): Node | null { + wrapWith(schema: IPublicTypeNodeSchema): INode | null { const nodes = this.selection.getTopNodes(); if (nodes.length < 1) { return null; @@ -465,17 +514,17 @@ export class DocumentModel implements IDocumentModel { }); } - export(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Serilize) { + export(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Serilize): IPublicTypeRootSchema | undefined { stage = compatStage(stage); // 置顶只作用于 Page 的第一级子节点,目前还用不到里层的置顶;如果后面有需要可以考虑将这段写到 node-children 中的 export - const currentSchema = this.rootNode?.export(stage); - if (Array.isArray(currentSchema?.children) && currentSchema?.children.length > 0) { - const FixedTopNodeIndex = currentSchema.children + const currentSchema = this.rootNode?.export(stage); + if (Array.isArray(currentSchema?.children) && currentSchema?.children?.length && currentSchema?.children?.length > 0) { + const FixedTopNodeIndex = currentSchema?.children .filter(i => isPlainObject(i)) .findIndex((i => (i as IPublicTypeNodeSchema).props?.__isTopFixed__)); if (FixedTopNodeIndex > 0) { - const FixedTopNode = currentSchema.children.splice(FixedTopNodeIndex, 1); - currentSchema.children.unshift(FixedTopNode[0]); + const FixedTopNode = currentSchema?.children.splice(FixedTopNodeIndex, 1); + currentSchema?.children.unshift(FixedTopNode[0]); } } return currentSchema; @@ -504,7 +553,7 @@ export class DocumentModel implements IDocumentModel { return this.simulator!.getComponent(componentName); } - getComponentMeta(componentName: string): ComponentMeta { + getComponentMeta(componentName: string): IComponentMeta { return this.designer.getComponentMeta( componentName, () => this.simulator?.generateComponentMetadata(componentName) || null, @@ -579,10 +628,10 @@ export class DocumentModel implements IDocumentModel { dropTarget: INode, dragObject: IPublicTypeDragNodeObject | IPublicTypeNodeSchema | INode | IPublicTypeDragNodeDataObject, ): boolean { - let items: Array; + let items: Array; if (isDragNodeDataObject(dragObject)) { items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data]; - } else if (isDragNodeObject(dragObject)) { + } else if (isDragNodeObject(dragObject)) { items = dragObject.nodes; } else if (isNode(dragObject) || isNodeSchema(dragObject)) { items = [dragObject]; @@ -599,11 +648,13 @@ export class DocumentModel implements IDocumentModel { * Use checkNesting method instead. */ checkDropTarget(dropTarget: INode, dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject): boolean { - let items: Array; + let items: Array; if (isDragNodeDataObject(dragObject)) { items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data]; - } else { + } else if (isDragNodeObject(dragObject)) { items = dragObject.nodes; + } else { + return false; } return items.every((item) => this.checkNestingUp(dropTarget, item)); } @@ -611,7 +662,7 @@ export class DocumentModel implements IDocumentModel { /** * 检查对象对父级的要求,涉及配置 parentWhitelist */ - checkNestingUp(parent: INode, obj: IPublicTypeNodeSchema | Node): boolean { + checkNestingUp(parent: INode, obj: IPublicTypeNodeSchema | INode): boolean { if (isNode(obj) || isNodeSchema(obj)) { const config = isNode(obj) ? obj.componentMeta : this.getComponentMeta(obj.componentName); if (config) { @@ -625,7 +676,7 @@ export class DocumentModel implements IDocumentModel { /** * 检查投放位置对子级的要求,涉及配置 childWhitelist */ - checkNestingDown(parent: INode, obj: IPublicTypeNodeSchema | Node): boolean { + checkNestingDown(parent: INode, obj: IPublicTypeNodeSchema | INode): boolean { const config = parent.componentMeta; return config.checkNestingDown(parent, obj); } @@ -666,7 +717,9 @@ export class DocumentModel implements IDocumentModel { */ /* istanbul ignore next */ exportAddonData() { - const addons = {}; + const addons: { + [key: string]: any; + } = {}; this._addons.forEach((addon) => { const data = addon.exportData(); if (data === null) { diff --git a/packages/designer/src/document/node/modal-nodes-manager.ts b/packages/designer/src/document/node/modal-nodes-manager.ts index 585b52f5f..8e04f72fc 100644 --- a/packages/designer/src/document/node/modal-nodes-manager.ts +++ b/packages/designer/src/document/node/modal-nodes-manager.ts @@ -1,9 +1,9 @@ -import { INode, Node } from './node'; +import { INode } from './node'; import { DocumentModel } from '../document-model'; import { IPublicModelModalNodesManager } from '@alilc/lowcode-types'; import { createModuleEventBus, IEventBus } from '@alilc/lowcode-editor-core'; -export function getModalNodes(node: INode | Node) { +export function getModalNodes(node: INode) { if (!node) return []; let nodes: any = []; if (node.componentMeta.isModal) { @@ -18,11 +18,7 @@ export function getModalNodes(node: INode | Node) { return nodes; } -export interface IModalNodesManager extends IPublicModelModalNodesManager { - - getModalNodes(): INode[]; - - getVisibleModalNode(): INode | null; +export interface IModalNodesManager extends IPublicModelModalNodesManager { } export class ModalNodesManager implements IModalNodesManager { diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 12a9e75ba..ff85b2231 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -10,7 +10,12 @@ export interface IOnChangeOptions { node: Node; } -export interface INodeChildren extends Omit { +export interface INodeChildren extends Omit, + 'importSchema' | + 'exportSchema' | + 'isEmpty' | + 'notEmpty' +> { get owner(): INode; unlinkChild(node: INode): void; @@ -42,31 +47,17 @@ export interface INodeChildren extends Omit void): void; - map(fn: (item: INode, index: number) => T): T[] | null; - - every(fn: (item: INode, index: number) => any): boolean; - - some(fn: (item: INode, index: number) => any): boolean; - - filter(fn: (item: INode, index: number) => any): any; - - find(fn: (item: INode, index: number) => boolean): any; - - reduce(fn: (acc: any, cur: INode) => any, initialValue: any): void; - - reverse(): INode[]; - - mergeChildren( - remover: (node: INode, idx: number) => boolean, - adder: (children: INode[]) => IPublicTypeNodeData[] | null, - sorter: (firstNode: INode, secondNode: INode) => number, - ): any; - /** * 根据索引获得节点 */ get(index: number): INode | null; + isEmpty(): boolean; + + notEmpty(): boolean; + + internalInitParent(): void; + /** overriding methods end */ } export class NodeChildren implements INodeChildren { @@ -140,12 +131,12 @@ export class NodeChildren implements INodeChildren { const child = originChildren[i]; const item = data[i]; - let node: Node | undefined; + let node: INode | undefined | null; if (isNodeSchema(item) && !checkId && child && child.componentName === item.componentName) { node = child; node.import(item); } else { - node = this.owner.document.createNode(item, checkId); + node = this.owner.document?.createNode(item, checkId); } children[i] = node; } @@ -436,7 +427,7 @@ export class NodeChildren implements INodeChildren { return this.children.filter(fn); } - find(fn: (item: INode, index: number) => boolean) { + find(fn: (item: INode, index: number) => boolean): INode | undefined { return this.children.find(fn); } @@ -471,7 +462,7 @@ export class NodeChildren implements INodeChildren { const items = adder(this.children); if (items && items.length > 0) { items.forEach((child: IPublicTypeNodeData) => { - const node = this.owner.document?.createNode(child); + const node: INode = this.owner.document?.createNode(child); this.children.push(node); node.internalSetParent(this.owner); }); diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 7739bcf1c..efa860c8d 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -16,9 +16,10 @@ import { IPublicModelExclusiveGroup, IPublicEnumTransformStage, IPublicTypeDisposable, + IBaseModelNode, } from '@alilc/lowcode-types'; import { compatStage, isDOMText, isJSExpression, isNode } from '@alilc/lowcode-utils'; -import { SettingTopEntry } from '@alilc/lowcode-designer'; +import { ISettingTopEntry, SettingTopEntry } from '@alilc/lowcode-designer'; import { Props, getConvertedExtraKey, IProps } from './props/props'; import { DocumentModel, IDocumentModel } from '../document-model'; import { NodeChildren, INodeChildren } from './node-children'; @@ -36,28 +37,38 @@ export interface NodeStatus { inPlaceEditing: boolean; } -export interface INode extends IPublicModelNode { - - /** - * 当前节点子集 - */ - get children(): INodeChildren | null; - - /** - * 获取上一个兄弟节点 - */ - get prevSibling(): INode | null; - - /** - * 获取下一个兄弟节点 - */ - get nextSibling(): INode | null; - - /** - * 父级节点 - */ - get parent(): INode | null; - +export interface INode extends Omit, + 'slots' | + 'slotFor' | + 'props' | + 'getProp' | + 'getExtraProp' | + 'replaceChild' | + 'isRoot' | + 'isPage' | + 'isComponent' | + 'isModal' | + 'isSlot' | + 'isParental' | + 'isLeaf' | + 'settingEntry' | + // 在内部的 node 模型中不存在 + 'getExtraPropValue' | + 'setExtraPropValue' | + 'exportSchema' | + 'visible' | + 'importSchema' | + 'isEmptyNode' | + // 内外实现有差异 + 'isContainer' | + 'isEmpty' +> { get slots(): INode[]; /** @@ -69,7 +80,9 @@ export interface INode extends IPublicModelNode { get componentMeta(): IComponentMeta; - get document(): IDocumentModel; + get settingEntry(): SettingTopEntry; + + get isPurged(): boolean; setVisible(flag: boolean): void; @@ -79,7 +92,7 @@ export interface INode extends IPublicModelNode { * 内部方法,请勿使用 * @param useMutator 是否触发联动逻辑 */ - internalSetParent(parent: INode | null, useMutator: boolean): void; + internalSetParent(parent: INode | null, useMutator?: boolean): void; setConditionGroup(grp: IPublicModelExclusiveGroup | string | null): void; @@ -89,12 +102,10 @@ export interface INode extends IPublicModelNode { unlinkSlot(slotNode: Node): void; - didDropOut(dragment: Node): void; - /** * 导出 schema */ - export(stage: IPublicEnumTransformStage, options?: any): IPublicTypeNodeSchema; + export(stage: IPublicEnumTransformStage, options?: any): T; emitPropChange(val: IPublicTypePropChangeOptions): void; @@ -117,6 +128,38 @@ export interface INode extends IPublicModelNode { onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable; onPropChange(func: (info: IPublicTypePropChangeOptions) => void): IPublicTypeDisposable; + + isModal(): boolean; + + isRoot(): boolean; + + isPage(): boolean; + + isComponent(): boolean; + + isSlot(): boolean; + + isParental(): boolean; + + isLeaf(): boolean; + + isContainer(): boolean; + + isEmpty(): boolean; + + remove( + useMutator?: boolean, + purge?: boolean, + options?: NodeRemoveOptions, + ): void; + + didDropIn(dragment: Node): void; + + didDropOut(dragment: Node): void; + + get isPurging(): boolean; + + purge(): void; } /** @@ -251,9 +294,9 @@ export class Node isInited = false; - _settingEntry: SettingTopEntry; + _settingEntry: ISettingTopEntry; - get settingEntry(): SettingTopEntry { + get settingEntry(): ISettingTopEntry { if (this._settingEntry) return this._settingEntry; this._settingEntry = this.document.designer.createSettingEntry([this]); return this._settingEntry; @@ -319,7 +362,7 @@ export class Node pseudo: false, }; - constructor(readonly document: IDocumentModel, nodeSchema: Schema, options: any = {}) { + constructor(readonly document: IDocumentModel, nodeSchema: Schema) { makeObservable(this); const { componentName, id, children, props, ...extras } = nodeSchema; this.id = document.nextId(id); @@ -347,7 +390,7 @@ export class Node this.onVisibleChange((visible: boolean) => { editor?.eventBus.emit(EDITOR_EVENT.NODE_VISIBLE_CHANGE, this, visible); }); - this.onChildrenChange((info?: { type: string; node: Node }) => { + this.onChildrenChange((info?: { type: string; node: INode }) => { editor?.eventBus.emit(EDITOR_EVENT.NODE_VISIBLE_CHANGE, info); }); } @@ -475,7 +518,7 @@ export class Node this.document.addWillPurge(this); } - private didDropIn(dragment: Node) { + didDropIn(dragment: Node) { const { callbacks } = this.componentMeta.advanced; if (callbacks?.onNodeAdd) { const cbThis = this.internalToShellNode(); @@ -486,7 +529,7 @@ export class Node } } - private didDropOut(dragment: Node) { + didDropOut(dragment: Node) { const { callbacks } = this.componentMeta.advanced; if (callbacks?.onNodeRemove) { const cbThis = this.internalToShellNode(); @@ -869,7 +912,7 @@ export class Node /** * 导出 schema */ - export(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save, options: any = {}): Schema { + export(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save, options: any = {}): T { stage = compatStage(stage); const baseSchema: any = { componentName: this.componentName, @@ -955,7 +998,7 @@ export class Node /** * 删除一个Slot节点 */ - removeSlot(slotNode: Node, purge = false): boolean { + removeSlot(slotNode: Node): boolean { // if (purge) { // // should set parent null // slotNode?.internalSetParent(null, false); @@ -1047,16 +1090,16 @@ export class Node return this.componentName; } - insert(node: Node, ref?: Node, useMutator = true) { + insert(node: Node, ref?: INode, useMutator = true) { this.insertAfter(node, ref, useMutator); } - insertBefore(node: Node, ref?: Node, useMutator = true) { + insertBefore(node: INode, ref?: INode, useMutator = true) { const nodeInstance = ensureNode(node, this.document); this.children?.internalInsert(nodeInstance, ref ? ref.index : null, useMutator); } - insertAfter(node: any, ref?: Node, useMutator = true) { + insertAfter(node: any, ref?: INode, useMutator = true) { const nodeInstance = ensureNode(node, this.document); this.children?.internalInsert(nodeInstance, ref ? ref.index + 1 : null, useMutator); } @@ -1085,15 +1128,15 @@ export class Node return this.props; } - onChildrenChange(fn: (param?: { type: string; node: Node }) => void): IPublicTypeDisposable { + onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable { const wrappedFunc = wrapWithEventSwitch(fn); return this.children?.onChange(wrappedFunc); } mergeChildren( - remover: () => any, - adder: (children: Node[]) => IPublicTypeNodeData[] | null, - sorter: () => any, + remover: (node: INode, idx: number) => any, + adder: (children: INode[]) => IPublicTypeNodeData[] | null, + sorter: (firstNode: INode, secondNode: INode) => any, ) { this.children?.mergeChildren(remover, adder, sorter); } diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 81675aa57..90d72668a 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -2,7 +2,7 @@ import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, r import { IPublicTypeCompositeValue, GlobalEvent, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicEnumTransformStage, IPublicModelProp } from '@alilc/lowcode-types'; import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot } from '@alilc/lowcode-utils'; import { valueToSource } from './value-to-source'; -import { Props, IProps, IPropParent } from './props'; +import { IProps, IPropParent } from './props'; import { SlotNode, INode } from '../node'; // import { TransformStage } from '../transform-stage'; @@ -13,7 +13,7 @@ export type UNSET = typeof UNSET; export interface IProp extends Omit { - readonly props: Props; + readonly props: IProps; readonly owner: INode; @@ -24,6 +24,8 @@ export interface IProp extends Omit { +export interface IProps extends Omit, | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'> { /** * 获取 props 对应的 node */ getNode(): INode; - getProp(path: string): IProp | null; + get(path: string, createIfNone?: boolean): Prop | null; - get(path: string, createIfNone: boolean): Prop; + export(stage?: IPublicEnumTransformStage): { + props?: IPublicTypePropsMap | IPublicTypePropsList; + extras?: ExtrasObject; + }; + + merge(value: IPublicTypePropsMap, extras?: IPublicTypePropsMap): void; } export class Props implements IProps, IPropParent { diff --git a/packages/designer/src/document/selection.ts b/packages/designer/src/document/selection.ts index bcbf778ea..2456de759 100644 --- a/packages/designer/src/document/selection.ts +++ b/packages/designer/src/document/selection.ts @@ -1,20 +1,10 @@ import { obx, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; -import { Node, INode, comparePosition, PositionNO } from './node/node'; +import { INode, comparePosition, PositionNO } from './node/node'; import { DocumentModel } from './document-model'; import { IPublicModelSelection } from '@alilc/lowcode-types'; -export interface ISelection extends Omit< IPublicModelSelection, 'getNodes' | 'getTopNodes' > { +export interface ISelection extends Omit, 'node'> { - /** - * 获取选中的节点实例 - * @returns - */ - getNodes(): INode[]; - - /** - * 获取顶层选区节点,场景:拖拽时,建立蒙层,只蒙在最上层 - */ - getTopNodes(includeRoot?: boolean): INode[]; } export class Selection implements ISelection { @@ -115,7 +105,7 @@ export class Selection implements ISelection { /** * 选区是否包含节点 */ - containsNode(node: Node, excludeRoot = false) { + containsNode(node: INode, excludeRoot = false) { for (const id of this._selected) { const parent = this.doc.getNode(id); if (excludeRoot && parent?.contains(this.doc.focusNode)) { @@ -131,8 +121,8 @@ export class Selection implements ISelection { /** * 获取选中的节点 */ - getNodes(): Node[] { - const nodes = []; + getNodes(): INode[] { + const nodes: INode[] = []; for (const id of this._selected) { const node = this.doc.getNode(id); if (node) { diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 42ba0b4fc..6516d67aa 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -12,13 +12,31 @@ import { import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils'; import { ISimulatorHost } from '../simulator'; -export interface IProject extends Omit< IPublicApiProject, 'simulatorHost' | 'importSchema' | 'exportSchema' | 'openDocument' | 'getDocumentById' | 'getCurrentDocument' | 'addPropsTransducer' | 'onRemoveDocument' | 'onChangeDocument' | 'onSimulatorHostReady' | 'onSimulatorRendererReady' | 'setI18n' > { +export interface IProject extends Omit< IPublicApiProject, + 'simulatorHost' | + 'importSchema' | + 'exportSchema' | + 'openDocument' | + 'getDocumentById' | + 'getCurrentDocument' | + 'addPropsTransducer' | + 'onRemoveDocument' | + 'onChangeDocument' | + 'onSimulatorHostReady' | + 'onSimulatorRendererReady' | + 'setI18n' | + 'currentDocument' | + 'selection' | + 'documents' | + 'createDocument' | + 'getDocumentByFileName' +> { get designer(): IDesigner; get simulator(): ISimulatorHost | null; - get currentDocument(): IDocumentModel | null; + get currentDocument(): IDocumentModel | null | undefined; get documents(): IDocumentModel[]; @@ -60,6 +78,8 @@ export interface IProject extends Omit< IPublicApiProject, 'simulatorHost' | 'im // eslint-disable-next-line @typescript-eslint/no-unused-vars value: any, ): void; + + checkExclusive(activeDoc: DocumentModel): void; } export class Project implements IProject { @@ -85,7 +105,7 @@ export class Project implements IProject { return this._simulator || null; } - @computed get currentDocument(): IDocumentModel | null { + @computed get currentDocument(): IDocumentModel | null | undefined { return this.documents.find((doc) => doc.active); } diff --git a/packages/designer/src/simulator.ts b/packages/designer/src/simulator.ts index 5a2fb8efc..32b9233c9 100644 --- a/packages/designer/src/simulator.ts +++ b/packages/designer/src/simulator.ts @@ -2,7 +2,7 @@ import { ComponentType } from 'react'; import { IPublicTypeComponentMetadata, IPublicTypeNodeSchema, IPublicTypeScrollable, IPublicTypeComponentInstance, IPublicModelSensor, IPublicTypeNodeInstance } from '@alilc/lowcode-types'; import { Point, ScrollTarget, ILocateEvent } from './designer'; import { BuiltinSimulatorRenderer } from './builtin-simulator/renderer'; -import { Node, INode } from './document'; +import { INode } from './document'; export type AutoFit = '100%'; // eslint-disable-next-line no-redeclare @@ -132,7 +132,7 @@ export interface ISimulatorHost

extends IPublicModelSensor { /** * 滚动视口到节点 */ - scrollToNode(node: Node, detail?: any): void; + scrollToNode(node: INode, detail?: any): void; /** * 描述组件 @@ -147,7 +147,7 @@ export interface ISimulatorHost

extends IPublicModelSensor { /** * 根据节点获取节点的组件实例 */ - getComponentInstances(node: Node): IPublicTypeComponentInstance[] | null; + getComponentInstances(node: INode): IPublicTypeComponentInstance[] | null; /** * 根据 schema 创建组件类 @@ -157,11 +157,11 @@ export interface ISimulatorHost

extends IPublicModelSensor { /** * 根据节点获取节点的组件运行上下文 */ - getComponentContext(node: Node): object | null; + getComponentContext(node: INode): object | null; getClosestNodeInstance(from: IPublicTypeComponentInstance, specId?: string): IPublicTypeNodeInstance | null; - computeRect(node: Node): DOMRect | null; + computeRect(node: INode): DOMRect | null; computeComponentInstanceRect(instance: IPublicTypeComponentInstance, selector?: string): DOMRect | null; @@ -189,6 +189,6 @@ export function isSimulatorHost(obj: any): obj is ISimulatorHost { export type Component = ComponentType | object; export interface INodeSelector { - node: Node; + node: INode; instance?: IPublicTypeComponentInstance; } diff --git a/packages/shell/src/model/document-model.ts b/packages/shell/src/model/document-model.ts index 85d44c2cc..b1015b8de 100644 --- a/packages/shell/src/model/document-model.ts +++ b/packages/shell/src/model/document-model.ts @@ -21,6 +21,7 @@ import { IPublicApiCanvas, IPublicTypeDisposable, IPublicModelEditor, + IPublicTypeNodeSchema, } from '@alilc/lowcode-types'; import { isDragNodeObject } from '@alilc/lowcode-utils'; import { Node as ShellNode } from './node'; @@ -195,7 +196,7 @@ export class DocumentModel implements IPublicModelDocumentModel { * @param data * @returns */ - createNode(data: any): IPublicModelNode | null { + createNode(data: IPublicTypeNodeSchema): IPublicModelNode | null { return ShellNode.create(this[documentSymbol].createNode(data)); } @@ -289,7 +290,7 @@ export class DocumentModel implements IPublicModelDocumentModel { * @param fn */ onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): IPublicTypeDisposable { - return this[documentSymbol].onChangeNodeVisible((node: IPublicModelNode, visible: boolean) => { + return this[documentSymbol].onChangeNodeVisible((node: InnerNode, visible: boolean) => { fn(ShellNode.create(node)!, visible); }); } diff --git a/packages/shell/src/model/node.ts b/packages/shell/src/model/node.ts index ba2412e89..9b407de5c 100644 --- a/packages/shell/src/model/node.ts +++ b/packages/shell/src/model/node.ts @@ -362,9 +362,9 @@ export class Node implements IPublicModelNode { * @param sorter */ mergeChildren( - remover: (node: IPublicModelNode, idx: number) => boolean, - adder: (children: IPublicModelNode[]) => any, - sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number, + remover: (node: Node, idx: number) => boolean, + adder: (children: Node[]) => any, + sorter: (firstNode: Node, secondNode: Node) => number, ): any { return this.children?.mergeChildren(remover, adder, sorter); } diff --git a/packages/shell/src/model/selection.ts b/packages/shell/src/model/selection.ts index ff2124bec..073083a65 100644 --- a/packages/shell/src/model/selection.ts +++ b/packages/shell/src/model/selection.ts @@ -1,14 +1,14 @@ import { IDocumentModel as InnerDocumentModel, INode as InnerNode, - ISelection as InnerSelection, + ISelection, } from '@alilc/lowcode-designer'; import { Node as ShellNode } from './node'; import { selectionSymbol } from '../symbols'; import { IPublicModelSelection, IPublicModelNode, IPublicTypeDisposable } from '@alilc/lowcode-types'; export class Selection implements IPublicModelSelection { - private readonly [selectionSymbol]: InnerSelection; + private readonly [selectionSymbol]: ISelection; constructor(document: InnerDocumentModel) { this[selectionSymbol] = document.selection; diff --git a/packages/types/src/shell/model/component-meta.ts b/packages/types/src/shell/model/component-meta.ts index 369680fd6..f2b0032a7 100644 --- a/packages/types/src/shell/model/component-meta.ts +++ b/packages/types/src/shell/model/component-meta.ts @@ -2,7 +2,9 @@ import { IPublicTypeNodeSchema, IPublicTypeNodeData, IPublicTypeIconType, IPubli import { ReactElement } from 'react'; import { IPublicModelNode } from './node'; -export interface IPublicModelComponentMeta { +export interface IPublicModelComponentMeta< + Node = IPublicModelNode +> { /** * 组件名 @@ -92,7 +94,7 @@ export interface IPublicModelComponentMeta { * @param my 当前节点 * @param parent 父节点 */ - checkNestingUp(my: IPublicModelNode | IPublicTypeNodeData, parent: any): boolean; + checkNestingUp(my: Node | IPublicTypeNodeData, parent: any): boolean; /** * 检测目标节点是否可被放置在父节点中 @@ -101,8 +103,8 @@ export interface IPublicModelComponentMeta { * @param parent 父节点 */ checkNestingDown( - my: IPublicModelNode | IPublicTypeNodeData, - target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[], + my: Node | IPublicTypeNodeData, + target: IPublicTypeNodeSchema | Node | IPublicTypeNodeSchema[], ): boolean; /** diff --git a/packages/types/src/shell/model/detecting.ts b/packages/types/src/shell/model/detecting.ts index 9bc215f9a..ec6320ad2 100644 --- a/packages/types/src/shell/model/detecting.ts +++ b/packages/types/src/shell/model/detecting.ts @@ -1,7 +1,7 @@ import { IPublicModelNode } from './'; import { IPublicTypeDisposable } from '../type'; -export interface IPublicModelDetecting { +export interface IPublicModelDetecting { /** * 是否启用 @@ -15,7 +15,7 @@ export interface IPublicModelDetecting { * get current hovering node * @since v1.0.16 */ - get current(): IPublicModelNode | null; + get current(): Node | null; /** * hover 指定节点 @@ -42,5 +42,5 @@ export interface IPublicModelDetecting { * set callback which will be called when hovering object changed. * @since v1.1.0 */ - onDetectingChange(fn: (node: IPublicModelNode | null) => void): IPublicTypeDisposable; + onDetectingChange(fn: (node: Node | null) => void): IPublicTypeDisposable; } diff --git a/packages/types/src/shell/model/document-model.ts b/packages/types/src/shell/model/document-model.ts index 72d20ceb0..99086d20d 100644 --- a/packages/types/src/shell/model/document-model.ts +++ b/packages/types/src/shell/model/document-model.ts @@ -2,15 +2,22 @@ import { IPublicTypeRootSchema, IPublicTypeDragNodeDataObject, IPublicTypeDragNo import { IPublicEnumTransformStage } from '../enum'; import { IPublicApiProject } from '../api'; import { IPublicModelDropLocation, IPublicModelDetecting, IPublicModelNode, IPublicModelSelection, IPublicModelHistory, IPublicModelModalNodesManager } from './'; -import { IPublicTypeOnChangeOptions } from '@alilc/lowcode-types'; +import { IPublicTypeNodeData, IPublicTypeNodeSchema, IPublicTypeOnChangeOptions } from '@alilc/lowcode-types'; -export interface IPublicModelDocumentModel { +export interface IPublicModelDocumentModel< + Selection = IPublicModelSelection, + History = IPublicModelHistory, + Node = IPublicModelNode, + DropLocation = IPublicModelDropLocation, + ModalNodesManager = IPublicModelModalNodesManager, + Project = IPublicApiProject +> { /** * 节点选中区模型实例 * instance of selection */ - selection: IPublicModelSelection; + selection: Selection; /** * 画布节点 hover 区模型实例 @@ -22,7 +29,7 @@ export interface IPublicModelDocumentModel { * 操作历史模型实例 * instance of history */ - history: IPublicModelHistory; + history: History; /** * id @@ -36,30 +43,30 @@ export interface IPublicModelDocumentModel { * get project which this documentModel belongs to * @returns */ - get project(): IPublicApiProject; + get project(): Project; /** * 获取文档的根节点 * root node of this documentModel * @returns */ - get root(): IPublicModelNode | null; + get root(): Node | null; - get focusNode(): IPublicModelNode | null; + get focusNode(): Node | null; - set focusNode(node: IPublicModelNode | null); + set focusNode(node: Node | null); /** * 获取文档下所有节点 * @returns */ - get nodesMap(): Map; + get nodesMap(): Map; /** * 模态节点管理 * get instance of modalNodesManager */ - get modalNodesManager(): IPublicModelModalNodesManager | null; + get modalNodesManager(): ModalNodesManager | null; /** * 根据 nodeId 返回 Node 实例 @@ -67,7 +74,7 @@ export interface IPublicModelDocumentModel { * @param nodeId * @returns */ - getNodeById(nodeId: string): IPublicModelNode | null; + getNodeById(nodeId: string): Node | null; /** * 导入 schema @@ -89,11 +96,11 @@ export interface IPublicModelDocumentModel { * insert a node */ insertNode( - parent: IPublicModelNode, - thing: IPublicModelNode, + parent: Node, + thing: Node | IPublicTypeNodeData, at?: number | null | undefined, copy?: boolean | undefined - ): IPublicModelNode | null; + ): Node | null; /** * 创建一个节点 @@ -101,14 +108,14 @@ export interface IPublicModelDocumentModel { * @param data * @returns */ - createNode(data: any): IPublicModelNode | null; + createNode(data: IPublicTypeNodeSchema): Node | null; /** * 移除指定节点/节点id * remove a node by node instance or nodeId * @param idOrNode */ - removeNode(idOrNode: string | IPublicModelNode): void; + removeNode(idOrNode: string | Node): void; /** * componentsMap of documentModel @@ -126,7 +133,7 @@ export interface IPublicModelDocumentModel { * @since v1.0.16 */ checkNesting( - dropTarget: IPublicModelNode, + dropTarget: Node, dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject ): boolean; @@ -134,26 +141,26 @@ export interface IPublicModelDocumentModel { * 当前 document 新增节点事件 * set callback for event on node is created for a document */ - onAddNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; + onAddNode(fn: (node: Node) => void): IPublicTypeDisposable; /** * 当前 document 新增节点事件,此时节点已经挂载到 document 上 * set callback for event on node is mounted to canvas */ - onMountNode(fn: (payload: { node: IPublicModelNode }) => void): IPublicTypeDisposable; + onMountNode(fn: (payload: { node: Node }) => void): IPublicTypeDisposable; /** * 当前 document 删除节点事件 * set callback for event on node is removed */ - onRemoveNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; + onRemoveNode(fn: (node: Node) => void): IPublicTypeDisposable; /** * 当前 document 的 hover 变更事件 * * set callback for event on detecting changed */ - onChangeDetecting(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; + onChangeDetecting(fn: (node: Node) => void): IPublicTypeDisposable; /** * 当前 document 的选中变更事件 @@ -166,7 +173,7 @@ export interface IPublicModelDocumentModel { * set callback for event on visibility changed for certain node * @param fn */ - onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): IPublicTypeDisposable; + onChangeNodeVisible(fn: (node: Node, visible: boolean) => void): IPublicTypeDisposable; /** * 当前 document 的节点 children 变更事件 @@ -193,21 +200,21 @@ export interface IPublicModelDocumentModel { * @param node * @since v1.1.0 */ - isDetectingNode(node: IPublicModelNode): boolean; + isDetectingNode(node: Node): boolean; /** * 获取当前的 DropLocation 信息 * get current drop location * @since v1.1.0 */ - get dropLocation(): IPublicModelDropLocation | null; + get dropLocation(): DropLocation | null; /** * 设置当前的 DropLocation 信息 * set current drop location * @since v1.1.0 */ - set dropLocation(loc: IPublicModelDropLocation | null); + set dropLocation(loc: DropLocation | null); /** * 设置聚焦节点变化的回调 @@ -216,7 +223,7 @@ export interface IPublicModelDocumentModel { * @since v1.1.0 */ onFocusNodeChanged( - fn: (doc: IPublicModelDocumentModel, focusNode: IPublicModelNode) => void, + fn: (doc: IPublicModelDocumentModel, focusNode: Node) => void, ): IPublicTypeDisposable; /** diff --git a/packages/types/src/shell/model/modal-nodes-manager.ts b/packages/types/src/shell/model/modal-nodes-manager.ts index bfbba50ec..07656c070 100644 --- a/packages/types/src/shell/model/modal-nodes-manager.ts +++ b/packages/types/src/shell/model/modal-nodes-manager.ts @@ -1,6 +1,6 @@ import { IPublicModelNode } from './'; -export interface IPublicModelModalNodesManager { +export interface IPublicModelModalNodesManager { /** * 设置模态节点,触发内部事件 @@ -12,13 +12,13 @@ export interface IPublicModelModalNodesManager { * 获取模态节点(们) * get modal nodes */ - getModalNodes(): IPublicModelNode[]; + getModalNodes(): Node[]; /** * 获取当前可见的模态节点 * get current visible modal node */ - getVisibleModalNode(): IPublicModelNode | null; + getVisibleModalNode(): Node | null; /** * 隐藏模态节点(们) @@ -31,12 +31,12 @@ export interface IPublicModelModalNodesManager { * set specfic model node as visible * @param node Node */ - setVisible(node: IPublicModelNode): void; + setVisible(node: Node): void; /** * 设置指定节点为不可见态 * set specfic model node as invisible * @param node Node */ - setInvisible(node: IPublicModelNode): void; + setInvisible(node: Node): void; } diff --git a/packages/types/src/shell/model/node-children.ts b/packages/types/src/shell/model/node-children.ts index 0379194bf..ecab5fd33 100644 --- a/packages/types/src/shell/model/node-children.ts +++ b/packages/types/src/shell/model/node-children.ts @@ -2,13 +2,15 @@ import { IPublicTypeNodeSchema, IPublicTypeNodeData } from '../type'; import { IPublicEnumTransformStage } from '../enum'; import { IPublicModelNode } from './'; -export interface IPublicModelNodeChildren { +export interface IPublicModelNodeChildren< + Node = IPublicModelNode +> { /** * 返回当前 children 实例所属的节点实例 * get owner node of this nodeChildren */ - get owner(): IPublicModelNode | null; + get owner(): Node | null; /** * children 内的节点实例数 @@ -45,7 +47,7 @@ export interface IPublicModelNodeChildren { * delete the node * @param node */ - delete(node: IPublicModelNode): boolean; + delete(node: Node): boolean; /** * 插入一个节点 @@ -54,7 +56,7 @@ export interface IPublicModelNodeChildren { * @param at 插入下标 * @returns */ - insert(node: IPublicModelNode, at?: number | null): void; + insert(node: Node, at?: number | null): void; /** * 返回指定节点的下标 @@ -62,7 +64,7 @@ export interface IPublicModelNodeChildren { * @param node * @returns */ - indexOf(node: IPublicModelNode): number; + indexOf(node: Node): number; /** * 类似数组 splice 操作 @@ -71,7 +73,7 @@ export interface IPublicModelNodeChildren { * @param deleteCount * @param node */ - splice(start: number, deleteCount: number, node?: IPublicModelNode): any; + splice(start: number, deleteCount: number, node?: Node): any; /** * 返回指定下标的节点 @@ -79,7 +81,7 @@ export interface IPublicModelNodeChildren { * @param index * @returns */ - get(index: number): IPublicModelNode | null; + get(index: number): Node | null; /** * 是否包含指定节点 @@ -87,62 +89,62 @@ export interface IPublicModelNodeChildren { * @param node * @returns */ - has(node: IPublicModelNode): boolean; + has(node: Node): boolean; /** * 类似数组的 forEach * provide the same function with {Array.prototype.forEach} * @param fn */ - forEach(fn: (node: IPublicModelNode, index: number) => void): void; + forEach(fn: (node: Node, index: number) => void): void; /** * 类似数组的 reverse * provide the same function with {Array.prototype.reverse} */ - reverse(): IPublicModelNode[]; + reverse(): Node[]; /** * 类似数组的 map * provide the same function with {Array.prototype.map} * @param fn */ - map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null; + map(fn: (node: Node, index: number) => T): T[] | null; /** * 类似数组的 every * provide the same function with {Array.prototype.every} * @param fn */ - every(fn: (node: IPublicModelNode, index: number) => boolean): boolean; + every(fn: (node: Node, index: number) => boolean): boolean; /** * 类似数组的 some * provide the same function with {Array.prototype.some} * @param fn */ - some(fn: (node: IPublicModelNode, index: number) => boolean): boolean; + some(fn: (node: Node, index: number) => boolean): boolean; /** * 类似数组的 filter * provide the same function with {Array.prototype.filter} * @param fn */ - filter(fn: (node: IPublicModelNode, index: number) => boolean): any; + filter(fn: (node: Node, index: number) => boolean): any; /** * 类似数组的 find * provide the same function with {Array.prototype.find} * @param fn */ - find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null; + find(fn: (node: Node, index: number) => boolean): Node | null | undefined; /** * 类似数组的 reduce * provide the same function with {Array.prototype.reduce} * @param fn */ - reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void; + reduce(fn: (acc: any, cur: Node) => any, initialValue: any): void; /** * 导入 schema @@ -166,9 +168,9 @@ export interface IPublicModelNodeChildren { * @param sorter */ mergeChildren( - remover: (node: IPublicModelNode, idx: number) => boolean, - adder: (children: IPublicModelNode[]) => IPublicTypeNodeData[] | null, - sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number + remover: (node: Node, idx: number) => boolean, + adder: (children: Node[]) => IPublicTypeNodeData[] | null, + sorter: (firstNode: Node, secondNode: Node) => number ): any; } diff --git a/packages/types/src/shell/model/node.ts b/packages/types/src/shell/model/node.ts index 70c92016b..dd6db71bf 100644 --- a/packages/types/src/shell/model/node.ts +++ b/packages/types/src/shell/model/node.ts @@ -3,7 +3,13 @@ import { IPublicTypeNodeSchema, IPublicTypeIconType, IPublicTypeI18nData, IPubli import { IPublicEnumTransformStage } from '../enum'; import { IPublicModelNodeChildren, IPublicModelComponentMeta, IPublicModelProp, IPublicModelProps, IPublicModelSettingTopEntry, IPublicModelDocumentModel, IPublicModelExclusiveGroup } from './'; -export interface IPublicModelNode { +export interface IBaseModelNode< + Document = IPublicModelDocumentModel, + Node = IPublicModelNode, + NodeChildren = IPublicModelNodeChildren, + ComponentMeta = IPublicModelComponentMeta, + SettingTopEntry = IPublicModelSettingTopEntry +> { /** * 节点 id @@ -185,43 +191,43 @@ export interface IPublicModelNode { * 节点的物料元数据 * get component meta of this node */ - get componentMeta(): IPublicModelComponentMeta | null; + get componentMeta(): ComponentMeta | null; /** * 获取节点所属的文档模型对象 * get documentModel of this node */ - get document(): IPublicModelDocumentModel | null; + get document(): Document | null; /** * 获取当前节点的前一个兄弟节点 * get previous sibling of this node */ - get prevSibling(): IPublicModelNode | null; + get prevSibling(): Node | null; /** * 获取当前节点的后一个兄弟节点 * get next sibling of this node */ - get nextSibling(): IPublicModelNode | null; + get nextSibling(): Node | null; /** * 获取当前节点的父亲节点 * get parent of this node */ - get parent(): IPublicModelNode | null; + get parent(): Node | null; /** * 获取当前节点的孩子节点模型 * get children of this node */ - get children(): IPublicModelNodeChildren | null; + get children(): NodeChildren | null; /** * 节点上挂载的插槽节点们 * get slots of this node */ - get slots(): IPublicModelNode[]; + get slots(): Node[]; /** * 当前节点为插槽节点时,返回节点对应的属性实例 @@ -258,7 +264,7 @@ export interface IPublicModelNode { * get setting entry of this node * @since v1.1.0 */ - get settingEntry(): IPublicModelSettingTopEntry; + get settingEntry(): SettingTopEntry; /** * 返回节点的尺寸、位置信息 @@ -359,8 +365,8 @@ export interface IPublicModelNode { * @param useMutator */ insertBefore( - node: IPublicModelNode, - ref?: IPublicModelNode | undefined, + node: Node, + ref?: Node | undefined, useMutator?: boolean, ): void; @@ -372,8 +378,8 @@ export interface IPublicModelNode { * @param useMutator */ insertAfter( - node: IPublicModelNode, - ref?: IPublicModelNode | undefined, + node: Node, + ref?: Node | undefined, useMutator?: boolean, ): void; @@ -384,7 +390,7 @@ export interface IPublicModelNode { * @param data 用作替换的节点对象或者节点描述 * @returns */ - replaceChild(node: IPublicModelNode, data: any): IPublicModelNode | null; + replaceChild(node: Node, data: any): Node | null; /** * 将当前节点替换成指定节点描述 @@ -427,9 +433,9 @@ export interface IPublicModelNode { * @since v1.1.0 */ mergeChildren( - remover: (node: IPublicModelNode, idx: number) => boolean, - adder: (children: IPublicModelNode[]) => any, - sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number + remover: (node: Node, idx: number) => boolean, + adder: (children: Node[]) => any, + sorter: (firstNode: Node, secondNode: Node) => number ): any; /** @@ -438,7 +444,7 @@ export interface IPublicModelNode { * @param node * @since v1.1.0 */ - contains(node: IPublicModelNode): boolean; + contains(node: Node): boolean; /** * 是否可执行某 action @@ -476,3 +482,5 @@ export interface IPublicModelNode { */ setConditionalVisible(): void; } + +export interface IPublicModelNode extends IBaseModelNode {} \ No newline at end of file diff --git a/packages/types/src/shell/model/props.ts b/packages/types/src/shell/model/props.ts index 9c862a008..3c390a8cf 100644 --- a/packages/types/src/shell/model/props.ts +++ b/packages/types/src/shell/model/props.ts @@ -1,7 +1,9 @@ import { IPublicTypeCompositeValue } from '../type'; -import { IPublicModelNode, IPublicModelProp } from './'; +import { IPublicModelNode } from './'; -export interface IPublicModelProps { +export interface IBaseModelProps< + Prop +> { /** * id @@ -24,7 +26,7 @@ export interface IPublicModelProps { * get prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ - getProp(path: string): IPublicModelProp | null; + getProp(path: string): Prop | null; /** * 获取指定 path 的属性模型实例值 @@ -39,7 +41,7 @@ export interface IPublicModelProps { * get extra prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ - getExtraProp(path: string): IPublicModelProp | null; + getExtraProp(path: string): Prop | null; /** * 获取指定 path 的属性模型实例值 @@ -83,3 +85,5 @@ export interface IPublicModelProps { add(value: IPublicTypeCompositeValue, key?: string | number | undefined): any; } + +export type IPublicModelProps = IBaseModelProps; \ No newline at end of file diff --git a/packages/types/src/shell/model/selection.ts b/packages/types/src/shell/model/selection.ts index 3b2fdb2f5..317a49837 100644 --- a/packages/types/src/shell/model/selection.ts +++ b/packages/types/src/shell/model/selection.ts @@ -1,7 +1,9 @@ import { IPublicModelNode } from './'; import { IPublicTypeDisposable } from '../type'; -export interface IPublicModelSelection { +export interface IPublicModelSelection< + Node = IPublicModelNode +> { /** * 返回选中的节点 id @@ -14,7 +16,7 @@ export interface IPublicModelSelection { * return selected Node instance,return the first one if multiple nodes are selected * @since v1.1.0 */ - get node(): IPublicModelNode | null; + get node(): Node | null; /** * 选中指定节点(覆盖方式) @@ -62,7 +64,7 @@ export interface IPublicModelSelection { * 获取选中的节点实例 * get selected nodes */ - getNodes(): IPublicModelNode[]; + getNodes(): Node[]; /** * 获取选区的顶层节点 @@ -72,7 +74,7 @@ export interface IPublicModelSelection { * getTopNodes() will return [A, B], subA will be removed * @since v1.0.16 */ - getTopNodes(includeRoot?: boolean): IPublicModelNode[]; + getTopNodes(includeRoot?: boolean): Node[]; /** * 注册 selection 变化事件回调 diff --git a/packages/types/src/shell/type/drag-node-object.ts b/packages/types/src/shell/type/drag-node-object.ts index ec375cbc0..21f14b2bc 100644 --- a/packages/types/src/shell/type/drag-node-object.ts +++ b/packages/types/src/shell/type/drag-node-object.ts @@ -1,7 +1,7 @@ import { IPublicModelNode } from '..'; import { IPublicEnumDragObjectType } from '../enum'; -export interface IPublicTypeDragNodeObject { +export interface IPublicTypeDragNodeObject { type: IPublicEnumDragObjectType.Node; - nodes: IPublicModelNode[]; + nodes: Node[]; } diff --git a/packages/types/src/shell/type/field-config.ts b/packages/types/src/shell/type/field-config.ts index 32b40f157..bd09e7b90 100644 --- a/packages/types/src/shell/type/field-config.ts +++ b/packages/types/src/shell/type/field-config.ts @@ -13,7 +13,7 @@ export interface IPublicTypeFieldConfig extends IPublicTypeFieldExtraProps { /** * the name of this setting field, which used in quickEditor */ - name: string | number; + name?: string | number; /** * the field title diff --git a/packages/types/src/shell/type/field-extra-props.ts b/packages/types/src/shell/type/field-extra-props.ts index 2977da1d8..79466389e 100644 --- a/packages/types/src/shell/type/field-extra-props.ts +++ b/packages/types/src/shell/type/field-extra-props.ts @@ -19,12 +19,12 @@ export interface IPublicTypeFieldExtraProps { /** * get value for field */ - getValue?: (target: IPublicModelSettingTarget, fieldValue: any) => any; + getValue?: (target: IPublicModelSettingPropEntry, fieldValue: any) => any; /** * set value for field */ - setValue?: (target: IPublicModelSettingTarget, value: any) => void; + setValue?: (target: IPublicModelSettingPropEntry, value: any) => void; /** * the field conditional show, is not set always true diff --git a/packages/types/src/shell/type/metadata.ts b/packages/types/src/shell/type/metadata.ts index 918074c58..7ee0228c9 100644 --- a/packages/types/src/shell/type/metadata.ts +++ b/packages/types/src/shell/type/metadata.ts @@ -1,5 +1,5 @@ import { IPublicTypePropType, IPublicTypeComponentAction } from './'; -import { IPublicModelProp, IPublicModelSettingTarget } from '../model'; +import { IPublicModelNode, IPublicModelProp, IPublicModelSettingTarget } from '../model'; /** * 嵌套控制函数 @@ -184,20 +184,20 @@ export interface ConfigureSupport { */ export interface IPublicTypeCallbacks { // hooks - onMouseDownHook?: (e: MouseEvent, currentNode: any) => any; - onDblClickHook?: (e: MouseEvent, currentNode: any) => any; - onClickHook?: (e: MouseEvent, currentNode: any) => any; + onMouseDownHook?: (e: MouseEvent, currentNode: IPublicModelNode) => any; + onDblClickHook?: (e: MouseEvent, currentNode: IPublicModelNode) => any; + onClickHook?: (e: MouseEvent, currentNode: IPublicModelNode) => any; // onLocateHook?: (e: any, currentNode: any) => any; // onAcceptHook?: (currentNode: any, locationData: any) => any; - onMoveHook?: (currentNode: any) => boolean; + onMoveHook?: (currentNode: IPublicModelNode) => boolean; // thinkof 限制性拖拽 - onHoverHook?: (currentNode: any) => boolean; - onChildMoveHook?: (childNode: any, currentNode: any) => boolean; + onHoverHook?: (currentNode: IPublicModelNode) => boolean; + onChildMoveHook?: (childNode: IPublicModelNode, currentNode: IPublicModelNode) => boolean; // events - onNodeRemove?: (removedNode: any, currentNode: any) => void; - onNodeAdd?: (addedNode: any, currentNode: any) => void; - onSubtreeModified?: (currentNode: any, options: any) => void; + onNodeRemove?: (removedNode: IPublicModelNode, currentNode: IPublicModelNode) => void; + onNodeAdd?: (addedNode: IPublicModelNode, currentNode: IPublicModelNode) => void; + onSubtreeModified?: (currentNode: IPublicModelNode, options: any) => void; onResize?: ( e: MouseEvent & { trigger: string; @@ -220,6 +220,6 @@ export interface IPublicTypeCallbacks { deltaX?: number; deltaY?: number; }, - currentNode: any, + currentNode: IPublicModelNode, ) => void; } diff --git a/packages/types/src/shell/type/setter-config.ts b/packages/types/src/shell/type/setter-config.ts index ddca72829..ac8a05aa3 100644 --- a/packages/types/src/shell/type/setter-config.ts +++ b/packages/types/src/shell/type/setter-config.ts @@ -6,49 +6,60 @@ import { IPublicTypeDynamicProps } from './dynamic-props'; * 设置器配置 */ export interface IPublicTypeSetterConfig { + // if *string* passed must be a registered Setter Name /** * 配置设置器用哪一个 setter */ componentName: string | IPublicTypeCustomView; + /** * 传递给 setter 的属性 * * the props pass to Setter Component */ props?: Record | IPublicTypeDynamicProps; + /** * @deprecated */ children?: any; + /** * 是否必填? * * ArraySetter 里有个快捷预览,可以在不打开面板的情况下直接编辑 */ isRequired?: boolean; + /** * Setter 的初始值 * * @todo initialValue 可能要和 defaultValue 二选一 */ initialValue?: any | ((target: IPublicModelSettingTarget) => any); + + defaultValue?: any; + // for MixedSetter /** * 给 MixedSetter 时切换 Setter 展示用的 */ title?: IPublicTypeTitleContent; + // for MixedSetter check this is available /** * 给 MixedSetter 用于判断优先选中哪个 */ condition?: (target: IPublicModelSettingTarget) => boolean; + /** * 给 MixedSetter,切换值时声明类型 * * @todo 物料协议推进 */ valueType?: IPublicTypeCompositeValue[]; + // 标识是否为动态 setter,默认为 true isDynamic?: boolean; } diff --git a/packages/utils/src/check-types/is-drag-node-data-object.ts b/packages/utils/src/check-types/is-drag-node-data-object.ts index 6f17abf23..4b08f67fa 100644 --- a/packages/utils/src/check-types/is-drag-node-data-object.ts +++ b/packages/utils/src/check-types/is-drag-node-data-object.ts @@ -1,5 +1,5 @@ -import { IPublicEnumDragObjectType } from '@alilc/lowcode-types'; +import { IPublicEnumDragObjectType, IPublicTypeDragNodeDataObject } from '@alilc/lowcode-types'; -export function isDragNodeDataObject(obj: any): boolean { +export function isDragNodeDataObject(obj: any): obj is IPublicTypeDragNodeDataObject { return obj && obj.type === IPublicEnumDragObjectType.NodeData; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-drag-node-object.ts b/packages/utils/src/check-types/is-drag-node-object.ts index 79b28fb58..1b6c131e9 100644 --- a/packages/utils/src/check-types/is-drag-node-object.ts +++ b/packages/utils/src/check-types/is-drag-node-object.ts @@ -1,5 +1,5 @@ -import { IPublicEnumDragObjectType } from '@alilc/lowcode-types'; +import { IPublicEnumDragObjectType, IPublicModelNode, IPublicTypeDragNodeObject } from '@alilc/lowcode-types'; -export function isDragNodeObject(obj: any): boolean { +export function isDragNodeObject(obj: any): obj is IPublicTypeDragNodeObject { return obj && obj.type === IPublicEnumDragObjectType.Node; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-node.ts b/packages/utils/src/check-types/is-node.ts index 9fe27b29d..14c2e2f74 100644 --- a/packages/utils/src/check-types/is-node.ts +++ b/packages/utils/src/check-types/is-node.ts @@ -1,3 +1,5 @@ -export function isNode(node: any): boolean { +import { IPublicModelNode } from '@alilc/lowcode-types'; + +export function isNode(node: any): node is Node { return node && node.isNode; } \ No newline at end of file