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

View File

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

View File

@ -1,5 +1,5 @@
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
*/
export const getClosestClickableNode = (
currentNode: Node | undefined | null,
currentNode: INode | undefined | null,
event: MouseEvent,
) => {
let node = currentNode;

View File

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

View File

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

View File

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

View File

@ -122,7 +122,7 @@ export class DropLocation implements IDropLocation {
return this.target.document;
}
constructor({ target, detail, source, event }: IPublicTypeLocationData) {
constructor({ target, detail, source, event }: IPublicTypeLocationData<INode>) {
this.target = target;
this.detail = detail;
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 { Designer } from '../designer';
import { IDesigner } from '../designer';
import { INode } from '../../document';
export interface ISettingEntry extends IPublicModelSettingTarget {
readonly nodes: INode[];
readonly componentMeta: IComponentMeta | null;
readonly designer: Designer;
export interface ISettingEntry extends IBaseModelSettingEntry<
INode,
IComponentMeta,
ISettingEntry
> {
readonly designer: IDesigner;
// 顶端
readonly top: ISettingEntry;
// 父级
readonly parent: ISettingEntry;
readonly isGroup: boolean;
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 {
IPublicTypeTitleContent,
IPublicTypeSetterType,
@ -25,8 +26,29 @@ function getSettingFieldCollectorKey(parent: ISettingEntry, config: IPublicTypeF
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 {
@ -57,12 +79,12 @@ export class SettingField extends SettingPropEntry implements ISettingField {
@obx.ref private _expanded = true;
private _items: Array<SettingField | IPublicTypeCustomView> = [];
private _items: Array<ISettingField | IPublicTypeCustomView> = [];
constructor(
parent: ISettingEntry,
config: IPublicTypeFieldConfig,
private settingFieldCollector?: (name: string | number, field: SettingField) => void,
private settingFieldCollector?: (name: string | number, field: ISettingField) => void,
) {
super(parent, config.name, config.type);
makeObservable(this);
@ -97,7 +119,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
if (isDynamicSetter(this._setter)) {
return untracked(() => {
const shellThis = this.internalToShellPropEntry();
return this._setter.call(shellThis, shellThis);
return (this._setter as IPublicTypeDynamicSetter)?.call(shellThis, shellThis);
});
}
return this._setter;
@ -111,7 +133,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
this._expanded = value;
}
get items(): Array<SettingField | IPublicTypeCustomView> {
get items(): Array<ISettingField | IPublicTypeCustomView> {
return this._items;
}
@ -122,8 +144,8 @@ export class SettingField extends SettingPropEntry implements ISettingField {
private initItems(
items: Array<IPublicTypeFieldConfig | IPublicTypeCustomView>,
settingFieldCollector?: {
(name: string | number, field: SettingField): void;
(name: string, field: SettingField): void;
(name: string | number, field: ISettingField): void;
(name: string, field: ISettingField): void;
},
) {
this._items = items.map((item) => {
@ -140,7 +162,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
}
// 创建子配置项,通常用于 object/array 类型数据
createField(config: IPublicTypeFieldConfig): SettingField {
createField(config: IPublicTypeFieldConfig): ISettingField {
this.settingFieldCollector?.(getSettingFieldCollectorKey(this.parent, config), this);
return new SettingField(this, config, this.settingFieldCollector);
}
@ -161,8 +183,8 @@ export class SettingField extends SettingPropEntry implements ISettingField {
}
getItems(
filter?: (item: SettingField | IPublicTypeCustomView) => boolean,
): Array<SettingField | IPublicTypeCustomView> {
filter?: (item: ISettingField | IPublicTypeCustomView) => boolean,
): Array<ISettingField | IPublicTypeCustomView> {
return this._items.filter((item) => {
if (filter) {
return filter(item);
@ -252,6 +274,6 @@ export class SettingField extends SettingPropEntry implements ISettingField {
/**
* @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;
}

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
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';
const logger = new Logger({ level: 'warn', bizName: 'history' });
@ -10,7 +10,7 @@ export interface Serialization<K = IPublicTypeNodeSchema, T = string> {
}
export interface IHistory extends IPublicModelHistory {
onStateChange(func: () => any): IPublicTypeDisposable;
}
export class History<T = IPublicTypeNodeSchema> implements IHistory {
@ -189,11 +189,11 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
* @param func
* @returns
*/
onChangeState(func: () => any): () => void {
onChangeState(func: () => any): IPublicTypeDisposable {
return this.onStateChange(func);
}
onStateChange(func: () => any): () => void {
onStateChange(func: () => any): IPublicTypeDisposable {
this.emitter.on('statechange', func);
return () => {
this.emitter.removeListener('statechange', func);
@ -205,7 +205,7 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
* @param func
* @returns
*/
onChangeCursor(func: () => any): () => void {
onChangeCursor(func: () => any): IPublicTypeDisposable {
return this.onCursor(func);
}

View File

@ -7,11 +7,17 @@ import { intl } from '../../locale';
export interface IExclusiveGroup extends IPublicModelExclusiveGroup<INode> {
readonly name: string;
get index(): number | undefined;
remove(node: INode): void;
add(node: INode): void;
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

View File

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

View File

@ -37,9 +37,9 @@ export interface NodeStatus {
inPlaceEditing: boolean;
}
export interface INode extends Omit<IBaseModelNode<
export interface IBaseNode<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> extends Omit<IBaseModelNode<
IDocumentModel,
INode,
IBaseNode,
INodeChildren,
IComponentMeta,
ISettingTopEntry,
@ -77,6 +77,10 @@ export interface INode extends Omit<IBaseModelNode<
get isPurging(): boolean;
getId(): string;
getParent(): INode | null;
/**
* 使
* @param useMutator
@ -147,6 +151,8 @@ export interface INode extends Omit<IBaseModelNode<
setVisible(flag: boolean): void;
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 SlotNode = Node<IPublicTypeSlotSchema>;
export type PageNode = Node<IPublicTypePageSchema>;
export type ComponentNode = Node<IPublicTypeComponentSchema>;
export type RootNode = PageNode | ComponentNode;
export type ISlotNode = IBaseNode<IPublicTypeSlotSchema>;
export type IPageNode = IBaseNode<IPublicTypePageSchema>;
export type IComponentNode = IBaseNode<IPublicTypeComponentSchema>;
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;
}
export function isLowCodeComponent(node: INode): node is INode {
export function isLowCodeComponent(node: INode): node is IComponentNode {
return node.componentMeta?.getMetadata().devMode === 'lowCode';
}
@ -1446,7 +1453,7 @@ export function insertChild(
at?: number | null,
copy?: boolean,
): INode | null {
let node: INode | null | RootNode | undefined;
let node: INode | null | IRootNode | undefined;
let nodeSchema: IPublicTypeNodeSchema;
if (isNode<INode>(thing) && (copy || thing.isSlot())) {
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 { 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 { IProps, IPropParent } from './props';
import { SlotNode, INode } from '../node';
import { ISlotNode, INode } from '../node';
// import { TransformStage } from '../transform-stage';
const { set: mobxSet, isObservableArray } = mobx;
@ -30,6 +30,12 @@ export interface IProp extends Omit<IPublicModelProp<
unset(): void;
get value(): IPublicTypeCompositeValue | UNSET;
compare(other: IProp | null): number;
isUnset(): boolean;
key: string | number | undefined;
}
export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot';
@ -402,7 +408,7 @@ export class Prop implements IProp, IPropParent {
this._type = 'slot';
let slotSchema: IPublicTypeSlotSchema;
// 当 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;
slotSchema = {
componentName: 'Slot',
@ -427,7 +433,7 @@ export class Prop implements IProp, IPropParent {
this._slotNode.import(slotSchema);
} else {
const { owner } = this.props;
this._slotNode = owner.document.createNode<SlotNode>(slotSchema);
this._slotNode = owner.document.createNode<ISlotNode>(slotSchema);
if (this._slotNode) {
owner.addSlot(this._slotNode);
this._slotNode.internalSetSlotFor(this);

View File

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

View File

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

View File

@ -1,5 +1,5 @@
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 { BuiltinSimulatorRenderer } from './builtin-simulator/renderer';
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;
/**
@ -177,6 +177,8 @@ export interface ISimulatorHost<P = object> extends IPublicModelSensor {
*
*/
purge(): void;
setupComponents(library: IPublicTypePackage[]): Promise<void>;
}
export function isSimulatorHost(obj: any): obj is ISimulatorHost {

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,9 @@
import { IPublicTypeDragNodeDataObject, IPublicTypeDragObject } from '../type';
import { IPublicModelDragObject, IPublicModelLocateEvent, IPublicModelNode } from './';
export interface IPublicModelDragon {
export interface IPublicModelDragon<
Node = IPublicModelNode
> {
/**
*
@ -51,7 +53,7 @@ export interface IPublicModelDragon {
* @param dragObject
* @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 './resource';
export * from './clipboard';
export * from './setting-entry';
export * from './setting-field';

View File

@ -297,8 +297,9 @@ export interface IBaseModelNode<
* path
* get prop by path
* @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

View File

@ -3,12 +3,15 @@ import {
IPublicModelLocateEvent,
IPublicModelDropLocation,
IPublicTypeComponentInstance,
IPublicModelNode,
} from '..';
/**
*
*/
export interface IPublicModelSensor {
export interface IPublicModelSensor<
Node = IPublicModelNode
> {
/**
* 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 { 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;
}
export interface IPublicModelSettingTarget extends IBaseModelSettingTarget<
IPublicModelSettingTarget
> {
}

View File

@ -1,5 +1,4 @@
import { IPublicModelSettingTarget } from '../model/setting-target';
import { IPublicTypeCustomView } from '..';
import { IPublicModelSettingPropEntry, IPublicTypeCustomView } from '..';
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
export type IPublicTypeLocationDetail = IPublicTypeLocationChildrenDetail | IPublicTypeLocationPropDetail | { type: string; [key: string]: any };
export interface IPublicTypeLocationData {
target: IPublicModelNode; // shadowNode | ConditionFlow | ElementNode | RootNode
export interface IPublicTypeLocationData<
Node = IPublicModelNode
> {
target: Node; // shadowNode | ConditionFlow | ElementNode | RootNode
detail: IPublicTypeLocationDetail;
source: string;
event: IPublicModelLocateEvent;

View File

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

View File

@ -1,8 +1,11 @@
import { IPublicTypeComponentInstance, IPublicModelNode } from '..';
export interface IPublicTypeNodeInstance<T = IPublicTypeComponentInstance> {
export interface IPublicTypeNodeInstance<
T = IPublicTypeComponentInstance,
Node = IPublicModelNode
> {
docId: string;
nodeId: string;
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 './';
// 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
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';
}

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;
}

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;
}

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;
}

View File

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

View File

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