diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 1ac91285d..8befb0433 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -1098,7 +1098,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost node.isLocked); if (lockedNode) return null; if ( !dropContainer || - canDropIn === false || - // too dirty - (nodes && typeof canDropIn === 'function' && !canDropIn(operationalNodes[0])) + (nodes && typeof childWhitelist === 'function' && !childWhitelist(operationalNodes[0])) ) { return null; } diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 9cde6b67c..e51f76209 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -226,13 +226,11 @@ export class SettingTopEntry implements SettingEntry { } - // ==== compatibles for vision ===== getProp(propName: string | number) { return this.get(propName); } // ==== copy some Node api ===== - // `VE.Node.getProps` getStatus() { } diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 4a34213f3..688b167b7 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -642,6 +642,7 @@ export class DocumentModel { this.rootNodeVisitorMap[visitorName] = visitorResult; } catch (e) { console.error('RootNodeVisitor is not valid.'); + console.error(e); } return visitorResult; } diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 05de1009b..d0d36324d 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -316,6 +316,7 @@ export class Prop implements IPropParent { const slotSchema: SlotSchema = { componentName: 'Slot', title: data.title, + id: data.id, name: data.name, params: data.params, children: data.value, diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index 3489e7f76..becae741f 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -21,6 +21,7 @@ import { PreferenceValueType, IPluginPreferenceMananger, } from './plugin-types'; +import { isValidPreferenceKey } from './plugin-utils'; export default class PluginContext implements ILowCodePluginContext { private readonly [editorSymbol]: Editor; @@ -53,26 +54,22 @@ export default class PluginContext implements ILowCodePluginContext { this.plugins = plugins; this.event = new Event(editor, { prefix: 'common' }); this.logger = getLogger({ level: 'warn', bizName: `designer:plugin:${pluginName}` }); + + const enhancePluginContextHook = engineConfig.get('enhancePluginContextHook'); + if (enhancePluginContextHook) { + enhancePluginContextHook(this); + } } setPreference( pluginName: string, preferenceDeclaration: ILowCodePluginPreferenceDeclaration, ): void { - const isValidPreferenceKey = (key: string): boolean => { - if (!preferenceDeclaration || !Array.isArray(preferenceDeclaration.properties)) { - return false; - } - return preferenceDeclaration.properties.some((prop) => { - return prop.key === key; - }); - }; - const getPreferenceValue = ( key: string, defaultValue?: PreferenceValueType, ): PreferenceValueType | undefined => { - if (!isValidPreferenceKey(key)) { + if (!isValidPreferenceKey(key, preferenceDeclaration)) { return undefined; } const pluginPreference = this.plugins.getPluginPreference(pluginName) || {}; diff --git a/packages/designer/src/plugin/plugin-manager.ts b/packages/designer/src/plugin/plugin-manager.ts index 5b29d7bf9..f0b45f2cf 100644 --- a/packages/designer/src/plugin/plugin-manager.ts +++ b/packages/designer/src/plugin/plugin-manager.ts @@ -11,7 +11,9 @@ import { ILowCodePluginConfigMeta, PluginPreference, ILowCodePluginPreferenceDeclaration, + isLowCodeRegisterOptions, } from './plugin-types'; +import { filterValidOptions } from './plugin-utils'; import { LowCodePlugin } from './plugin'; import LowCodePluginContext from './plugin-context'; import { invariant } from '../utils'; @@ -41,15 +43,30 @@ export class LowCodePluginManager implements ILowCodePluginManager { return semverSatisfies(engineVersion, versionExp); } + /** + * register a plugin + * @param pluginConfigCreator - a creator function which returns the plugin config + * @param options - the plugin options + * @param registerOptions - the plugin register options + */ async register( - pluginConfigCreator: (ctx: ILowCodePluginContext) => ILowCodePluginConfig, - options?: ILowCodeRegisterOptions, + pluginConfigCreator: (ctx: ILowCodePluginContext, options: any) => ILowCodePluginConfig, + options?: any, + registerOptions?: ILowCodeRegisterOptions, ): Promise { - const { pluginName, meta = {} } = pluginConfigCreator as any; + // registerOptions maybe in the second place + if (isLowCodeRegisterOptions(options)) { + registerOptions = options; + options = {}; + } + let { pluginName, meta = {} } = pluginConfigCreator as any; const { preferenceDeclaration, engines } = meta as ILowCodePluginConfigMeta; const ctx = this._getLowCodePluginContext({ pluginName }); - const config = pluginConfigCreator(ctx); - + const customFilterValidOptions = engineConfig.get('customPluginFilterOptions', filterValidOptions); + const config = pluginConfigCreator(ctx, customFilterValidOptions(options, preferenceDeclaration!)); + // compat the legacy way to declare pluginName + // @ts-ignore + pluginName = pluginName || config.name; invariant( pluginName, 'pluginConfigCreator.pluginName required', @@ -58,7 +75,7 @@ export class LowCodePluginManager implements ILowCodePluginManager { ctx.setPreference(pluginName, (preferenceDeclaration as ILowCodePluginPreferenceDeclaration)); - const allowOverride = options?.override === true; + const allowOverride = registerOptions?.override === true; if (this.pluginsMap.has(pluginName)) { if (!allowOverride) { @@ -83,7 +100,8 @@ export class LowCodePluginManager implements ILowCodePluginManager { } const plugin = new LowCodePlugin(pluginName, this, config, meta); - if (options?.autoInit) { + // support initialization of those plugins which registered after normal initialization by plugin-manager + if (registerOptions?.autoInit) { await plugin.init(); } this.plugins.push(plugin); diff --git a/packages/designer/src/plugin/plugin-types.ts b/packages/designer/src/plugin/plugin-types.ts index ca91d2ff2..1bfb5aa31 100644 --- a/packages/designer/src/plugin/plugin-types.ts +++ b/packages/designer/src/plugin/plugin-types.ts @@ -48,6 +48,7 @@ export interface ILowCodePluginPreferenceDeclaration { export type PluginPreference = Map>; export interface ILowCodePluginConfig { + dep?: string | string[]; init?(): void; destroy?(): void; exports?(): any; @@ -130,6 +131,10 @@ export interface ILowCodePluginManagerCore { export type ILowCodePluginManager = ILowCodePluginManagerCore & ILowCodePluginManagerPluginAccessor; +export function isLowCodeRegisterOptions(opts: any): opts is ILowCodeRegisterOptions { + return opts && ('autoInit' in opts || 'override' in opts); +} + export interface ILowCodeRegisterOptions { autoInit?: boolean; // allow overriding existing plugin with same name when override === true diff --git a/packages/designer/src/plugin/plugin-utils.ts b/packages/designer/src/plugin/plugin-utils.ts new file mode 100644 index 000000000..a92927400 --- /dev/null +++ b/packages/designer/src/plugin/plugin-utils.ts @@ -0,0 +1,28 @@ +import type { ILowCodePluginPreferenceDeclaration } from './plugin-types'; +import { isPlainObject } from 'lodash'; + +export function isValidPreferenceKey( + key: string, + preferenceDeclaration: ILowCodePluginPreferenceDeclaration, +): boolean { + if (!preferenceDeclaration || !Array.isArray(preferenceDeclaration.properties)) { + return false; + } + return preferenceDeclaration.properties.some((prop) => { + return prop.key === key; + }); +} + +export function filterValidOptions(opts: any, preferenceDeclaration: ILowCodePluginPreferenceDeclaration) { + if (!opts || !isPlainObject(opts)) return opts; + const filteredOpts = {} as any; + Object.keys(opts).forEach(key => { + if (isValidPreferenceKey(key, preferenceDeclaration)) { + const v = opts[key]; + if (v !== undefined && v !== null) { + filteredOpts[key] = v; + } + } + }); + return filteredOpts; +} \ No newline at end of file diff --git a/packages/designer/src/plugin/plugin.ts b/packages/designer/src/plugin/plugin.ts index 0a2de53d4..0fd11ae9e 100644 --- a/packages/designer/src/plugin/plugin.ts +++ b/packages/designer/src/plugin/plugin.ts @@ -50,7 +50,11 @@ export class LowCodePlugin implements ILowCodePlugin { if (typeof this.meta.dependencies === 'string') { return [this.meta.dependencies]; } - return this.meta.dependencies || []; + // compat legacy way to declare dependencies + if (typeof this.config.dep === 'string') { + return [this.config.dep]; + } + return this.meta.dependencies || this.config.dep || []; } get disabled() { diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index 7e9101d96..058241a57 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -11,6 +11,7 @@ import { RemoteComponentDescription, GlobalEvent, } from '@alilc/lowcode-types'; +import { engineConfig } from './config'; import { globalLocale } from './intl'; import * as utils from './utils'; import Preference from './utils/preference'; @@ -71,6 +72,8 @@ export class Editor extends (EventEmitter as any) implements IEditor { this.setAssets(data); return; } + // store the data to engineConfig while invoking editor.set() + engineConfig.set(key as any, data); this.context.set(key, data); this.notifyGot(key); } diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index ac97c1450..1004f6327 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -314,6 +314,7 @@ body { display: none; flex-shrink: 0; position: relative; + z-index: 820; &.lc-area-visible { display: block; } diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 8916b9e30..f08296bc1 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -6,6 +6,7 @@ import { LowCodePluginManager, ILowCodePluginContext, PluginPreference, + TransformStage, } from '@alilc/lowcode-designer'; import { Skeleton as InnerSkeleton, @@ -22,7 +23,8 @@ import utils from './modules/utils'; import * as editorCabin from './modules/editor-cabin'; import getSkeletonCabin from './modules/skeleton-cabin'; import getDesignerCabin from './modules/designer-cabin'; - +import classes from './modules/classes'; +import symbols from './modules/symbols'; export * from './modules/editor-types'; export * from './modules/skeleton-types'; export * from './modules/designer-types'; @@ -60,8 +62,12 @@ const config = engineConfig; const event = new Event(editor, { prefix: 'common' }); const logger = getLogger({ level: 'warn', bizName: 'common' }); const designerCabin = getDesignerCabin(editor); +const objects = { + TransformStage, +}; const common = { utils, + objects, editorCabin, designerCabin, skeletonCabin, @@ -81,6 +87,12 @@ export { // 兼容原 editor 的事件功能 event as editor, }; +// declare this is open-source version +export const isOpenSource = true; +export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { + symbols, + classes, +}; // 注册一批内置插件 (async function registerPlugins() { diff --git a/packages/engine/src/modules/classes.ts b/packages/engine/src/modules/classes.ts new file mode 100644 index 000000000..11d1e7089 --- /dev/null +++ b/packages/engine/src/modules/classes.ts @@ -0,0 +1,25 @@ +import { + Project, + Skeleton, + DocumentModel, + Node, + NodeChildren, + History, + SettingPropEntry, + SettingTopEntry, + Selection, +} from '@alilc/lowcode-shell'; +import { Node as InnerNode } from '@alilc/lowcode-designer'; + +export default { + Project, + Skeleton, + DocumentModel, + Node, + NodeChildren, + History, + SettingPropEntry, + SettingTopEntry, + InnerNode, + Selection, +}; diff --git a/packages/engine/src/modules/designer-cabin.ts b/packages/engine/src/modules/designer-cabin.ts index 9b55a3946..812f53a76 100644 --- a/packages/engine/src/modules/designer-cabin.ts +++ b/packages/engine/src/modules/designer-cabin.ts @@ -3,6 +3,10 @@ import { isSettingField, Designer, TransformStage, + LiveEditing, + isDragNodeDataObject, + DragObjectType, + isNode, } from '@alilc/lowcode-designer'; import { Editor } from '@alilc/lowcode-editor-core'; import { Dragon } from '@alilc/lowcode-shell'; @@ -15,5 +19,9 @@ export default function getDesignerCabin(editor: Editor) { isSettingField, dragon: Dragon.create(designer.dragon), TransformStage, + LiveEditing, + DragObjectType, + isDragNodeDataObject, + isNode, }; } \ No newline at end of file diff --git a/packages/engine/src/modules/designer-types.ts b/packages/engine/src/modules/designer-types.ts index c6e30ea9e..abcb418d7 100644 --- a/packages/engine/src/modules/designer-types.ts +++ b/packages/engine/src/modules/designer-types.ts @@ -13,3 +13,6 @@ export type ILowCodePluginConfig = designerCabin.ILowCodePluginConfig; export type ILowCodePluginManager = designerCabin.ILowCodePluginManager; export type ILowCodePluginContext = designerCabin.ILowCodePluginContext; export type PluginPreference = designerCabin.PluginPreference; +export type PropsReducerContext = designerCabin.PropsReducerContext; +export type DragObjectType = designerCabin.DragObjectType; +export type DragNodeDataObject = designerCabin.DragNodeDataObject; \ No newline at end of file diff --git a/packages/engine/src/modules/editor-cabin.ts b/packages/engine/src/modules/editor-cabin.ts index c9263c2c5..bcb3cc965 100644 --- a/packages/engine/src/modules/editor-cabin.ts +++ b/packages/engine/src/modules/editor-cabin.ts @@ -3,12 +3,11 @@ export { Tip, shallowIntl, createIntl, + intl, createSetterContent, - // TODO: To be deleted obx, + untracked, computed, observer, - getSetter, - getSettersMap, globalLocale, } from '@alilc/lowcode-editor-core'; \ No newline at end of file diff --git a/packages/engine/src/modules/symbols.ts b/packages/engine/src/modules/symbols.ts new file mode 100644 index 000000000..ac469bc26 --- /dev/null +++ b/packages/engine/src/modules/symbols.ts @@ -0,0 +1,21 @@ +import { + projectSymbol, + documentSymbol, + nodeSymbol, + designerSymbol, + skeletonSymbol, + editorSymbol, + settingPropEntrySymbol, + settingTopEntrySymbol, +} from '@alilc/lowcode-shell'; + +export default { + projectSymbol, + documentSymbol, + nodeSymbol, + skeletonSymbol, + editorSymbol, + designerSymbol, + settingPropEntrySymbol, + settingTopEntrySymbol, +}; diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 42a75d804..3cfe5a9dc 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -106,7 +106,11 @@ export default class TreeTitle extends Component<{ data-id={treeNode.id} onClick={() => { if (isModal) { - node.document.modalNodesManager.setVisible(node); + if (node.getVisible()) { + node.document.modalNodesManager.setInvisible(node); + } else { + node.document.modalNodesManager.setVisible(node); + } return; } if (node.conditionGroup) { diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index 8d9681362..24a4a825e 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -260,6 +260,10 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { this.initOnVisibleChangeEvent(_leaf); this.curEventLeaf = _leaf; + cache.ref.set(props.componentId, { + makeUnitRender: this.makeUnitRender, + }); + let cacheState = cache.state.get(props.componentId); if (!cacheState || cacheState.__tag !== props.__tag) { cacheState = this.defaultState; @@ -557,7 +561,6 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { cache.ref.set(props.componentId, _ref)} /> )); diff --git a/packages/shell/src/component-meta.ts b/packages/shell/src/component-meta.ts index 59635555a..bc8a44922 100644 --- a/packages/shell/src/component-meta.ts +++ b/packages/shell/src/component-meta.ts @@ -1,8 +1,10 @@ import { ComponentMeta as InnerComponentMeta, + ParentalNode, } from '@alilc/lowcode-designer'; -import { componentMetaSymbol } from './symbols'; - +import Node from './node'; +import { NodeData, NodeSchema } from '@alilc/lowcode-types'; +import { componentMetaSymbol, nodeSymbol } from './symbols'; export default class ComponentMeta { private readonly [componentMetaSymbol]: InnerComponentMeta; @@ -75,6 +77,13 @@ export default class ComponentMeta { return this[componentMetaSymbol].npm; } + /** + * @deprecated + */ + get prototype() { + return this[componentMetaSymbol].prototype; + } + /** * 设置 npm 信息 * @param npm @@ -90,4 +99,26 @@ export default class ComponentMeta { getMetadata() { return this[componentMetaSymbol].getMetadata(); } + + /** + * check if the current node could be placed in parent node + * @param my + * @param parent + * @returns + */ + checkNestingUp(my: Node | NodeData, parent: ParentalNode) { + const curNode = my.isNode ? my[nodeSymbol] : my; + return this[componentMetaSymbol].checkNestingUp(curNode as any, parent); + } + + /** + * check if the target node(s) could be placed in current node + * @param my + * @param parent + * @returns + */ + checkNestingDown(my: Node | NodeData, target: NodeSchema | Node | NodeSchema[]) { + const curNode = my.isNode ? my[nodeSymbol] : my; + return this[componentMetaSymbol].checkNestingDown(curNode as any, target[nodeSymbol] || target); + } } diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index 552da0bbe..1b29ac0a0 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -6,7 +6,13 @@ import { IOnChangeOptions as InnerIOnChangeOptions, PropChangeOptions as InnerPropChangeOptions, } from '@alilc/lowcode-designer'; -import { TransformStage, RootSchema, NodeSchema, NodeData, GlobalEvent } from '@alilc/lowcode-types'; +import { + TransformStage, + RootSchema, + NodeSchema, + NodeData, + GlobalEvent, +} from '@alilc/lowcode-types'; import Node from './node'; import Selection from './selection'; import Detecting from './detecting'; @@ -33,6 +39,7 @@ type PropChangeOptions = { export default class DocumentModel { private readonly [documentSymbol]: InnerDocumentModel; private readonly [editorSymbol]: Editor; + private _focusNode: Node; public selection: Selection; public detecting: Detecting; public history: History; @@ -45,6 +52,8 @@ export default class DocumentModel { this.detecting = new Detecting(document); this.history = new History(document.getHistory()); this.canvas = new Canvas(document.designer); + + this._focusNode = Node.create(this[documentSymbol].focusNode); } static create(document: InnerDocumentModel | undefined | null) { @@ -68,6 +77,14 @@ export default class DocumentModel { return Node.create(this[documentSymbol].getRoot()); } + get focusNode(): Node { + return this._focusNode; + } + + set focusNode(node: Node) { + this._focusNode = node; + } + /** * 获取文档下所有节点 * @returns @@ -87,6 +104,11 @@ export default class DocumentModel { return ModalNodesManager.create(this[documentSymbol].modalNodesManager); } + // @TODO: 不能直接暴露 + get dropLocation() { + return this[documentSymbol].dropLocation; + } + /** * 根据 nodeId 返回 Node 实例 * @param nodeId @@ -157,7 +179,7 @@ export default class DocumentModel { * 当前 document 新增节点事件 */ onAddNode(fn: (node: Node) => void) { - this[documentSymbol].onNodeCreate((node: InnerNode) => { + return this[documentSymbol].onNodeCreate((node: InnerNode) => { fn(Node.create(node)!); }); } @@ -166,7 +188,7 @@ export default class DocumentModel { * 当前 document 删除节点事件 */ onRemoveNode(fn: (node: Node) => void) { - this[documentSymbol].onNodeDestroy((node: InnerNode) => { + return this[documentSymbol].onNodeDestroy((node: InnerNode) => { fn(Node.create(node)!); }); } diff --git a/packages/shell/src/dragon.ts b/packages/shell/src/dragon.ts index b3d770fb4..85f4b84d3 100644 --- a/packages/shell/src/dragon.ts +++ b/packages/shell/src/dragon.ts @@ -16,6 +16,13 @@ export default class Dragon { return new Dragon(dragon); } + /** + * is dragging or not + */ + get dragging() { + return this[dragonSymbol].dragging; + } + /** * 绑定 dragstart 事件 * @param func diff --git a/packages/shell/src/event.ts b/packages/shell/src/event.ts index 7dc988107..cb2242229 100644 --- a/packages/shell/src/event.ts +++ b/packages/shell/src/event.ts @@ -61,6 +61,15 @@ export default class Event { } this[editorSymbol].emit(`${this.options.prefix}:${event}`, ...args); } + + /** + * DO NOT USE if u fully understand what this method does. + * @param event + * @param args + */ + __internalEmit__(event: string, ...args: unknown[]) { + this[editorSymbol].emit(event, ...args); + } } export function getEvent(editor: InnerEditor, options: any = { prefix: 'common' }) { diff --git a/packages/shell/src/index.ts b/packages/shell/src/index.ts index 7396b18a9..07a0c83a7 100644 --- a/packages/shell/src/index.ts +++ b/packages/shell/src/index.ts @@ -5,6 +5,7 @@ import Event, { getEvent } from './event'; import History from './history'; import Material from './material'; import Node from './node'; +import NodeChildren from './node-children'; import Project from './project'; import Prop from './prop'; import Selection from './selection'; @@ -13,6 +14,7 @@ import Hotkey from './hotkey'; import Skeleton from './skeleton'; import Dragon from './dragon'; import SettingPropEntry from './setting-prop-entry'; +import SettingTopEntry from './setting-top-entry'; export * from './symbols'; /** @@ -30,6 +32,7 @@ export { History, Material, Node, + NodeChildren, Project, Prop, Selection, @@ -37,6 +40,7 @@ export { Hotkey, Skeleton, SettingPropEntry, + SettingTopEntry, Dragon, getEvent, }; \ No newline at end of file diff --git a/packages/shell/src/material.ts b/packages/shell/src/material.ts index 1e11ee21a..23cbc1938 100644 --- a/packages/shell/src/material.ts +++ b/packages/shell/src/material.ts @@ -7,9 +7,10 @@ import { addBuiltinComponentAction, removeBuiltinComponentAction, modifyBuiltinComponentAction, + isComponentMeta, } from '@alilc/lowcode-designer'; import { AssetsJson } from '@alilc/lowcode-utils'; -import { ComponentAction } from '@alilc/lowcode-types'; +import { ComponentAction, ComponentMetadata } from '@alilc/lowcode-types'; import { editorSymbol, designerSymbol } from './symbols'; import ComponentMeta from './component-meta'; @@ -86,6 +87,26 @@ export default class Material { return ComponentMeta.create(this[designerSymbol].getComponentMeta(componentName)); } + /** + * create an instance of ComponentMeta by given metadata + * @param metadata + * @returns + */ + createComponentMeta(metadata: ComponentMetadata) { + return ComponentMeta.create(this[designerSymbol].createComponentMeta(metadata)); + } + + /** + * test if the given object is a ComponentMeta instance or not + * @param obj + * @returns + */ + isComponentMeta(obj: any) { + return isComponentMeta(obj); + } + + + /** * 获取所有已注册的物料元数据 * @returns diff --git a/packages/shell/src/node-children.ts b/packages/shell/src/node-children.ts index 024e5b296..2557e37ac 100644 --- a/packages/shell/src/node-children.ts +++ b/packages/shell/src/node-children.ts @@ -37,6 +37,13 @@ export default class NodeChildren { return this[nodeChildrenSymbol].isEmpty(); } + /** + * judge if it is not empty + */ + get notEmpty() { + return !this.isEmpty; + } + /** * 删除指定节点 * @param node @@ -81,7 +88,7 @@ export default class NodeChildren { * @returns */ get(index: number) { - return this[nodeChildrenSymbol].get(index); + return Node.create(this[nodeChildrenSymbol].get(index)); } /** diff --git a/packages/shell/src/node.ts b/packages/shell/src/node.ts index 27b8a62fa..03f90f6c9 100644 --- a/packages/shell/src/node.ts +++ b/packages/shell/src/node.ts @@ -17,9 +17,13 @@ export default class Node { private readonly [documentSymbol]: InnerDocumentModel; private readonly [nodeSymbol]: InnerNode; + private _id: string; + constructor(node: InnerNode) { this[nodeSymbol] = node; this[documentSymbol] = node.document; + + this._id = this[nodeSymbol].id; } static create(node: InnerNode | null | undefined) { @@ -36,7 +40,14 @@ export default class Node { * 节点 id */ get id() { - return this[nodeSymbol].id; + return this._id; + } + + /** + * set id + */ + set id(id: string) { + this._id = id; } /** @@ -84,7 +95,7 @@ export default class Node { /** * 是否为「模态框」节点 */ - get isModal() { + get isModal() { return this[nodeSymbol].isModal(); } @@ -109,6 +120,13 @@ export default class Node { return this[nodeSymbol].isLeaf(); } + /** + * judge if it is a node or not + */ + get isNode() { + return true; + } + /** * 下标 */ @@ -208,10 +226,17 @@ export default class Node { /** * 返回节点的属性集 */ - get propsData() { + get propsData() { return this[nodeSymbol].propsData; } + /** + * 获取符合搭建协议-节点 schema 结构 + */ + get schema(): any { + return this[nodeSymbol].schema; + } + /** * @deprecated use .children instead */ @@ -258,6 +283,14 @@ export default class Node { return this[nodeSymbol].hasLoop(); } + getVisible() { + return this[nodeSymbol].getVisible(); + } + + isConditionalVisible() { + return this[nodeSymbol].isConditionalVisible(); + } + /** * @deprecated use .props instead */ @@ -265,6 +298,10 @@ export default class Node { return this.props; } + contains(node: Node) { + return this[nodeSymbol].contains(node[nodeSymbol]); + } + /** * 获取指定 path 的属性模型实例 * @param path 属性路径,支持 a / a.b / a.0 等格式 diff --git a/packages/shell/src/prop.ts b/packages/shell/src/prop.ts index f7967f7db..9d5f42cb5 100644 --- a/packages/shell/src/prop.ts +++ b/packages/shell/src/prop.ts @@ -43,6 +43,11 @@ export default class Prop { return Node.create(this[propSymbol].getNode()); } + /** + * judge if it is a prop or not + */ + get isProp() { return true; } + /** * 设置值 * @param val diff --git a/packages/shell/src/selection.ts b/packages/shell/src/selection.ts index df90447c0..71bda7fc3 100644 --- a/packages/shell/src/selection.ts +++ b/packages/shell/src/selection.ts @@ -22,6 +22,13 @@ export default class Selection { return this[selectionSymbol].selected; } + /** + * return selected Node instance + */ + get node() { + return this.getNodes()[0]; + } + /** * 选中指定节点(覆盖方式) * @param id diff --git a/packages/types/package.json b/packages/types/package.json index a71326e20..07e3b9151 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@alilc/lowcode-datasource-types": "^1.0.0", - "react": "^16.9 || ^17", + "react": "^16.9", "strict-event-emitter-types": "^2.0.0" }, "devDependencies": { diff --git a/packages/utils/src/misc.ts b/packages/utils/src/misc.ts index a97c12389..1cde5adb3 100644 --- a/packages/utils/src/misc.ts +++ b/packages/utils/src/misc.ts @@ -102,6 +102,6 @@ export function invariant(check: any, message: string, thing?: any) { export function deprecate(fail: any, message: string, alterative?: string) { if (fail) { - console.warn(`Deprecation: ${message}` + (alterative ? `, use ${alterative} instead.'` : '')); + console.warn(`Deprecation: ${message}` + (alterative ? `, use ${alterative} instead.` : '')); } } \ No newline at end of file