fix: fix ts error

This commit is contained in:
liujuping 2023-03-14 11:08:42 +08:00 committed by 林熠
parent 41753de24a
commit 4433b2ee78
42 changed files with 356 additions and 196 deletions

View File

@ -67,7 +67,7 @@ import { BuiltinSimulatorRenderer } from './renderer';
import { clipboard } from '../designer/clipboard'; import { clipboard } from '../designer/clipboard';
import { LiveEditing } from './live-editing/live-editing'; import { LiveEditing } from './live-editing/live-editing';
import { Project } from '../project'; import { Project } from '../project';
import { Scroller } from '../designer/scroller'; import { IScroller } from '../designer/scroller';
import { isElementNode, isDOMNodeVisible } from '../utils/misc'; import { isElementNode, isDOMNodeVisible } from '../utils/misc';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
@ -170,7 +170,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
readonly viewport = new Viewport(); readonly viewport = new Viewport();
readonly scroller: Scroller; readonly scroller: IScroller;
readonly emitter: IEventBus = createModuleEventBus('BuiltinSimulatorHost'); readonly emitter: IEventBus = createModuleEventBus('BuiltinSimulatorHost');
@ -381,7 +381,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
// todo // todo
} }
mountViewport(viewport: Element | null) { mountViewport(viewport: HTMLElement | null) {
this.viewport.mount(viewport); this.viewport.mount(viewport);
} }
@ -510,7 +510,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
// TODO: dispose the bindings // TODO: dispose the bindings
} }
async setupComponents(library) { async setupComponents(library: LibraryItem[]) {
const libraryAsset: AssetList = this.buildLibrary(library); const libraryAsset: AssetList = this.buildLibrary(library);
await this.renderer?.load(libraryAsset); await this.renderer?.load(libraryAsset);
if (Object.keys(this.asyncLibraryMap).length > 0) { if (Object.keys(this.asyncLibraryMap).length > 0) {
@ -576,7 +576,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
const isRGLNode = rglNode?.isRGLContainer; const isRGLNode = rglNode?.isRGLContainer;
if (isRGLNode) { if (isRGLNode) {
// 如果拖拽的是磁铁块的右下角 handle则直接跳过 // 如果拖拽的是磁铁块的右下角 handle则直接跳过
if (downEvent.target.classList.contains('react-resizable-handle')) return; if (downEvent.target?.classList.contains('react-resizable-handle')) return;
// 禁止多选 // 禁止多选
isMulti = false; isMulti = false;
designer.dragon.emitter.emit('rgl.switch', { designer.dragon.emitter.emit('rgl.switch', {
@ -605,7 +605,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
if (!isShaken(downEvent, e) || isRGLNode) { if (!isShaken(downEvent, e) || isRGLNode) {
let { id } = node; let { id } = node;
designer.activeTracker.track({ node, instance: nodeInst?.instance }); designer.activeTracker.track({ node, instance: nodeInst?.instance });
if (isMulti && !node.contains(focusNode) && selection.has(id)) { if (isMulti && focusNode && !node.contains(focusNode) && selection.has(id)) {
selection.remove(id); selection.remove(id);
} else { } else {
// TODO: 避免选中 Page 组件,默认选中第一个子节点;新增规则 或 判断 Live 模式 // TODO: 避免选中 Page 组件,默认选中第一个子节点;新增规则 或 判断 Live 模式
@ -613,7 +613,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
const firstChildId = node.getChildren()?.get(0)?.getId(); const firstChildId = node.getChildren()?.get(0)?.getId();
if (firstChildId) id = firstChildId; if (firstChildId) id = firstChildId;
} }
selection.select(node.contains(focusNode) ? focusNode.id : id); if (focusNode) {
selection.select(node.contains(focusNode) ? focusNode.id : id);
}
// dirty code should refector // dirty code should refector
const editor = this.designer?.editor; const editor = this.designer?.editor;
@ -629,8 +631,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
} }
}; };
if (isLeftButton && !node.contains(focusNode)) { if (isLeftButton && focusNode && !node.contains(focusNode)) {
let nodes: Node[] = [node]; let nodes: INode[] = [node];
let ignoreUpSelected = false; let ignoreUpSelected = false;
if (isMulti) { if (isMulti) {
// multi select mode, directily add // multi select mode, directily add
@ -639,7 +641,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
selection.add(node.id); selection.add(node.id);
ignoreUpSelected = true; ignoreUpSelected = true;
} }
selection.remove(focusNode.id); focusNode?.id && selection.remove(focusNode.id);
// 获得顶层 nodes // 获得顶层 nodes
nodes = selection.getTopNodes(); nodes = selection.getTopNodes();
} else if (selection.containsNode(node, true)) { } else if (selection.containsNode(node, true)) {
@ -727,7 +729,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
if (nodeInst?.node) { if (nodeInst?.node) {
let { node } = nodeInst; let { node } = nodeInst;
const focusNode = node.document?.focusNode; const focusNode = node.document?.focusNode;
if (node.contains(focusNode)) { if (focusNode && node.contains(focusNode)) {
node = focusNode; node = focusNode;
} }
detecting.capture(node); detecting.capture(node);
@ -738,7 +740,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
e.stopPropagation(); e.stopPropagation();
} }
}; };
const leave = () => detecting.leave(this.project.currentDocument); const leave = () => {
this.project.currentDocument && detecting.leave(this.project.currentDocument)
};
doc.addEventListener('mouseover', hover, true); doc.addEventListener('mouseover', hover, true);
doc.addEventListener('mouseleave', leave, false); doc.addEventListener('mouseleave', leave, false);
@ -912,8 +916,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
/** /**
* @see ISimulator * @see ISimulator
*/ */
getComponentInstances(node: Node, context?: IPublicTypeNodeInstance): IPublicTypeComponentInstance[] | null { getComponentInstances(node: INode, context?: IPublicTypeNodeInstance): IPublicTypeComponentInstance[] | null {
const docId = node.document.id; const docId = node.document?.id;
if (!docId) {
return null;
}
const instances = this.instancesMap[docId]?.get(node.id) || null; const instances = this.instancesMap[docId]?.get(node.id) || null;
if (!instances || !context) { if (!instances || !context) {
@ -946,7 +953,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
/** /**
* @see ISimulator * @see ISimulator
*/ */
computeRect(node: Node): IPublicTypeRect | null { computeRect(node: INode): IPublicTypeRect | null {
const instances = this.getComponentInstances(node); const instances = this.getComponentInstances(node);
if (!instances) { if (!instances) {
return null; return null;
@ -1042,7 +1049,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
/** /**
* DOM simulator * DOM simulator
*/ */
getNodeInstanceFromElement(target: Element | null): IPublicTypeNodeInstance<IPublicTypeComponentInstance> | null { getNodeInstanceFromElement(target: Element | null): IPublicTypeNodeInstance<IPublicTypeComponentInstance, INode> | null {
if (!target) { if (!target) {
return null; return null;
} }
@ -1215,7 +1222,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
return null; return null;
} }
const dropContainer = this.getDropContainer(e); const dropContainer = this.getDropContainer(e);
const lockedNode = getClosestNode(dropContainer?.container as Node, (node) => node.isLocked); const lockedNode = getClosestNode(dropContainer?.container, (node) => node.isLocked);
if (lockedNode) return null; if (lockedNode) return null;
if ( if (
!dropContainer !dropContainer
@ -1257,7 +1264,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
e.dragObject && e.dragObject &&
e.dragObject.nodes && e.dragObject.nodes &&
e.dragObject.nodes.length && e.dragObject.nodes.length &&
e.dragObject.nodes[0].componentMeta.isModal e.dragObject.nodes[0].componentMeta.isModal &&
document.focusNode
) { ) {
return this.designer.createLocation({ return this.designer.createLocation({
target: document.focusNode, target: document.focusNode,
@ -1372,8 +1380,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
const isAny = isDragAnyObject(dragObject); const isAny = isDragAnyObject(dragObject);
const document = this.project.currentDocument!; const document = this.project.currentDocument!;
const { currentRoot } = document; const { currentRoot } = document;
let container: INode; let container: INode | null;
let nodeInstance: IPublicTypeNodeInstance<IPublicTypeComponentInstance> | undefined; let nodeInstance: IPublicTypeNodeInstance<IPublicTypeComponentInstance, INode> | undefined;
if (target) { if (target) {
const ref = this.getNodeInstanceFromElement(target); const ref = this.getNodeInstanceFromElement(target);
@ -1391,8 +1399,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
container = currentRoot; container = currentRoot;
} }
if (!container.isParental()) { if (!container?.isParental()) {
container = container.parent || currentRoot; container = container?.parent || currentRoot;
} }
// TODO: use spec container to accept specialData // TODO: use spec container to accept specialData
@ -1402,7 +1410,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
} }
// get common parent, avoid drop container contains by dragObject // get common parent, avoid drop container contains by dragObject
const drillDownExcludes = new Set<Node>(); const drillDownExcludes = new Set<INode>();
if (isDragNodeObject(dragObject)) { if (isDragNodeObject(dragObject)) {
const { nodes } = dragObject; const { nodes } = dragObject;
let i = nodes.length; let i = nodes.length;
@ -1414,7 +1422,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
} }
if (p !== container) { if (p !== container) {
container = p || document.focusNode; container = p || document.focusNode;
drillDownExcludes.add(container); container && drillDownExcludes.add(container);
} }
} }
@ -1425,11 +1433,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
} else { } else {
instance = this.getClosestNodeInstance( instance = this.getClosestNodeInstance(
nodeInstance.instance as any, nodeInstance.instance as any,
container.id, container?.id,
)?.instance; )?.instance;
} }
} else { } else {
instance = this.getComponentInstances(container)?.[0]; instance = container && this.getComponentInstances(container)?.[0];
} }
let dropContainer: DropContainer = { let dropContainer: DropContainer = {
@ -1457,7 +1465,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
container = container.parent; container = container.parent;
instance = this.getClosestNodeInstance(dropContainer.instance, container.id)?.instance; instance = this.getClosestNodeInstance(dropContainer.instance, container.id)?.instance;
dropContainer = { dropContainer = {
container: container as INode, container: container,
instance, instance,
}; };
} else { } else {
@ -1500,7 +1508,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
*/ */
getNearByContainer( getNearByContainer(
{ container, instance }: DropContainer, { container, instance }: DropContainer,
drillDownExcludes: Set<Node>, drillDownExcludes: Set<INode>,
e: ILocateEvent, e: ILocateEvent,
) { ) {
const { children } = container; const { children } = container;
@ -1519,7 +1527,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
} }
if (child.conditionGroup) { if (child.conditionGroup) {
const bn = child.conditionGroup; const bn = child.conditionGroup;
i = bn.index + bn.length - 1; i = (bn.index || 0) + bn.length - 1;
child = bn.visibleNode; child = bn.visibleNode;
} }
if (!child.isParental() || drillDownExcludes.has(child)) { if (!child.isParental() || drillDownExcludes.has(child)) {

View File

@ -1,5 +1,5 @@
import { Component } from '../simulator'; import { Component } from '../simulator';
import { IPublicTypeNodeSchema, IPublicTypeComponentInstance, IPublicTypeNodeInstance } from '@alilc/lowcode-types'; import { IPublicTypeNodeSchema, IPublicTypeComponentInstance, IPublicTypeNodeInstance, Asset } from '@alilc/lowcode-types';
export interface BuiltinSimulatorRenderer { export interface BuiltinSimulatorRenderer {
readonly isSimulatorRenderer: true; readonly isSimulatorRenderer: true;
@ -22,6 +22,7 @@ export interface BuiltinSimulatorRenderer {
stopAutoRepaintNode(): void; stopAutoRepaintNode(): void;
enableAutoRepaintNode(): void; enableAutoRepaintNode(): void;
run(): void; run(): void;
load(asset: Asset): Promise<any>;
} }
export function isSimulatorRenderer(obj: any): obj is BuiltinSimulatorRenderer { export function isSimulatorRenderer(obj: any): obj is BuiltinSimulatorRenderer {

View File

@ -1,5 +1,5 @@
import { getClosestNode, canClickNode } from '@alilc/lowcode-utils'; import { getClosestNode, canClickNode } from '@alilc/lowcode-utils';
import { Node } from '../../document'; import { INode } from '../../document';
/** /**
* *
@ -7,7 +7,7 @@ import { Node } from '../../document';
* @param event * @param event
*/ */
export const getClosestClickableNode = ( export const getClosestClickableNode = (
currentNode: Node | undefined | null, currentNode: INode | undefined | null,
event: MouseEvent, event: MouseEvent,
) => { ) => {
let node = currentNode; let node = currentNode;

View File

@ -58,6 +58,10 @@ export function buildFilter(rule?: string | string[] | RegExp | IPublicTypeNesti
export interface IComponentMeta extends IPublicModelComponentMeta<INode> { export interface IComponentMeta extends IPublicModelComponentMeta<INode> {
prototype?: any; prototype?: any;
setMetadata(metadata: IPublicTypeComponentMetadata): void;
get rootSelector(): string | undefined;
} }
export class ComponentMeta implements IComponentMeta { export class ComponentMeta implements IComponentMeta {
@ -332,7 +336,7 @@ export class ComponentMeta implements IComponentMeta {
if (this.parentWhitelist) { if (this.parentWhitelist) {
return this.parentWhitelist( return this.parentWhitelist(
parent.internalToShellNode(), parent.internalToShellNode(),
isNode(my) ? my.internalToShellNode() : my, isNode<INode>(my) ? my.internalToShellNode() : my,
); );
} }
return true; return true;
@ -343,7 +347,7 @@ export class ComponentMeta implements IComponentMeta {
if (this.childWhitelist) { if (this.childWhitelist) {
const _target: any = !Array.isArray(target) ? [target] : target; const _target: any = !Array.isArray(target) ? [target] : target;
return _target.every((item: Node | IPublicTypeNodeSchema) => { return _target.every((item: Node | IPublicTypeNodeSchema) => {
const _item = !isNode(item) ? new Node(my.document, item) : item; const _item = !isNode<INode>(item) ? new Node(my.document, item) : item;
return ( return (
this.childWhitelist && this.childWhitelist &&
this.childWhitelist(_item.internalToShellNode(), my.internalToShellNode()) this.childWhitelist(_item.internalToShellNode(), my.internalToShellNode())

View File

@ -18,6 +18,7 @@ import {
IPublicEnumTransformStage, IPublicEnumTransformStage,
IPublicModelDragon, IPublicModelDragon,
IPublicModelDropLocation, IPublicModelDropLocation,
IPublicModelLocateEvent,
} from '@alilc/lowcode-types'; } from '@alilc/lowcode-types';
import { megreAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; import { megreAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils';
import { Project } from '../project'; import { Project } from '../project';
@ -45,15 +46,15 @@ export interface DesignerProps {
defaultSchema?: IPublicTypeProjectSchema; defaultSchema?: IPublicTypeProjectSchema;
hotkeys?: object; hotkeys?: object;
viewName?: string; viewName?: string;
simulatorProps?: object | ((document: DocumentModel) => object); simulatorProps?: Record<string, any> | ((document: DocumentModel) => object);
simulatorComponent?: ComponentType<any>; simulatorComponent?: ComponentType<any>;
dragGhostComponent?: ComponentType<any>; dragGhostComponent?: ComponentType<any>;
suspensed?: boolean; suspensed?: boolean;
componentMetadatas?: IPublicTypeComponentMetadata[]; componentMetadatas?: IPublicTypeComponentMetadata[];
globalComponentActions?: IPublicTypeComponentAction[]; globalComponentActions?: IPublicTypeComponentAction[];
onMount?: (designer: Designer) => void; onMount?: (designer: Designer) => void;
onDragstart?: (e: ILocateEvent) => void; onDragstart?: (e: IPublicModelLocateEvent) => void;
onDrag?: (e: ILocateEvent) => void; onDrag?: (e: IPublicModelLocateEvent) => void;
onDragend?: ( onDragend?: (
e: { dragObject: IPublicModelDragObject; copy: boolean }, e: { dragObject: IPublicModelDragObject; copy: boolean },
loc?: DropLocation, loc?: DropLocation,
@ -73,12 +74,14 @@ export interface IDesigner {
get detecting(): Detecting; get detecting(): Detecting;
get simulatorComponent(): ComponentType<any> | undefined;
createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller; createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller;
/** /**
* dragon * dragon
*/ */
createLocation(locationData: IPublicTypeLocationData): IPublicModelDropLocation; createLocation(locationData: IPublicTypeLocationData<INode>): DropLocation;
get componentsMap(): { [key: string]: IPublicTypeNpmInfo | Component }; get componentsMap(): { [key: string]: IPublicTypeNpmInfo | Component };
@ -100,6 +103,8 @@ export interface IDesigner {
transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage): IPublicTypeCompositeObject | IPublicTypePropsList; transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage): IPublicTypeCompositeObject | IPublicTypePropsList;
createSettingEntry(nodes: INode[]): ISettingTopEntry; createSettingEntry(nodes: INode[]): ISettingTopEntry;
autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions<any, any>): IReactionDisposer;
} }
export class Designer implements IDesigner { export class Designer implements IDesigner {
@ -196,7 +201,7 @@ export class Designer implements IDesigner {
const loc = this._dropLocation; const loc = this._dropLocation;
if (loc) { if (loc) {
if (isLocationChildrenDetail(loc.detail) && loc.detail.valid !== false) { if (isLocationChildrenDetail(loc.detail) && loc.detail.valid !== false) {
let nodes: Node[] | undefined; let nodes: INode[] | undefined;
if (isDragNodeObject(dragObject)) { if (isDragNodeObject(dragObject)) {
nodes = insertChildren(loc.target, [...dragObject.nodes], loc.detail.index, copy); nodes = insertChildren(loc.target, [...dragObject.nodes], loc.detail.index, copy);
} else if (isDragNodeDataObject(dragObject)) { } else if (isDragNodeDataObject(dragObject)) {
@ -209,7 +214,7 @@ export class Designer implements IDesigner {
nodes = insertChildren(loc.target, nodeData, loc.detail.index); nodes = insertChildren(loc.target, nodeData, loc.detail.index);
} }
if (nodes) { if (nodes) {
loc.document.selection.selectAll(nodes.map((o) => o.id)); loc.document?.selection.selectAll(nodes.map((o) => o.id));
setTimeout(() => this.activeTracker.track(nodes![0]), 10); setTimeout(() => this.activeTracker.track(nodes![0]), 10);
} }
} }
@ -222,7 +227,7 @@ export class Designer implements IDesigner {
}); });
this.activeTracker.onChange(({ node, detail }) => { this.activeTracker.onChange(({ node, detail }) => {
node.document.simulator?.scrollToNode(node, detail); node.document?.simulator?.scrollToNode(node, detail);
}); });
let historyDispose: undefined | (() => void); let historyDispose: undefined | (() => void);
@ -264,8 +269,8 @@ export class Designer implements IDesigner {
currentSelection.selected.length === 0 && currentSelection.selected.length === 0 &&
this.simulatorProps?.designMode === 'live' this.simulatorProps?.designMode === 'live'
) { ) {
const rootNodeChildrens = this.currentDocument.getRoot().getChildren().children; const rootNodeChildrens = this.currentDocument?.getRoot()?.getChildren()?.children;
if (rootNodeChildrens.length > 0) { if (rootNodeChildrens && rootNodeChildrens.length > 0) {
currentSelection.select(rootNodeChildrens[0].id); currentSelection.select(rootNodeChildrens[0].id);
} }
} }
@ -288,14 +293,16 @@ export class Designer implements IDesigner {
/** /**
* dragon * dragon
*/ */
createLocation(locationData: IPublicTypeLocationData): DropLocation { createLocation(locationData: IPublicTypeLocationData<INode>): DropLocation {
const loc = new DropLocation(locationData); const loc = new DropLocation(locationData);
if (this._dropLocation && this._dropLocation.document !== loc.document) { if (this._dropLocation && this._dropLocation.document && this._dropLocation.document !== loc.document) {
this._dropLocation.document.dropLocation = null; this._dropLocation.document.dropLocation = null;
} }
this._dropLocation = loc; this._dropLocation = loc;
this.postEvent('dropLocation.change', loc); this.postEvent('dropLocation.change', loc);
loc.document.dropLocation = loc; if (loc.document) {
loc.document.dropLocation = loc;
}
this.activeTracker.track({ node: loc.target, detail: loc.detail }); this.activeTracker.track({ node: loc.target, detail: loc.detail });
return loc; return loc;
} }
@ -304,7 +311,7 @@ export class Designer implements IDesigner {
* *
*/ */
clearLocation() { clearLocation() {
if (this._dropLocation) { if (this._dropLocation && this._dropLocation.document) {
this._dropLocation.document.dropLocation = null; this._dropLocation.document.dropLocation = null;
} }
this.postEvent('dropLocation.change', undefined); this.postEvent('dropLocation.change', undefined);
@ -376,7 +383,7 @@ export class Designer implements IDesigner {
} else { } else {
// FIXME!!, parent maybe null // FIXME!!, parent maybe null
target = refNode.parent!; target = refNode.parent!;
index = refNode.index + 1; index = (refNode.index || 0) + 1;
} }
if (target && insertNode && !target.componentMeta.checkNestingDown(target, insertNode)) { if (target && insertNode && !target.componentMeta.checkNestingDown(target, insertNode)) {
@ -467,7 +474,7 @@ export class Designer implements IDesigner {
return this._simulatorComponent; return this._simulatorComponent;
} }
@computed get simulatorProps(): object { @computed get simulatorProps(): Record<string, any> {
if (typeof this._simulatorProps === 'function') { if (typeof this._simulatorProps === 'function') {
return this._simulatorProps(this.project); return this._simulatorProps(this.project);
} }
@ -622,7 +629,7 @@ export class Designer implements IDesigner {
} }
} }
autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions): IReactionDisposer { autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions<any, any>): IReactionDisposer {
return autorun(effect, options); return autorun(effect, options);
} }

View File

@ -23,7 +23,6 @@ export interface ILocateEvent extends IPublicModelLocateEvent {
* *
*/ */
sensor?: IPublicModelSensor; sensor?: IPublicModelSensor;
} }
/** /**
@ -97,7 +96,7 @@ function isDragEvent(e: any): e is DragEvent {
} }
export interface IDragon extends IPublicModelDragon { export interface IDragon extends IPublicModelDragon {
emitter: IEventBus;
} }
/** /**
@ -106,6 +105,8 @@ export interface IDragon extends IPublicModelDragon {
export class Dragon implements IDragon { export class Dragon implements IDragon {
private sensors: IPublicModelSensor[] = []; private sensors: IPublicModelSensor[] = [];
private nodeInstPointerEvents: boolean;
key = Math.random(); key = Math.random();
/** /**
@ -127,7 +128,7 @@ export class Dragon implements IDragon {
viewName: string | undefined; viewName: string | undefined;
private emitter: IEventBus = createModuleEventBus('Dragon'); emitter: IEventBus = createModuleEventBus('Dragon');
constructor(readonly designer: Designer) { constructor(readonly designer: Designer) {
makeObservable(this); makeObservable(this);
@ -356,8 +357,8 @@ export class Dragon implements IDragon {
rglNode, rglNode,
node: tarNode, node: tarNode,
}); });
const { selection } = designer.project.currentDocument; const selection = designer.project.currentDocument?.selection;
selection.select(tarNode.id); selection?.select(tarNode.id);
} }
} }
} }

View File

@ -122,7 +122,7 @@ export class DropLocation implements IDropLocation {
return this.target.document; return this.target.document;
} }
constructor({ target, detail, source, event }: IPublicTypeLocationData) { constructor({ target, detail, source, event }: IPublicTypeLocationData<INode>) {
this.target = target; this.target = target;
this.detail = detail; this.detail = detail;
this.source = source; this.source = source;

View File

@ -1,17 +1,26 @@
import { IPublicModelSettingTarget } from '@alilc/lowcode-types'; import { IBaseModelSettingEntry, IPublicModelSettingPropEntry, IPublicTypeSetValueOptions } from '@alilc/lowcode-types';
import { IComponentMeta } from '../../component-meta'; import { IComponentMeta } from '../../component-meta';
import { Designer } from '../designer'; import { IDesigner } from '../designer';
import { INode } from '../../document'; import { INode } from '../../document';
export interface ISettingEntry extends IPublicModelSettingTarget { export interface ISettingEntry extends IBaseModelSettingEntry<
readonly nodes: INode[]; INode,
readonly componentMeta: IComponentMeta | null; IComponentMeta,
readonly designer: Designer; ISettingEntry
> {
readonly designer: IDesigner;
// 顶端 readonly isGroup: boolean;
readonly top: ISettingEntry;
// 父级
readonly parent: ISettingEntry;
get: (propName: string | number) => ISettingEntry | null; readonly id: string;
get name(): string | number | undefined;
internalToShellPropEntry(): IPublicModelSettingPropEntry;
valueChange(options: IPublicTypeSetValueOptions): void;
get valueState(): number;
clearValue(): void;
} }

View File

@ -1,3 +1,4 @@
import { ReactNode } from 'react';
import { import {
IPublicTypeTitleContent, IPublicTypeTitleContent,
IPublicTypeSetterType, IPublicTypeSetterType,
@ -25,8 +26,29 @@ function getSettingFieldCollectorKey(parent: ISettingEntry, config: IPublicTypeF
return path.join('.'); return path.join('.');
} }
export interface ISettingField extends ISettingEntry { export interface ISettingField extends Omit<ISettingEntry, 'setValue'> {
get items(): Array<ISettingField | IPublicTypeCustomView>;
get title(): string | ReactNode | undefined;
purge(): void;
extraProps: IPublicTypeFieldExtraProps;
get setter(): IPublicTypeSetterType | null;
get expanded(): boolean;
readonly isRequired: boolean;
setExpanded(value: boolean): void;
setValue(
val: any,
isHotValue?: boolean,
force?: boolean,
extraOptions?: IPublicTypeSetValueOptions,
): void;
} }
export class SettingField extends SettingPropEntry implements ISettingField { export class SettingField extends SettingPropEntry implements ISettingField {
@ -57,12 +79,12 @@ export class SettingField extends SettingPropEntry implements ISettingField {
@obx.ref private _expanded = true; @obx.ref private _expanded = true;
private _items: Array<SettingField | IPublicTypeCustomView> = []; private _items: Array<ISettingField | IPublicTypeCustomView> = [];
constructor( constructor(
parent: ISettingEntry, parent: ISettingEntry,
config: IPublicTypeFieldConfig, config: IPublicTypeFieldConfig,
private settingFieldCollector?: (name: string | number, field: SettingField) => void, private settingFieldCollector?: (name: string | number, field: ISettingField) => void,
) { ) {
super(parent, config.name, config.type); super(parent, config.name, config.type);
makeObservable(this); makeObservable(this);
@ -97,7 +119,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
if (isDynamicSetter(this._setter)) { if (isDynamicSetter(this._setter)) {
return untracked(() => { return untracked(() => {
const shellThis = this.internalToShellPropEntry(); const shellThis = this.internalToShellPropEntry();
return this._setter.call(shellThis, shellThis); return (this._setter as IPublicTypeDynamicSetter)?.call(shellThis, shellThis);
}); });
} }
return this._setter; return this._setter;
@ -111,7 +133,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
this._expanded = value; this._expanded = value;
} }
get items(): Array<SettingField | IPublicTypeCustomView> { get items(): Array<ISettingField | IPublicTypeCustomView> {
return this._items; return this._items;
} }
@ -122,8 +144,8 @@ export class SettingField extends SettingPropEntry implements ISettingField {
private initItems( private initItems(
items: Array<IPublicTypeFieldConfig | IPublicTypeCustomView>, items: Array<IPublicTypeFieldConfig | IPublicTypeCustomView>,
settingFieldCollector?: { settingFieldCollector?: {
(name: string | number, field: SettingField): void; (name: string | number, field: ISettingField): void;
(name: string, field: SettingField): void; (name: string, field: ISettingField): void;
}, },
) { ) {
this._items = items.map((item) => { this._items = items.map((item) => {
@ -140,7 +162,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
} }
// 创建子配置项,通常用于 object/array 类型数据 // 创建子配置项,通常用于 object/array 类型数据
createField(config: IPublicTypeFieldConfig): SettingField { createField(config: IPublicTypeFieldConfig): ISettingField {
this.settingFieldCollector?.(getSettingFieldCollectorKey(this.parent, config), this); this.settingFieldCollector?.(getSettingFieldCollectorKey(this.parent, config), this);
return new SettingField(this, config, this.settingFieldCollector); return new SettingField(this, config, this.settingFieldCollector);
} }
@ -161,8 +183,8 @@ export class SettingField extends SettingPropEntry implements ISettingField {
} }
getItems( getItems(
filter?: (item: SettingField | IPublicTypeCustomView) => boolean, filter?: (item: ISettingField | IPublicTypeCustomView) => boolean,
): Array<SettingField | IPublicTypeCustomView> { ): Array<ISettingField | IPublicTypeCustomView> {
return this._items.filter((item) => { return this._items.filter((item) => {
if (filter) { if (filter) {
return filter(item); return filter(item);
@ -252,6 +274,6 @@ export class SettingField extends SettingPropEntry implements ISettingField {
/** /**
* @deprecated use same function from '@alilc/lowcode-utils' instead * @deprecated use same function from '@alilc/lowcode-utils' instead
*/ */
export function isSettingField(obj: any): obj is SettingField { export function isSettingField(obj: any): obj is ISettingField {
return obj && obj.isSettingField; return obj && obj.isSettingField;
} }

View File

@ -1,11 +1,10 @@
import { obx, computed, makeObservable, runInAction, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { obx, computed, makeObservable, runInAction, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
import { GlobalEvent, IPublicModelEditor, IPublicTypeSetValueOptions } from '@alilc/lowcode-types'; import { GlobalEvent, IPublicApiSetters, IPublicModelEditor, IPublicTypeSetValueOptions } from '@alilc/lowcode-types';
import { uniqueId, isJSExpression, isSettingField } from '@alilc/lowcode-utils'; import { uniqueId, isJSExpression, isSettingField } from '@alilc/lowcode-utils';
import { Setters } from '@alilc/lowcode-shell';
import { ISettingEntry } from './setting-entry'; import { ISettingEntry } from './setting-entry';
import { INode } from '../../document'; import { INode } from '../../document';
import { IComponentMeta } from '../../component-meta'; import { IComponentMeta } from '../../component-meta';
import { Designer } from '../designer'; import { IDesigner } from '../designer';
import { ISettingField } from './setting-field'; import { ISettingField } from './setting-field';
export class SettingPropEntry implements ISettingEntry { export class SettingPropEntry implements ISettingEntry {
@ -18,13 +17,13 @@ export class SettingPropEntry implements ISettingEntry {
readonly isSingle: boolean; readonly isSingle: boolean;
readonly setters: Setters; readonly setters: IPublicApiSetters;
readonly nodes: INode[]; readonly nodes: INode[];
readonly componentMeta: IComponentMeta | null; readonly componentMeta: IComponentMeta | null;
readonly designer: Designer; readonly designer: IDesigner;
readonly top: ISettingEntry; readonly top: ISettingEntry;
@ -37,7 +36,7 @@ export class SettingPropEntry implements ISettingEntry {
readonly emitter: IEventBus = createModuleEventBus('SettingPropEntry'); readonly emitter: IEventBus = createModuleEventBus('SettingPropEntry');
// ==== dynamic properties ==== // ==== dynamic properties ====
@obx.ref private _name: string | number; @obx.ref private _name: string | number | undefined;
get name() { get name() {
return this._name; return this._name;
@ -45,7 +44,7 @@ export class SettingPropEntry implements ISettingEntry {
@computed get path() { @computed get path() {
const path = this.parent.path.slice(); const path = this.parent.path.slice();
if (this.type === 'field') { if (this.type === 'field' && this.name) {
path.push(this.name); path.push(this.name);
} }
return path; return path;
@ -53,7 +52,7 @@ export class SettingPropEntry implements ISettingEntry {
extraProps: any = {}; extraProps: any = {};
constructor(readonly parent: ISettingEntry | ISettingField, name: string | number, type?: 'field' | 'group') { constructor(readonly parent: ISettingEntry | ISettingField, name: string | number | undefined, type?: 'field' | 'group') {
makeObservable(this); makeObservable(this);
if (type == null) { if (type == null) {
const c = typeof name === 'string' ? name.slice(0, 1) : ''; const c = typeof name === 'string' ? name.slice(0, 1) : '';
@ -161,7 +160,7 @@ export class SettingPropEntry implements ISettingEntry {
*/ */
getValue(): any { getValue(): any {
let val: any; let val: any;
if (this.type === 'field') { if (this.type === 'field' && this.name) {
val = this.parent.getPropValue(this.name); val = this.parent.getPropValue(this.name);
} }
const { getValue } = this.extraProps; const { getValue } = this.extraProps;
@ -179,7 +178,7 @@ export class SettingPropEntry implements ISettingEntry {
setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: IPublicTypeSetValueOptions) { setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: IPublicTypeSetValueOptions) {
const oldValue = this.getValue(); const oldValue = this.getValue();
if (this.type === 'field') { if (this.type === 'field') {
this.parent.setPropValue(this.name, val); this.name && this.parent.setPropValue(this.name, val);
} }
const { setValue } = this.extraProps; const { setValue } = this.extraProps;
@ -203,7 +202,7 @@ export class SettingPropEntry implements ISettingEntry {
*/ */
clearValue() { clearValue() {
if (this.type === 'field') { if (this.type === 'field') {
this.parent.clearPropValue(this.name); this.name && this.parent.clearPropValue(this.name);
} }
const { setValue } = this.extraProps; const { setValue } = this.extraProps;
if (setValue) { if (setValue) {

View File

@ -39,7 +39,7 @@ import { IProject, Project } from '../project';
import { ISimulatorHost } from '../simulator'; import { ISimulatorHost } from '../simulator';
import { IComponentMeta } from '../component-meta'; import { IComponentMeta } from '../component-meta';
import { IDesigner, IHistory } from '../designer'; import { IDesigner, IHistory } from '../designer';
import { insertChildren, insertChild, RootNode, INode } from './node/node'; import { insertChildren, insertChild, IRootNode, INode } from './node/node';
import { Selection, ISelection } from './selection'; import { Selection, ISelection } from './selection';
import { History } from './history'; import { History } from './history';
import { IModalNodesManager, ModalNodesManager, Node } from './node'; import { IModalNodesManager, ModalNodesManager, Node } from './node';
@ -56,7 +56,7 @@ export type GetDataType<T, NodeType> = T extends undefined
export interface IDocumentModel extends Omit< IPublicModelDocumentModel< export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
ISelection, ISelection,
IHistory, IHistory,
INode | RootNode, INode | IRootNode,
IDropLocation, IDropLocation,
IModalNodesManager, IModalNodesManager,
IProject IProject
@ -89,11 +89,26 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
get nodesMap(): Map<string, INode>; get nodesMap(): Map<string, INode>;
/**
*
*/
get suspensed(): boolean;
get fileName(): string;
get currentRoot(): INode | null;
selection: ISelection;
isBlank(): boolean;
/** /**
* id * id
*/ */
getNode(id: string): INode | null; getNode(id: string): INode | null;
getRoot(): INode | null;
getHistory(): IHistory; getHistory(): IHistory;
checkNesting( checkNesting(
@ -122,13 +137,21 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
getComponentMeta(componentName: string): IComponentMeta; getComponentMeta(componentName: string): IComponentMeta;
insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean): INode[]; insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean): INode[];
open(): DocumentModel;
remove(): void;
suspense(): void;
close(): void;
} }
export class DocumentModel implements IDocumentModel { export class DocumentModel implements IDocumentModel {
/** /**
* Page/Component/Block * Page/Component/Block
*/ */
rootNode: INode | null; rootNode: IRootNode | null;
/** /**
* *
@ -280,7 +303,7 @@ export class DocumentModel implements IDocumentModel {
return this.rootNode; return this.rootNode;
} }
constructor(project: Project, schema?: IPublicTypeRootSchema) { constructor(project: IProject, schema?: IPublicTypeRootSchema) {
makeObservable(this); makeObservable(this);
this.project = project; this.project = project;
this.designer = this.project?.designer; this.designer = this.project?.designer;
@ -346,7 +369,7 @@ export class DocumentModel implements IDocumentModel {
} }
isBlank() { isBlank() {
return this._blank && !this.isModified(); return !!(this._blank && !this.isModified());
} }
/** /**
@ -552,7 +575,7 @@ export class DocumentModel implements IDocumentModel {
/** /**
* *
*/ */
isModified() { isModified(): boolean {
return this.history.isSavePoint(); return this.history.isSavePoint();
} }
@ -641,7 +664,7 @@ export class DocumentModel implements IDocumentModel {
items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data]; items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
} else if (isDragNodeObject<INode>(dragObject)) { } else if (isDragNodeObject<INode>(dragObject)) {
items = dragObject.nodes; items = dragObject.nodes;
} else if (isNode(dragObject) || isNodeSchema(dragObject)) { } else if (isNode<INode>(dragObject) || isNodeSchema(dragObject)) {
items = [dragObject]; items = [dragObject];
} else { } else {
console.warn('the dragObject is not in the correct type, dragObject:', dragObject); console.warn('the dragObject is not in the correct type, dragObject:', dragObject);
@ -760,7 +783,7 @@ export class DocumentModel implements IDocumentModel {
/* istanbul ignore next */ /* istanbul ignore next */
acceptRootNodeVisitor( acceptRootNodeVisitor(
visitorName = 'default', visitorName = 'default',
visitorFn: (node: RootNode) => any, visitorFn: (node: IRootNode) => any,
) { ) {
let visitorResult = {}; let visitorResult = {};
if (!visitorName) { if (!visitorName) {
@ -768,8 +791,10 @@ export class DocumentModel implements IDocumentModel {
console.warn('Invalid or empty RootNodeVisitor name.'); console.warn('Invalid or empty RootNodeVisitor name.');
} }
try { try {
visitorResult = visitorFn.call(this, this.rootNode); if (this.rootNode) {
this.rootNodeVisitorMap[visitorName] = visitorResult; visitorResult = visitorFn.call(this, this.rootNode);
this.rootNodeVisitorMap[visitorName] = visitorResult;
}
} catch (e) { } catch (e) {
console.error('RootNodeVisitor is not valid.'); console.error('RootNodeVisitor is not valid.');
console.error(e); console.error(e);
@ -864,7 +889,7 @@ export class DocumentModel implements IDocumentModel {
console.warn('onRefresh method is deprecated'); console.warn('onRefresh method is deprecated');
} }
onReady(fn: Function) { onReady(fn: (...args: any[]) => void) {
this.designer.editor.eventBus.on('document-open', fn); this.designer.editor.eventBus.on('document-open', fn);
return () => { return () => {
this.designer.editor.eventBus.off('document-open', fn); this.designer.editor.eventBus.off('document-open', fn);
@ -876,7 +901,7 @@ export class DocumentModel implements IDocumentModel {
} }
} }
export function isDocumentModel(obj: any): obj is DocumentModel { export function isDocumentModel(obj: any): obj is IDocumentModel {
return obj && obj.rootNode; return obj && obj.rootNode;
} }

View File

@ -1,11 +1,11 @@
import { Component } from 'react'; import { Component } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { observer } from '@alilc/lowcode-editor-core'; import { observer } from '@alilc/lowcode-editor-core';
import { DocumentModel } from './document-model'; import { DocumentModel, IDocumentModel } from './document-model';
import { BuiltinSimulatorHostView } from '../builtin-simulator'; import { BuiltinSimulatorHostView } from '../builtin-simulator';
@observer @observer
export class DocumentView extends Component<{ document: DocumentModel }> { export class DocumentView extends Component<{ document: IDocumentModel }> {
render() { render() {
const { document } = this.props; const { document } = this.props;
const { simulatorProps } = document; const { simulatorProps } = document;
@ -26,7 +26,7 @@ export class DocumentView extends Component<{ document: DocumentModel }> {
} }
} }
class DocumentInfoView extends Component<{ document: DocumentModel }> { class DocumentInfoView extends Component<{ document: IDocumentModel }> {
render() { render() {
return null; return null;
} }

View File

@ -1,5 +1,5 @@
import { reaction, untracked, globalContext, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { reaction, untracked, globalContext, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
import { IPublicTypeNodeSchema, IPublicModelHistory } from '@alilc/lowcode-types'; import { IPublicTypeNodeSchema, IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types';
import { Logger } from '@alilc/lowcode-utils'; import { Logger } from '@alilc/lowcode-utils';
const logger = new Logger({ level: 'warn', bizName: 'history' }); const logger = new Logger({ level: 'warn', bizName: 'history' });
@ -10,7 +10,7 @@ export interface Serialization<K = IPublicTypeNodeSchema, T = string> {
} }
export interface IHistory extends IPublicModelHistory { export interface IHistory extends IPublicModelHistory {
onStateChange(func: () => any): IPublicTypeDisposable;
} }
export class History<T = IPublicTypeNodeSchema> implements IHistory { export class History<T = IPublicTypeNodeSchema> implements IHistory {
@ -189,11 +189,11 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
* @param func * @param func
* @returns * @returns
*/ */
onChangeState(func: () => any): () => void { onChangeState(func: () => any): IPublicTypeDisposable {
return this.onStateChange(func); return this.onStateChange(func);
} }
onStateChange(func: () => any): () => void { onStateChange(func: () => any): IPublicTypeDisposable {
this.emitter.on('statechange', func); this.emitter.on('statechange', func);
return () => { return () => {
this.emitter.removeListener('statechange', func); this.emitter.removeListener('statechange', func);
@ -205,7 +205,7 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
* @param func * @param func
* @returns * @returns
*/ */
onChangeCursor(func: () => any): () => void { onChangeCursor(func: () => any): IPublicTypeDisposable {
return this.onCursor(func); return this.onCursor(func);
} }

View File

@ -7,11 +7,17 @@ import { intl } from '../../locale';
export interface IExclusiveGroup extends IPublicModelExclusiveGroup<INode> { export interface IExclusiveGroup extends IPublicModelExclusiveGroup<INode> {
readonly name: string; readonly name: string;
get index(): number | undefined;
remove(node: INode): void; remove(node: INode): void;
add(node: INode): void; add(node: INode): void;
isVisible(node: INode): boolean; isVisible(node: INode): boolean;
get length(): number;
get visibleNode(): INode;
} }
// modals assoc x-hide value, initial: check is Modal, yes will put it in modals, cross levels // modals assoc x-hide value, initial: check is Modal, yes will put it in modals, cross levels

View File

@ -20,6 +20,8 @@ export interface INodeChildren extends Omit<IPublicModelNodeChildren<INode>,
get length(): number; get length(): number;
children: INode[];
unlinkChild(node: INode): void; unlinkChild(node: INode): void;
/** /**
@ -65,7 +67,7 @@ export interface INodeChildren extends Omit<IPublicModelNodeChildren<INode>,
/** overriding methods end */ /** overriding methods end */
} }
export class NodeChildren implements INodeChildren { export class NodeChildren implements INodeChildren {
@obx.shallow private children: INode[]; @obx.shallow children: INode[];
private emitter: IEventBus = createModuleEventBus('NodeChildren'); private emitter: IEventBus = createModuleEventBus('NodeChildren');

View File

@ -37,9 +37,9 @@ export interface NodeStatus {
inPlaceEditing: boolean; inPlaceEditing: boolean;
} }
export interface INode extends Omit<IBaseModelNode< export interface IBaseNode<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> extends Omit<IBaseModelNode<
IDocumentModel, IDocumentModel,
INode, IBaseNode,
INodeChildren, INodeChildren,
IComponentMeta, IComponentMeta,
ISettingTopEntry, ISettingTopEntry,
@ -77,6 +77,10 @@ export interface INode extends Omit<IBaseModelNode<
get isPurging(): boolean; get isPurging(): boolean;
getId(): string;
getParent(): INode | null;
/** /**
* 使 * 使
* @param useMutator * @param useMutator
@ -147,6 +151,8 @@ export interface INode extends Omit<IBaseModelNode<
setVisible(flag: boolean): void; setVisible(flag: boolean): void;
getVisible(): boolean; getVisible(): boolean;
getChildren(): INodeChildren | null;
} }
/** /**
@ -1352,16 +1358,17 @@ export interface LeafNode extends Node {
export type IPublicTypePropChangeOptions = Omit<GlobalEvent.Node.Prop.ChangeOptions, 'node'>; export type IPublicTypePropChangeOptions = Omit<GlobalEvent.Node.Prop.ChangeOptions, 'node'>;
export type SlotNode = Node<IPublicTypeSlotSchema>; export type ISlotNode = IBaseNode<IPublicTypeSlotSchema>;
export type PageNode = Node<IPublicTypePageSchema>; export type IPageNode = IBaseNode<IPublicTypePageSchema>;
export type ComponentNode = Node<IPublicTypeComponentSchema>; export type IComponentNode = IBaseNode<IPublicTypeComponentSchema>;
export type RootNode = PageNode | ComponentNode; export type IRootNode = IPageNode | IComponentNode;
export type INode = IPageNode | ISlotNode | IComponentNode | IRootNode;
export function isRootNode(node: INode): node is INode { export function isRootNode(node: INode): node is IRootNode {
return node && node.isRootNode; return node && node.isRootNode;
} }
export function isLowCodeComponent(node: INode): node is INode { export function isLowCodeComponent(node: INode): node is IComponentNode {
return node.componentMeta?.getMetadata().devMode === 'lowCode'; return node.componentMeta?.getMetadata().devMode === 'lowCode';
} }
@ -1446,7 +1453,7 @@ export function insertChild(
at?: number | null, at?: number | null,
copy?: boolean, copy?: boolean,
): INode | null { ): INode | null {
let node: INode | null | RootNode | undefined; let node: INode | null | IRootNode | undefined;
let nodeSchema: IPublicTypeNodeSchema; let nodeSchema: IPublicTypeNodeSchema;
if (isNode<INode>(thing) && (copy || thing.isSlot())) { if (isNode<INode>(thing) && (copy || thing.isSlot())) {
nodeSchema = thing.export(IPublicEnumTransformStage.Clone); nodeSchema = thing.export(IPublicEnumTransformStage.Clone);

View File

@ -1,9 +1,9 @@
import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core'; import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core';
import { IPublicTypeCompositeValue, GlobalEvent, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicEnumTransformStage, IPublicModelProp } from '@alilc/lowcode-types'; import { IPublicTypeCompositeValue, GlobalEvent, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicEnumTransformStage, IPublicModelProp } from '@alilc/lowcode-types';
import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot } from '@alilc/lowcode-utils'; import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot, isNodeSchema } from '@alilc/lowcode-utils';
import { valueToSource } from './value-to-source'; import { valueToSource } from './value-to-source';
import { IProps, IPropParent } from './props'; import { IProps, IPropParent } from './props';
import { SlotNode, INode } from '../node'; import { ISlotNode, INode } from '../node';
// import { TransformStage } from '../transform-stage'; // import { TransformStage } from '../transform-stage';
const { set: mobxSet, isObservableArray } = mobx; const { set: mobxSet, isObservableArray } = mobx;
@ -30,6 +30,12 @@ export interface IProp extends Omit<IPublicModelProp<
unset(): void; unset(): void;
get value(): IPublicTypeCompositeValue | UNSET; get value(): IPublicTypeCompositeValue | UNSET;
compare(other: IProp | null): number;
isUnset(): boolean;
key: string | number | undefined;
} }
export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot'; export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot';
@ -402,7 +408,7 @@ export class Prop implements IProp, IPropParent {
this._type = 'slot'; this._type = 'slot';
let slotSchema: IPublicTypeSlotSchema; let slotSchema: IPublicTypeSlotSchema;
// 当 data.value 的结构为 { componentName: 'Slot' } 时,复用部分 slotSchema 数据 // 当 data.value 的结构为 { componentName: 'Slot' } 时,复用部分 slotSchema 数据
if ((isPlainObject(data.value) && data.value?.componentName === 'Slot')) { if ((isPlainObject(data.value) && isNodeSchema(data.value) && data.value?.componentName === 'Slot')) {
const value = data.value as IPublicTypeSlotSchema; const value = data.value as IPublicTypeSlotSchema;
slotSchema = { slotSchema = {
componentName: 'Slot', componentName: 'Slot',
@ -427,7 +433,7 @@ export class Prop implements IProp, IPropParent {
this._slotNode.import(slotSchema); this._slotNode.import(slotSchema);
} else { } else {
const { owner } = this.props; const { owner } = this.props;
this._slotNode = owner.document.createNode<SlotNode>(slotSchema); this._slotNode = owner.document.createNode<ISlotNode>(slotSchema);
if (this._slotNode) { if (this._slotNode) {
owner.addSlot(this._slotNode); owner.addSlot(this._slotNode);
this._slotNode.internalSetSlotFor(this); this._slotNode.internalSetSlotFor(this);

View File

@ -4,7 +4,7 @@ import { DocumentModel } from './document-model';
import { IPublicModelSelection } from '@alilc/lowcode-types'; import { IPublicModelSelection } from '@alilc/lowcode-types';
export interface ISelection extends Omit<IPublicModelSelection<INode>, 'node'> { export interface ISelection extends Omit<IPublicModelSelection<INode>, 'node'> {
containsNode(node: INode, excludeRoot: boolean): boolean;
} }
export class Selection implements ISelection { export class Selection implements ISelection {

View File

@ -12,7 +12,9 @@ import {
import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils'; import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils';
import { ISimulatorHost } from '../simulator'; import { ISimulatorHost } from '../simulator';
export interface IProject extends Omit< IPublicApiProject, export interface IProject extends Omit< IPublicApiProject<
IDocumentModel
>,
'simulatorHost' | 'simulatorHost' |
'importSchema' | 'importSchema' |
'exportSchema' | 'exportSchema' |
@ -49,7 +51,7 @@ export interface IProject extends Omit< IPublicApiProject,
load(schema?: IPublicTypeProjectSchema, autoOpen?: boolean | string): void; load(schema?: IPublicTypeProjectSchema, autoOpen?: boolean | string): void;
getSchema( getSchema(
stage: IPublicEnumTransformStage, stage?: IPublicEnumTransformStage,
): IPublicTypeProjectSchema; ): IPublicTypeProjectSchema;
getDocument(id: string): IDocumentModel | null; getDocument(id: string): IDocumentModel | null;
@ -134,10 +136,10 @@ export class Project implements IProject {
} }
private getComponentsMap(): IPublicTypeComponentsMap { private getComponentsMap(): IPublicTypeComponentsMap {
return this.documents.reduce(( return this.documents.reduce<IPublicTypeComponentsMap>((
componentsMap: IPublicTypeComponentsMap, componentsMap: IPublicTypeComponentsMap,
curDoc: DocumentModel, curDoc: IDocumentModel,
) => { ): IPublicTypeComponentsMap => {
const curComponentsMap = curDoc.getComponentsMap(); const curComponentsMap = curDoc.getComponentsMap();
if (Array.isArray(curComponentsMap)) { if (Array.isArray(curComponentsMap)) {
curComponentsMap.forEach((item) => { curComponentsMap.forEach((item) => {
@ -176,7 +178,7 @@ export class Project implements IProject {
componentsMap: this.getComponentsMap(), componentsMap: this.getComponentsMap(),
componentsTree: this.documents componentsTree: this.documents
.filter((doc) => !doc.isBlank()) .filter((doc) => !doc.isBlank())
.map((doc) => doc.export(stage)), .map((doc) => doc.export(stage) || {} as IPublicTypeRootSchema),
i18n: this.i18n, i18n: this.i18n,
}; };
} }
@ -188,7 +190,7 @@ export class Project implements IProject {
setSchema(schema?: IPublicTypeProjectSchema) { setSchema(schema?: IPublicTypeProjectSchema) {
// FIXME: 这里的行为和 getSchema 并不对等,感觉不太对 // FIXME: 这里的行为和 getSchema 并不对等,感觉不太对
const doc = this.documents.find((doc) => doc.active); const doc = this.documents.find((doc) => doc.active);
doc && doc.import(schema?.componentsTree[0]); doc && schema?.componentsTree[0] && doc.import(schema?.componentsTree[0]);
this.simulator?.rerender(); this.simulator?.rerender();
} }
@ -244,7 +246,7 @@ export class Project implements IProject {
} }
} }
removeDocument(doc: IPublicModelDocumentModel) { removeDocument(doc: IDocumentModel) {
const index = this.documents.indexOf(doc); const index = this.documents.indexOf(doc);
if (index < 0) { if (index < 0) {
return; return;

View File

@ -1,5 +1,5 @@
import { ComponentType } from 'react'; import { ComponentType } from 'react';
import { IPublicTypeComponentMetadata, IPublicTypeNodeSchema, IPublicTypeScrollable, IPublicTypeComponentInstance, IPublicModelSensor, IPublicTypeNodeInstance } from '@alilc/lowcode-types'; import { IPublicTypeComponentMetadata, IPublicTypeNodeSchema, IPublicTypeScrollable, IPublicTypeComponentInstance, IPublicModelSensor, IPublicTypeNodeInstance, IPublicTypePackage } from '@alilc/lowcode-types';
import { Point, ScrollTarget, ILocateEvent } from './designer'; import { Point, ScrollTarget, ILocateEvent } from './designer';
import { BuiltinSimulatorRenderer } from './builtin-simulator/renderer'; import { BuiltinSimulatorRenderer } from './builtin-simulator/renderer';
import { INode } from './document'; import { INode } from './document';
@ -78,7 +78,7 @@ export interface DropContainer {
/** /**
* *
*/ */
export interface ISimulatorHost<P = object> extends IPublicModelSensor { export interface ISimulatorHost<P = object> extends IPublicModelSensor<INode> {
readonly isSimulator: true; readonly isSimulator: true;
/** /**
@ -177,6 +177,8 @@ export interface ISimulatorHost<P = object> extends IPublicModelSensor {
* *
*/ */
purge(): void; purge(): void;
setupComponents(library: IPublicTypePackage[]): Promise<void>;
} }
export function isSimulatorHost(obj: any): obj is ISimulatorHost { export function isSimulatorHost(obj: any): obj is ISimulatorHost {

View File

@ -1,16 +1,16 @@
import { Component, MouseEvent, Fragment } from 'react'; import { Component, MouseEvent, Fragment } from 'react';
import { shallowIntl, observer, obx, engineConfig, runInAction, globalContext } from '@alilc/lowcode-editor-core'; import { shallowIntl, observer, obx, engineConfig, runInAction, globalContext } from '@alilc/lowcode-editor-core';
import { createContent, isJSSlot, isSetterConfig, isSettingField } from '@alilc/lowcode-utils'; import { createContent, isJSSlot, isSetterConfig } from '@alilc/lowcode-utils';
import { Skeleton } from '@alilc/lowcode-editor-skeleton'; import { Skeleton, Stage } from '@alilc/lowcode-editor-skeleton';
import { IPublicTypeCustomView } from '@alilc/lowcode-types'; import { IPublicTypeCustomView } from '@alilc/lowcode-types';
import { SettingField, SettingTopEntry, ISettingEntry, ComponentMeta } from '@alilc/lowcode-designer'; import { SettingField, SettingTopEntry, ISettingEntry, IComponentMeta, ISettingField, isSettingField } from '@alilc/lowcode-designer';
import { createField } from '../field'; import { createField } from '../field';
import PopupService, { PopupPipe } from '../popup'; import PopupService, { PopupPipe } from '../popup';
import { SkeletonContext } from '../../context'; import { SkeletonContext } from '../../context';
import { intl } from '../../locale'; import { intl } from '../../locale';
import { Setters } from '@alilc/lowcode-shell'; import { Setters } from '@alilc/lowcode-shell';
function isStandardComponent(componentMeta: ComponentMeta | null) { function isStandardComponent(componentMeta: IComponentMeta | null) {
if (!componentMeta) return false; if (!componentMeta) return false;
const { prototype } = componentMeta; const { prototype } = componentMeta;
return prototype == null; return prototype == null;
@ -31,8 +31,9 @@ function isInitialValueNotEmpty(initialValue: any) {
return (initialValue !== undefined && initialValue !== null); return (initialValue !== undefined && initialValue !== null);
} }
type SettingFieldViewProps = { field: SettingField }; type SettingFieldViewProps = { field: ISettingField };
type SettingFieldViewState = { fromOnChange: boolean; value: any }; type SettingFieldViewState = { fromOnChange: boolean; value: any };
@observer @observer
class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldViewState> { class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldViewState> {
static contextType = SkeletonContext; static contextType = SkeletonContext;
@ -55,7 +56,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
let stageName; let stageName;
if (display === 'entry') { if (display === 'entry') {
runInAction(() => { runInAction(() => {
stageName = `${field.getNode().id}_${field.name.toString()}`; stageName = `${field.getNode().id}_${field.name?.toString()}`;
// 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新 // 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新
stages.container.remove(stageName); stages.container.remove(stageName);
stages.add({ stages.add({
@ -252,7 +253,9 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
}, },
removeProp: () => { removeProp: () => {
field.parent.clearPropValue(field.name); if (field.name) {
field.parent.clearPropValue(field.name);
}
}, },
}), }),
extraProps.forceInline ? 'plain' : extraProps.display, extraProps.forceInline ? 'plain' : extraProps.display,
@ -280,7 +283,7 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
let stageName; let stageName;
if (display === 'entry') { if (display === 'entry') {
runInAction(() => { runInAction(() => {
stageName = `${field.getNode().id}_${field.name.toString()}`; stageName = `${field.getNode().id}_${field.name?.toString()}`;
// 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新 // 清除原 stage不然 content 引用的一直是老的 field导致数据无法得到更新
stages.container.remove(stageName); stages.container.remove(stageName);
stages.add({ stages.add({
@ -324,7 +327,7 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
} }
} }
export function createSettingFieldView(item: SettingField | IPublicTypeCustomView, field: ISettingEntry, index?: number) { export function createSettingFieldView(item: ISettingField | IPublicTypeCustomView, field: ISettingEntry, index?: number) {
if (isSettingField(item)) { if (isSettingField(item)) {
if (item.isGroup) { if (item.isGroup) {
return <SettingGroupView field={item} key={item.id} />; return <SettingGroupView field={item} key={item.id} />;

View File

@ -1,17 +1,22 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Tab, Breadcrumb } from '@alifd/next'; import { Tab, Breadcrumb } from '@alifd/next';
import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core'; import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core';
import { Node, SettingField } from '@alilc/lowcode-designer'; import { Node, SettingField, isSettingField, INode } from '@alilc/lowcode-designer';
import classNames from 'classnames'; import classNames from 'classnames';
import { SettingsMain } from './main'; import { SettingsMain } from './main';
import { SettingsPane } from './settings-pane'; import { SettingsPane } from './settings-pane';
import { StageBox } from '../stage-box'; import { StageBox } from '../stage-box';
import { SkeletonContext } from '../../context'; import { SkeletonContext } from '../../context';
import { intl } from '../../locale'; import { intl } from '../../locale';
import { createIcon, isSettingField } from '@alilc/lowcode-utils'; import { createIcon } from '@alilc/lowcode-utils';
interface ISettingsPrimaryPaneProps {
engineEditor: Editor;
config: any;
}
@observer @observer
export class SettingsPrimaryPane extends Component<{ engineEditor: Editor; config: any }, { shouldIgnoreRoot: boolean }> { export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { shouldIgnoreRoot: boolean }> {
state = { state = {
shouldIgnoreRoot: false, shouldIgnoreRoot: false,
}; };
@ -19,7 +24,7 @@ export class SettingsPrimaryPane extends Component<{ engineEditor: Editor; confi
@obx.ref private _activeKey?: any; @obx.ref private _activeKey?: any;
constructor(props) { constructor(props: ISettingsPrimaryPaneProps) {
super(props); super(props);
makeObservable(this); makeObservable(this);
} }
@ -72,8 +77,8 @@ export class SettingsPrimaryPane extends Component<{ engineEditor: Editor; confi
const editor = this.props.engineEditor; const editor = this.props.engineEditor;
const designer = editor.get('designer'); const designer = editor.get('designer');
const current = designer?.currentSelection?.getNodes()?.[0]; const current = designer?.currentSelection?.getNodes()?.[0];
let node: Node | null = settings.first; let node: INode | null = settings.first;
const { focusNode } = node.document; const focusNode = node.document?.focusNode;
const items = []; const items = [];
let l = 3; let l = 3;
@ -83,7 +88,7 @@ export class SettingsPrimaryPane extends Component<{ engineEditor: Editor; confi
if (shouldIgnoreRoot && node.isRoot()) { if (shouldIgnoreRoot && node.isRoot()) {
break; break;
} }
if (node.contains(focusNode)) { if (focusNode && node.contains(focusNode)) {
l = 0; l = 0;
} }
const props = const props =

View File

@ -15,7 +15,7 @@ export interface WidgetConfig extends IPublicTypeWidgetBaseConfig {
props?: { props?: {
align?: 'left' | 'right' | 'bottom' | 'center' | 'top'; align?: 'left' | 'right' | 'bottom' | 'center' | 'top';
onInit?: (widget: IWidget) => void; onInit?: (widget: IWidget) => void;
title?: IPublicTypeTitleContent; title?: IPublicTypeTitleContent | null;
}; };
content?: string | ReactElement | ComponentType<any>; // children content?: string | ReactElement | ComponentType<any>; // children
} }

View File

@ -3,20 +3,22 @@ import { IPublicEnumTransformStage } from '../enum';
import { IPublicApiSimulatorHost } from './'; import { IPublicApiSimulatorHost } from './';
import { IPublicModelDocumentModel } from '../model'; import { IPublicModelDocumentModel } from '../model';
export interface IPublicApiProject { export interface IPublicApiProject<
DocumentModel = IPublicModelDocumentModel
> {
/** /**
* document * document
* get current document * get current document
*/ */
get currentDocument(): IPublicModelDocumentModel | null; get currentDocument(): DocumentModel | null;
/** /**
* project documents * project documents
* get all documents of this project * get all documents of this project
* @returns * @returns
*/ */
get documents(): IPublicModelDocumentModel[]; get documents(): DocumentModel[];
/** /**
* host * host
@ -30,7 +32,7 @@ export interface IPublicApiProject {
* @param doc * @param doc
* @returns * @returns
*/ */
openDocument(doc?: string | IPublicTypeRootSchema | undefined): IPublicModelDocumentModel | null; openDocument(doc?: string | IPublicTypeRootSchema | undefined): DocumentModel | null;
/** /**
* document * document
@ -38,14 +40,14 @@ export interface IPublicApiProject {
* @param data * @param data
* @returns * @returns
*/ */
createDocument(data?: IPublicTypeRootSchema): IPublicModelDocumentModel | null; createDocument(data?: IPublicTypeRootSchema): DocumentModel | null;
/** /**
* document * document
* remove a document * remove a document
* @param doc * @param doc
*/ */
removeDocument(doc: IPublicModelDocumentModel): void; removeDocument(doc: DocumentModel): void;
/** /**
* fileName document * fileName document
@ -53,7 +55,7 @@ export interface IPublicApiProject {
* @param fileName * @param fileName
* @returns * @returns
*/ */
getDocumentByFileName(fileName: string): IPublicModelDocumentModel | null; getDocumentByFileName(fileName: string): DocumentModel | null;
/** /**
* id document * id document
@ -61,7 +63,7 @@ export interface IPublicApiProject {
* @param id * @param id
* @returns * @returns
*/ */
getDocumentById(id: string): IPublicModelDocumentModel | null; getDocumentById(id: string): DocumentModel | null;
/** /**
* project * project
@ -82,7 +84,7 @@ export interface IPublicApiProject {
* get current document * get current document
* @returns * @returns
*/ */
getCurrentDocument(): IPublicModelDocumentModel | null; getCurrentDocument(): DocumentModel | null;
/** /**
* *
@ -107,7 +109,7 @@ export interface IPublicApiProject {
* project document * project document
* set callback for event onDocumentChanged * set callback for event onDocumentChanged
*/ */
onChangeDocument(fn: (doc: IPublicModelDocumentModel) => void): IPublicTypeDisposable; onChangeDocument(fn: (doc: DocumentModel) => void): IPublicTypeDisposable;
/** /**
* project ready * project ready

View File

@ -2,7 +2,9 @@
import { IPublicTypeDragNodeDataObject, IPublicTypeDragObject } from '../type'; import { IPublicTypeDragNodeDataObject, IPublicTypeDragObject } from '../type';
import { IPublicModelDragObject, IPublicModelLocateEvent, IPublicModelNode } from './'; import { IPublicModelDragObject, IPublicModelLocateEvent, IPublicModelNode } from './';
export interface IPublicModelDragon { export interface IPublicModelDragon<
Node = IPublicModelNode
> {
/** /**
* *
@ -51,7 +53,7 @@ export interface IPublicModelDragon {
* @param dragObject * @param dragObject
* @param boostEvent * @param boostEvent
*/ */
boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node | IPublicModelNode): void; boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node): void;
/** /**
* *

View File

@ -29,3 +29,5 @@ export * from './plugin-instance';
export * from './sensor'; export * from './sensor';
export * from './resource'; export * from './resource';
export * from './clipboard'; export * from './clipboard';
export * from './setting-entry';
export * from './setting-field';

View File

@ -297,8 +297,9 @@ export interface IBaseModelNode<
* path * path
* get prop by path * get prop by path
* @param path a / a.b / a.0 * @param path a / a.b / a.0
* @param createIfNone true
*/ */
getProp(path: string, createIfNone: boolean): Prop | null; getProp(path: string, createIfNone?: boolean): Prop | null;
/** /**
* path * path

View File

@ -3,12 +3,15 @@ import {
IPublicModelLocateEvent, IPublicModelLocateEvent,
IPublicModelDropLocation, IPublicModelDropLocation,
IPublicTypeComponentInstance, IPublicTypeComponentInstance,
IPublicModelNode,
} from '..'; } from '..';
/** /**
* *
*/ */
export interface IPublicModelSensor { export interface IPublicModelSensor<
Node = IPublicModelNode
> {
/** /**
* false * false
@ -38,5 +41,5 @@ export interface IPublicModelSensor {
/** /**
* *
*/ */
getNodeInstanceFromElement?: (e: Element | null) => IPublicTypeNodeInstance<IPublicTypeComponentInstance> | null; getNodeInstanceFromElement?: (e: Element | null) => IPublicTypeNodeInstance<IPublicTypeComponentInstance, Node> | null;
} }

View File

@ -0,0 +1,20 @@
import { IPublicModelComponentMeta } from "./component-meta";
import { IPublicModelNode } from "./node";
import { IBaseModelSettingTarget } from "./setting-target";
export interface IBaseModelSettingEntry<
Node,
ComponentMeta,
SettingEntry
> extends IBaseModelSettingTarget<
SettingEntry
> {
readonly nodes: Node[];
readonly componentMeta: ComponentMeta | null;
}
export interface IPublicModelSettingEntry extends IBaseModelSettingEntry<
IPublicModelNode,
IPublicModelComponentMeta,
IPublicModelSettingEntry
> {}

View File

@ -0,0 +1,5 @@
import { IPublicModelSettingEntry } from "./setting-entry";
export interface IPublicModelSettingField extends IPublicModelSettingEntry {
}

View File

@ -1,7 +1,9 @@
import { IPublicApiSetters } from '../api'; import { IPublicApiSetters } from '../api';
import { IPublicModelEditor } from './'; import { IPublicModelEditor } from './';
export interface IPublicModelSettingTarget { export interface IBaseModelSettingTarget<
SettingTarget
> {
/** /**
* *
@ -33,12 +35,12 @@ export interface IPublicModelSettingTarget {
/** /**
* *
*/ */
readonly top: IPublicModelSettingTarget; readonly top: SettingTarget;
/** /**
* *
*/ */
readonly parent: IPublicModelSettingTarget; readonly parent: SettingTarget;
/** /**
* *
@ -53,12 +55,12 @@ export interface IPublicModelSettingTarget {
/** /**
* *
*/ */
get: (propName: string | number) => IPublicModelSettingTarget | null; get: (propName: string | number) => SettingTarget | null;
/** /**
* *
*/ */
getProps?: () => IPublicModelSettingTarget; getProps?: () => SettingTarget;
/** /**
* *
@ -91,3 +93,9 @@ export interface IPublicModelSettingTarget {
*/ */
getNode: () => any; getNode: () => any;
} }
export interface IPublicModelSettingTarget extends IBaseModelSettingTarget<
IPublicModelSettingTarget
> {
}

View File

@ -1,5 +1,4 @@
import { IPublicModelSettingTarget } from '../model/setting-target'; import { IPublicModelSettingPropEntry, IPublicTypeCustomView } from '..';
import { IPublicTypeCustomView } from '..';
import { IPublicTypeSetterConfig } from './setter-config'; import { IPublicTypeSetterConfig } from './setter-config';
export type IPublicTypeDynamicSetter = (target: IPublicModelSettingTarget) => string | IPublicTypeSetterConfig | IPublicTypeCustomView; export type IPublicTypeDynamicSetter = (target: IPublicModelSettingPropEntry) => (string | IPublicTypeSetterConfig | IPublicTypeCustomView);

View File

@ -46,8 +46,10 @@ export interface IPublicTypeLocationPropDetail {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
export type IPublicTypeLocationDetail = IPublicTypeLocationChildrenDetail | IPublicTypeLocationPropDetail | { type: string; [key: string]: any }; export type IPublicTypeLocationDetail = IPublicTypeLocationChildrenDetail | IPublicTypeLocationPropDetail | { type: string; [key: string]: any };
export interface IPublicTypeLocationData { export interface IPublicTypeLocationData<
target: IPublicModelNode; // shadowNode | ConditionFlow | ElementNode | RootNode Node = IPublicModelNode
> {
target: Node; // shadowNode | ConditionFlow | ElementNode | RootNode
detail: IPublicTypeLocationDetail; detail: IPublicTypeLocationDetail;
source: string; source: string;
event: IPublicModelLocateEvent; event: IPublicModelLocateEvent;

View File

@ -184,9 +184,9 @@ export interface ConfigureSupport {
*/ */
export interface IPublicTypeCallbacks { export interface IPublicTypeCallbacks {
// hooks // hooks
onMouseDownHook?: (e: MouseEvent, currentNode: IPublicModelNode) => any; onMouseDownHook?: (e: MouseEvent, currentNode: IPublicModelNode | null) => any;
onDblClickHook?: (e: MouseEvent, currentNode: IPublicModelNode) => any; onDblClickHook?: (e: MouseEvent, currentNode: IPublicModelNode | null) => any;
onClickHook?: (e: MouseEvent, currentNode: IPublicModelNode) => any; onClickHook?: (e: MouseEvent, currentNode: IPublicModelNode | null) => any;
// onLocateHook?: (e: any, currentNode: any) => any; // onLocateHook?: (e: any, currentNode: any) => any;
// onAcceptHook?: (currentNode: any, locationData: any) => any; // onAcceptHook?: (currentNode: any, locationData: any) => any;
onMoveHook?: (currentNode: IPublicModelNode) => boolean; onMoveHook?: (currentNode: IPublicModelNode) => boolean;

View File

@ -1,8 +1,11 @@
import { IPublicTypeComponentInstance, IPublicModelNode } from '..'; import { IPublicTypeComponentInstance, IPublicModelNode } from '..';
export interface IPublicTypeNodeInstance<T = IPublicTypeComponentInstance> { export interface IPublicTypeNodeInstance<
T = IPublicTypeComponentInstance,
Node = IPublicModelNode
> {
docId: string; docId: string;
nodeId: string; nodeId: string;
instance: T; instance: T;
node?: IPublicModelNode | null; node?: Node | null;
} }

View File

@ -1,5 +1,5 @@
import { ReactElement } from 'react'; import { ReactElement, ReactNode } from 'react';
import { IPublicTypeI18nData, IPublicTypeTitleConfig } from './'; import { IPublicTypeI18nData, IPublicTypeTitleConfig } from './';
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
export type IPublicTypeTitleContent = string | IPublicTypeI18nData | ReactElement | IPublicTypeTitleConfig; export type IPublicTypeTitleContent = string | IPublicTypeI18nData | ReactElement | ReactNode | IPublicTypeTitleConfig;

View File

@ -1,6 +1,8 @@
// type checks // type checks
export function isI18nData(obj: any): boolean { import { IPublicTypeI18nData } from "@alilc/lowcode-types";
export function isI18nData(obj: any): obj is IPublicTypeI18nData {
return obj && obj.type === 'i18n'; return obj && obj.type === 'i18n';
} }

View File

@ -1,5 +1,5 @@
import { IPublicTypeLocationDetailType } from '@alilc/lowcode-types'; import { IPublicTypeLocationChildrenDetail, IPublicTypeLocationDetailType } from '@alilc/lowcode-types';
export function isLocationChildrenDetail(obj: any): boolean { export function isLocationChildrenDetail(obj: any): obj is IPublicTypeLocationChildrenDetail {
return obj && obj.type === IPublicTypeLocationDetailType.Children; return obj && obj.type === IPublicTypeLocationDetailType.Children;
} }

View File

@ -1,6 +1,6 @@
import { IPublicTypeComponentMap } from '@alilc/lowcode-types'; import { IPublicTypeComponentMap, IPublicTypeProCodeComponent } from '@alilc/lowcode-types';
export function isProCodeComponentType(desc: IPublicTypeComponentMap): boolean { export function isProCodeComponentType(desc: IPublicTypeComponentMap): desc is IPublicTypeProCodeComponent {
return 'package' in desc; return 'package' in desc;
} }

View File

@ -1,3 +1,5 @@
export function isSettingField(obj: any): boolean { import { IPublicModelSettingField } from "@alilc/lowcode-types";
export function isSettingField(obj: any): obj is IPublicModelSettingField {
return obj && obj.isSettingField; return obj && obj.isSettingField;
} }

View File

@ -1,7 +1,7 @@
import { IPublicTypeTitleConfig } from '@alilc/lowcode-types';
import { isI18nData } from './is-i18n-data'; import { isI18nData } from './is-i18n-data';
import { isPlainObject } from '../is-plain-object'; import { isPlainObject } from '../is-plain-object';
export function isTitleConfig(obj: any): obj is IPublicTypeTitleConfig {
export function isTitleConfig(obj: any): boolean {
return isPlainObject(obj) && !isI18nData(obj); return isPlainObject(obj) && !isI18nData(obj);
} }

View File

@ -1,10 +1,10 @@
// 仅使用类型 // 仅使用类型
import { IPublicModelNode } from '@alilc/lowcode-types'; import { IPublicModelNode } from '@alilc/lowcode-types';
export const getClosestNode = ( export const getClosestNode = <Node extends IPublicModelNode = IPublicModelNode>(
node: IPublicModelNode, node: Node,
until: (n: IPublicModelNode) => boolean, until: (n: Node) => boolean,
): IPublicModelNode | undefined => { ): Node | undefined => {
if (!node) { if (!node) {
return undefined; return undefined;
} }
@ -22,7 +22,7 @@ export const getClosestNode = (
* @param {unknown} e * @param {unknown} e
* @returns {boolean} true表示可点击 * @returns {boolean} true表示可点击
*/ */
export const canClickNode = (node: IPublicModelNode, e: unknown): boolean => { export function canClickNode<Node extends IPublicModelNode = IPublicModelNode>(node: Node, e: unknown): boolean {
const onClickHook = node.componentMeta?.advanced?.callbacks?.onClickHook; const onClickHook = node.componentMeta?.advanced?.callbacks?.onClickHook;
const canClick = typeof onClickHook === 'function' ? onClickHook(e as MouseEvent, node) : true; const canClick = typeof onClickHook === 'function' ? onClickHook(e as MouseEvent, node) : true;
return canClick; return canClick;