mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-19 14:04:28 +00:00
polyfill slot
This commit is contained in:
parent
73a5efe8e1
commit
f1b686bad5
@ -10,7 +10,7 @@ import {
|
|||||||
isVertical
|
isVertical
|
||||||
} from '../../designer';
|
} from '../../designer';
|
||||||
import { ISimulatorHost, } from '../../simulator';
|
import { ISimulatorHost, } from '../../simulator';
|
||||||
import {NodeParent } from '../../document';
|
import {ParentalNode } from '../../document';
|
||||||
import './insertion.less';
|
import './insertion.less';
|
||||||
|
|
||||||
interface InsertionData {
|
interface InsertionData {
|
||||||
@ -24,7 +24,7 @@ interface InsertionData {
|
|||||||
/**
|
/**
|
||||||
* 处理拖拽子节点(INode)情况
|
* 处理拖拽子节点(INode)情况
|
||||||
*/
|
*/
|
||||||
function processChildrenDetail(sim: ISimulatorHost, container: NodeParent, detail: LocationChildrenDetail): InsertionData {
|
function processChildrenDetail(sim: ISimulatorHost, container: ParentalNode, detail: LocationChildrenDetail): InsertionData {
|
||||||
let edge = detail.edge || null;
|
let edge = detail.edge || null;
|
||||||
|
|
||||||
if (!edge) {
|
if (!edge) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { obx, autorun, computed } from '@ali/lowcode-globals';
|
|||||||
import { ISimulatorHost, Component, NodeInstance, ComponentInstance } from '../simulator';
|
import { ISimulatorHost, Component, NodeInstance, ComponentInstance } from '../simulator';
|
||||||
import Viewport from './viewport';
|
import Viewport from './viewport';
|
||||||
import { createSimulator } from './create-simulator';
|
import { createSimulator } from './create-simulator';
|
||||||
import { Node, NodeParent, DocumentModel, isNodeParent, isNode, contains, isRootNode } from '../document';
|
import { Node, ParentalNode, DocumentModel, isNode, contains, isRootNode } from '../document';
|
||||||
import ResourceConsumer from './resource-consumer';
|
import ResourceConsumer from './resource-consumer';
|
||||||
import { AssetLevel, Asset, AssetList, assetBundle, assetItem, AssetType, getPublicPath } from '@ali/lowcode-globals';
|
import { AssetLevel, Asset, AssetList, assetBundle, assetItem, AssetType, getPublicPath } from '@ali/lowcode-globals';
|
||||||
import {
|
import {
|
||||||
@ -21,7 +21,7 @@ import {
|
|||||||
Rect,
|
Rect,
|
||||||
CanvasPoint,
|
CanvasPoint,
|
||||||
} from '../designer';
|
} from '../designer';
|
||||||
import { parseProps } from './utils/parse-props';
|
import { parseProps, parseMetadata } from './utils/parse-metadata';
|
||||||
import { isElement, hotkey } from '@ali/lowcode-globals';
|
import { isElement, hotkey } from '@ali/lowcode-globals';
|
||||||
import { ComponentMetadata } from '@ali/lowcode-globals';
|
import { ComponentMetadata } from '@ali/lowcode-globals';
|
||||||
import { BuiltinSimulatorRenderer } from './renderer';
|
import { BuiltinSimulatorRenderer } from './renderer';
|
||||||
@ -387,16 +387,19 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
|
|
||||||
const component = this.getComponent(componentName);
|
const component = this.getComponent(componentName);
|
||||||
|
|
||||||
if (component) {
|
if (!component) {
|
||||||
parseProps(component as any);
|
return {
|
||||||
|
componentName,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// 1. generate builtin div/p/h1/h2
|
// 1. generate builtin div/p/h1/h2
|
||||||
// 2. read propTypes
|
// 2. read propTypes
|
||||||
|
|
||||||
return {
|
return {
|
||||||
componentName,
|
componentName,
|
||||||
props: parseProps(this.getComponent(componentName)),
|
...parseMetadata(component),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -854,7 +857,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
container = currentRoot;
|
container = currentRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNodeParent(container)) {
|
if (!container.isParental()) {
|
||||||
container = container.parent || currentRoot;
|
container = container.parent || currentRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,7 +946,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isAcceptable(container: NodeParent): boolean {
|
isAcceptable(container: ParentalNode): boolean {
|
||||||
return false;
|
return false;
|
||||||
/*
|
/*
|
||||||
const meta = container.componentMeta;
|
const meta = container.componentMeta;
|
||||||
@ -1006,7 +1009,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
/**
|
/**
|
||||||
* 查找邻近容器
|
* 查找邻近容器
|
||||||
*/
|
*/
|
||||||
getNearByContainer(container: NodeParent, e: LocateEvent) {
|
getNearByContainer(container: ParentalNode, e: LocateEvent) {
|
||||||
/*
|
/*
|
||||||
const children = container.children;
|
const children = container.children;
|
||||||
if (!children || children.length < 1) {
|
if (!children || children.length < 1) {
|
||||||
@ -1110,6 +1113,6 @@ function getMatched(elements: Array<Element | Text>, selector: string): Element
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface DropContainer {
|
interface DropContainer {
|
||||||
container: NodeParent;
|
container: ParentalNode;
|
||||||
instance: ComponentInstance;
|
instance: ComponentInstance;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -198,3 +198,10 @@ export function parseProps(component: any): PropConfig[] {
|
|||||||
|
|
||||||
return Object.keys(result).map(key => result[key]);
|
return Object.keys(result).map(key => result[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseMetadata(component: any): any {
|
||||||
|
return {
|
||||||
|
props: parseProps(component),
|
||||||
|
...component.componentMetadata,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
computed,
|
computed,
|
||||||
NestingFilter,
|
NestingFilter,
|
||||||
} from '@ali/lowcode-globals';
|
} from '@ali/lowcode-globals';
|
||||||
import { Node, NodeParent } from './document';
|
import { Node, ParentalNode } from './document';
|
||||||
import { Designer } from './designer';
|
import { Designer } from './designer';
|
||||||
import { intl } from './locale';
|
import { intl } from './locale';
|
||||||
import { IconContainer } from './icons/container';
|
import { IconContainer } from './icons/container';
|
||||||
@ -194,7 +194,7 @@ export class ComponentMeta {
|
|||||||
return this._transformedMetadata!;
|
return this._transformedMetadata!;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkNestingUp(my: Node | NodeData, parent: NodeParent) {
|
checkNestingUp(my: Node | NodeData, parent: ParentalNode) {
|
||||||
// 检查父子关系,直接约束型,在画布中拖拽直接掠过目标容器
|
// 检查父子关系,直接约束型,在画布中拖拽直接掠过目标容器
|
||||||
if (this.parentWhitelist) {
|
if (this.parentWhitelist) {
|
||||||
return this.parentWhitelist(parent, my);
|
return this.parentWhitelist(parent, my);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
autorun,
|
autorun,
|
||||||
} from '@ali/lowcode-globals';
|
} from '@ali/lowcode-globals';
|
||||||
import { Project } from '../project';
|
import { Project } from '../project';
|
||||||
import { Node, DocumentModel, insertChildren, isRootNode, NodeParent } from '../document';
|
import { Node, DocumentModel, insertChildren, isRootNode, ParentalNode } from '../document';
|
||||||
import { ComponentMeta } from '../component-meta';
|
import { ComponentMeta } from '../component-meta';
|
||||||
import { INodeSelector, Component } from '../simulator';
|
import { INodeSelector, Component } from '../simulator';
|
||||||
import { Scroller, IScrollable } from './scroller';
|
import { Scroller, IScrollable } from './scroller';
|
||||||
@ -201,7 +201,7 @@ export class Designer {
|
|||||||
/**
|
/**
|
||||||
* 获得合适的插入位置
|
* 获得合适的插入位置
|
||||||
*/
|
*/
|
||||||
getSuitableInsertion(): { target: NodeParent; index?: number } | null {
|
getSuitableInsertion(): { target: ParentalNode; index?: number } | null {
|
||||||
const activedDoc = this.project.currentDocument;
|
const activedDoc = this.project.currentDocument;
|
||||||
if (!activedDoc) {
|
if (!activedDoc) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -88,7 +88,6 @@ export interface DragNodeObject {
|
|||||||
export interface DragNodeDataObject {
|
export interface DragNodeDataObject {
|
||||||
type: DragObjectType.NodeData;
|
type: DragObjectType.NodeData;
|
||||||
data: NodeSchema | NodeSchema[];
|
data: NodeSchema | NodeSchema[];
|
||||||
maps?: { [componentName: string]: string };
|
|
||||||
thumbnail?: string;
|
thumbnail?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
[extra: string]: any;
|
[extra: string]: any;
|
||||||
@ -233,7 +232,7 @@ export class Dragon {
|
|||||||
const masterSensors = this.getMasterSensors();
|
const masterSensors = this.getMasterSensors();
|
||||||
const handleEvents = makeEventsHandler(boostEvent, masterSensors);
|
const handleEvents = makeEventsHandler(boostEvent, masterSensors);
|
||||||
const newBie = !isDragNodeObject(dragObject);
|
const newBie = !isDragNodeObject(dragObject);
|
||||||
const forceCopyState = isDragNodeObject(dragObject) && dragObject.nodes.some((node) => node.isSlotRoot);
|
const forceCopyState = isDragNodeObject(dragObject) && dragObject.nodes.some((node) => node.isSlot());
|
||||||
const isBoostFromDragAPI = boostEvent.type.substr(0, 4) === 'drag';
|
const isBoostFromDragAPI = boostEvent.type.substr(0, 4) === 'drag';
|
||||||
let lastSensor: ISensor | undefined;
|
let lastSensor: ISensor | undefined;
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { DocumentModel, Node as ComponentNode, NodeParent } from '../document';
|
import { DocumentModel, Node as ComponentNode, ParentalNode } from '../document';
|
||||||
import { LocateEvent } from './dragon';
|
import { LocateEvent } from './dragon';
|
||||||
|
|
||||||
export interface LocationData {
|
export interface LocationData {
|
||||||
target: NodeParent; // shadowNode | ConditionFlow | ElementNode | RootNode
|
target: ParentalNode; // shadowNode | ConditionFlow | ElementNode | RootNode
|
||||||
detail: LocationDetail;
|
detail: LocationDetail;
|
||||||
source: string;
|
source: string;
|
||||||
event: LocateEvent;
|
event: LocateEvent;
|
||||||
@ -27,7 +27,7 @@ export interface LocationChildrenDetail {
|
|||||||
rect?: Rect;
|
rect?: Rect;
|
||||||
align?: 'V' | 'H';
|
align?: 'V' | 'H';
|
||||||
};
|
};
|
||||||
focus?: { type: 'slots' } | { type: 'node'; node: NodeParent };
|
focus?: { type: 'slots' } | { type: 'node'; node: ParentalNode };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LocationPropDetail {
|
export interface LocationPropDetail {
|
||||||
@ -126,7 +126,7 @@ export function getWindow(elem: Element | Document): Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class DropLocation {
|
export class DropLocation {
|
||||||
readonly target: NodeParent;
|
readonly target: ParentalNode;
|
||||||
readonly detail: LocationDetail;
|
readonly detail: LocationDetail;
|
||||||
readonly event: LocateEvent;
|
readonly event: LocateEvent;
|
||||||
readonly source: string;
|
readonly source: string;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
RootSchema,
|
|
||||||
NodeData,
|
NodeData,
|
||||||
isJSExpression,
|
isJSExpression,
|
||||||
isDOMText,
|
isDOMText,
|
||||||
@ -9,16 +8,26 @@ import {
|
|||||||
autorun,
|
autorun,
|
||||||
isNodeSchema,
|
isNodeSchema,
|
||||||
uniqueId,
|
uniqueId,
|
||||||
|
PageSchema,
|
||||||
|
ComponentSchema,
|
||||||
|
RootSchema,
|
||||||
} from '@ali/lowcode-globals';
|
} from '@ali/lowcode-globals';
|
||||||
import { Project } from '../project';
|
import { Project } from '../project';
|
||||||
import { ISimulatorHost } from '../simulator';
|
import { ISimulatorHost } from '../simulator';
|
||||||
import { ComponentMeta } from '../component-meta';
|
import { ComponentMeta } from '../component-meta';
|
||||||
import { isDragNodeDataObject, DragNodeObject, DragNodeDataObject, DropLocation } from '../designer';
|
import { isDragNodeDataObject, DragNodeObject, DragNodeDataObject, DropLocation } from '../designer';
|
||||||
import { Node, isNodeParent, insertChildren, insertChild, NodeParent, isNode } from './node/node';
|
import { Node, insertChildren, insertChild, isNode, RootNode, ParentalNode } from './node/node';
|
||||||
import { Selection } from './selection';
|
import { Selection } from './selection';
|
||||||
import { RootNode } from './node/root-node';
|
|
||||||
import { History } from './history';
|
import { History } from './history';
|
||||||
import { Prop } from './node/props/prop';
|
import { ExportType } from './node';
|
||||||
|
|
||||||
|
export type GetDataType<T, NodeType> = T extends undefined
|
||||||
|
? NodeType extends {
|
||||||
|
schema: infer R;
|
||||||
|
}
|
||||||
|
? R
|
||||||
|
: any
|
||||||
|
: T;
|
||||||
|
|
||||||
export class DocumentModel {
|
export class DocumentModel {
|
||||||
/**
|
/**
|
||||||
@ -58,7 +67,7 @@ export class DocumentModel {
|
|||||||
this.rootNode.getExtraProp('fileName', true)?.setValue(fileName);
|
this.rootNode.getExtraProp('fileName', true)?.setValue(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _modalNode?: NodeParent;
|
private _modalNode?: ParentalNode;
|
||||||
private _blank?: boolean;
|
private _blank?: boolean;
|
||||||
get modalNode() {
|
get modalNode() {
|
||||||
return this._modalNode;
|
return this._modalNode;
|
||||||
@ -81,8 +90,9 @@ export class DocumentModel {
|
|||||||
this._blank = true;
|
this._blank = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rootNode = this.createRootNode(schema || {
|
this.rootNode = this.createNode<RootNode>(schema || {
|
||||||
componentName: 'Page',
|
componentName: 'Page',
|
||||||
|
id: 'root',
|
||||||
fileName: ''
|
fileName: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -130,7 +140,7 @@ export class DocumentModel {
|
|||||||
/**
|
/**
|
||||||
* 根据 schema 创建一个节点
|
* 根据 schema 创建一个节点
|
||||||
*/
|
*/
|
||||||
createNode(data: NodeData, slotFor?: Prop): Node {
|
createNode<T extends Node = Node, C = undefined>(data: GetDataType<C, T>): T {
|
||||||
let schema: any;
|
let schema: any;
|
||||||
if (isDOMText(data) || isJSExpression(data)) {
|
if (isDOMText(data) || isJSExpression(data)) {
|
||||||
schema = {
|
schema = {
|
||||||
@ -150,14 +160,13 @@ export class DocumentModel {
|
|||||||
// will move to another position
|
// will move to another position
|
||||||
// todo: this.activeNodes?.push(node);
|
// todo: this.activeNodes?.push(node);
|
||||||
}
|
}
|
||||||
node.internalSetSlotFor(slotFor);
|
|
||||||
node.import(schema, true);
|
node.import(schema, true);
|
||||||
} else if (node) {
|
} else if (node) {
|
||||||
node = null;
|
node = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
node = new Node(this, schema, slotFor);
|
node = new Node(this, schema);
|
||||||
// will add
|
// will add
|
||||||
// todo: this.activeNodes?.push(node);
|
// todo: this.activeNodes?.push(node);
|
||||||
}
|
}
|
||||||
@ -169,27 +178,20 @@ export class DocumentModel {
|
|||||||
this.nodesMap.set(node.id, node);
|
this.nodesMap.set(node.id, node);
|
||||||
this.nodes.add(node);
|
this.nodes.add(node);
|
||||||
|
|
||||||
return node;
|
return node as any;
|
||||||
}
|
|
||||||
|
|
||||||
private createRootNode(schema: RootSchema) {
|
|
||||||
const node = new RootNode(this, schema);
|
|
||||||
this.nodesMap.set(node.id, node);
|
|
||||||
this.nodes.add(node);
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入一个节点
|
* 插入一个节点
|
||||||
*/
|
*/
|
||||||
insertNode(parent: NodeParent, thing: Node | NodeData, at?: number | null, copy?: boolean): Node {
|
insertNode(parent: ParentalNode, thing: Node | NodeData, at?: number | null, copy?: boolean): Node {
|
||||||
return insertChild(parent, thing, at, copy);
|
return insertChild(parent, thing, at, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入多个节点
|
* 插入多个节点
|
||||||
*/
|
*/
|
||||||
insertNodes(parent: NodeParent, thing: Node[] | NodeData[], at?: number | null, copy?: boolean) {
|
insertNodes(parent: ParentalNode, thing: Node[] | NodeData[], at?: number | null, copy?: boolean) {
|
||||||
return insertChildren(parent, thing, at, copy);
|
return insertChildren(parent, thing, at, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +251,7 @@ export class DocumentModel {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const wrapper = this.createNode(schema);
|
const wrapper = this.createNode(schema);
|
||||||
if (isNodeParent(wrapper)) {
|
if (wrapper.isParental()) {
|
||||||
const first = nodes[0];
|
const first = nodes[0];
|
||||||
// TODO: check nesting rules x 2
|
// TODO: check nesting rules x 2
|
||||||
insertChild(first.parent!, wrapper, first.index);
|
insertChild(first.parent!, wrapper, first.index);
|
||||||
@ -270,11 +272,15 @@ export class DocumentModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
import(schema: RootSchema, checkId = false) {
|
import(schema: RootSchema, checkId = false) {
|
||||||
this.rootNode.import(schema, checkId);
|
this.rootNode.import(schema as any, checkId);
|
||||||
// todo: purge something
|
// todo: purge something
|
||||||
// todo: select added and active track added
|
// todo: select added and active track added
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export(exportType: ExportType = ExportType.ForSerilize) {
|
||||||
|
return this.rootNode.export(exportType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出节点数据
|
* 导出节点数据
|
||||||
*/
|
*/
|
||||||
@ -409,7 +415,7 @@ export class DocumentModel {
|
|||||||
// todo:
|
// todo:
|
||||||
}
|
}
|
||||||
|
|
||||||
checkNesting(dropTarget: NodeParent, dragObject: DragNodeObject | DragNodeDataObject): boolean {
|
checkNesting(dropTarget: ParentalNode, dragObject: DragNodeObject | DragNodeDataObject): boolean {
|
||||||
let items: Array<Node | NodeSchema>;
|
let items: Array<Node | NodeSchema>;
|
||||||
if (isDragNodeDataObject(dragObject)) {
|
if (isDragNodeDataObject(dragObject)) {
|
||||||
items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
|
items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
|
||||||
@ -419,7 +425,7 @@ export class DocumentModel {
|
|||||||
return items.every((item) => this.checkNestingDown(dropTarget, item));
|
return items.every((item) => this.checkNestingDown(dropTarget, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDropTarget(dropTarget: NodeParent, dragObject: DragNodeObject | DragNodeDataObject): boolean {
|
checkDropTarget(dropTarget: ParentalNode, dragObject: DragNodeObject | DragNodeDataObject): boolean {
|
||||||
let items: Array<Node | NodeSchema>;
|
let items: Array<Node | NodeSchema>;
|
||||||
if (isDragNodeDataObject(dragObject)) {
|
if (isDragNodeDataObject(dragObject)) {
|
||||||
items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
|
items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
|
||||||
@ -432,7 +438,7 @@ export class DocumentModel {
|
|||||||
/**
|
/**
|
||||||
* 检查对象对父级的要求,涉及配置 parentWhitelist
|
* 检查对象对父级的要求,涉及配置 parentWhitelist
|
||||||
*/
|
*/
|
||||||
checkNestingUp(parent: NodeParent, obj: NodeSchema | Node): boolean {
|
checkNestingUp(parent: ParentalNode, obj: NodeSchema | Node): boolean {
|
||||||
if (isNode(obj) || isNodeSchema(obj)) {
|
if (isNode(obj) || isNodeSchema(obj)) {
|
||||||
const config = isNode(obj) ? obj.componentMeta : this.getComponentMeta(obj.componentName);
|
const config = isNode(obj) ? obj.componentMeta : this.getComponentMeta(obj.componentName);
|
||||||
if (config) {
|
if (config) {
|
||||||
@ -446,7 +452,7 @@ export class DocumentModel {
|
|||||||
/**
|
/**
|
||||||
* 检查投放位置对子级的要求,涉及配置 childWhitelist
|
* 检查投放位置对子级的要求,涉及配置 childWhitelist
|
||||||
*/
|
*/
|
||||||
checkNestingDown(parent: NodeParent, obj: NodeSchema | Node): boolean {
|
checkNestingDown(parent: ParentalNode, obj: NodeSchema | Node): boolean {
|
||||||
const config = parent.componentMeta;
|
const config = parent.componentMeta;
|
||||||
return config.checkNestingDown(parent, obj) && this.checkNestingUp(parent, obj);
|
return config.checkNestingDown(parent, obj) && this.checkNestingUp(parent, obj);
|
||||||
}
|
}
|
||||||
|
|||||||
5
packages/designer/src/document/node/export-type.ts
Normal file
5
packages/designer/src/document/node/export-type.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export enum ExportType {
|
||||||
|
ForRender = 1,
|
||||||
|
ForSerilize = 2,
|
||||||
|
ForSave = 3,
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
export * from './exclusive-group';
|
export * from './exclusive-group';
|
||||||
export * from './node';
|
export * from './node';
|
||||||
export * from './node-children';
|
export * from './node-children';
|
||||||
export * from './root-node';
|
|
||||||
export * from './props/prop';
|
export * from './props/prop';
|
||||||
export * from './props/prop-stash';
|
export * from './props/prop-stash';
|
||||||
export * from './props/props';
|
export * from './props/props';
|
||||||
|
export * from './export-type';
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { NodeData, isNodeSchema, obx, computed } from '@ali/lowcode-globals';
|
import { NodeData, isNodeSchema, obx, computed } from '@ali/lowcode-globals';
|
||||||
import { Node, NodeParent } from './node';
|
import { Node, ParentalNode } from './node';
|
||||||
|
import { ExportType } from './export-type';
|
||||||
|
|
||||||
export class NodeChildren {
|
export class NodeChildren {
|
||||||
@obx.val private children: Node[];
|
@obx.val private children: Node[];
|
||||||
constructor(readonly owner: NodeParent, data: NodeData | NodeData[]) {
|
constructor(readonly owner: ParentalNode, data: NodeData | NodeData[]) {
|
||||||
this.children = (Array.isArray(data) ? data : [data]).map(child => {
|
this.children = (Array.isArray(data) ? data : [data]).map(child => {
|
||||||
return this.owner.document.createNode(child);
|
return this.owner.document.createNode(child);
|
||||||
});
|
});
|
||||||
@ -15,10 +16,16 @@ export class NodeChildren {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出 schema
|
* 导出 schema
|
||||||
* @param serialize 序列化,加 id 标识符,用于储存为操作记录
|
|
||||||
*/
|
*/
|
||||||
export(serialize = false): NodeData[] {
|
export(exportType: ExportType = ExportType.ForSave): NodeData[] {
|
||||||
return this.children.map(node => node.export(serialize));
|
return this.children.map(node => {
|
||||||
|
const data = node.export(exportType);
|
||||||
|
if (node.isLeaf() && ExportType.ForSave === exportType) {
|
||||||
|
// FIXME: filter empty
|
||||||
|
return data.children as NodeData;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
import(data?: NodeData | NodeData[], checkId = false) {
|
import(data?: NodeData | NodeData[], checkId = false) {
|
||||||
|
|||||||
@ -8,6 +8,9 @@ import {
|
|||||||
TitleContent,
|
TitleContent,
|
||||||
obx,
|
obx,
|
||||||
computed,
|
computed,
|
||||||
|
SlotSchema,
|
||||||
|
PageSchema,
|
||||||
|
ComponentSchema,
|
||||||
} from '@ali/lowcode-globals';
|
} from '@ali/lowcode-globals';
|
||||||
import { Props, EXTRA_KEY_PREFIX } from './props/props';
|
import { Props, EXTRA_KEY_PREFIX } from './props/props';
|
||||||
import { DocumentModel } from '../document-model';
|
import { DocumentModel } from '../document-model';
|
||||||
@ -15,6 +18,7 @@ import { NodeChildren } from './node-children';
|
|||||||
import { Prop } from './props/prop';
|
import { Prop } from './props/prop';
|
||||||
import { ComponentMeta } from '../../component-meta';
|
import { ComponentMeta } from '../../component-meta';
|
||||||
import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group';
|
import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group';
|
||||||
|
import { ExportType } from './export-type';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基础节点
|
* 基础节点
|
||||||
@ -35,8 +39,36 @@ import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group';
|
|||||||
* locked can not select/hover/ item on canvas but can control on outline
|
* locked can not select/hover/ item on canvas but can control on outline
|
||||||
* hidden not visible on canvas
|
* hidden not visible on canvas
|
||||||
* slotArgs like loopArgs, for slot node
|
* slotArgs like loopArgs, for slot node
|
||||||
|
*
|
||||||
|
* 根容器节点
|
||||||
|
*
|
||||||
|
* [Node Properties]
|
||||||
|
* componentName: Page/Block/Component
|
||||||
|
* props
|
||||||
|
* children
|
||||||
|
*
|
||||||
|
* [Root Container Extra Properties]
|
||||||
|
* fileName
|
||||||
|
* meta
|
||||||
|
* state
|
||||||
|
* defaultProps
|
||||||
|
* dataSource
|
||||||
|
* lifeCycles
|
||||||
|
* methods
|
||||||
|
* css
|
||||||
|
*
|
||||||
|
* [Directives **not used**]
|
||||||
|
* loop
|
||||||
|
* loopArgs
|
||||||
|
* condition
|
||||||
|
* ------- future support -----
|
||||||
|
* conditionGroup
|
||||||
|
* title
|
||||||
|
* ignore
|
||||||
|
* locked
|
||||||
|
* hidden
|
||||||
*/
|
*/
|
||||||
export class Node {
|
export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||||
/**
|
/**
|
||||||
* 是节点实例
|
* 是节点实例
|
||||||
*/
|
*/
|
||||||
@ -63,11 +95,11 @@ export class Node {
|
|||||||
*/
|
*/
|
||||||
readonly props: Props;
|
readonly props: Props;
|
||||||
protected _children?: NodeChildren;
|
protected _children?: NodeChildren;
|
||||||
@obx.ref private _parent: NodeParent | null = null;
|
@obx.ref private _parent: ParentalNode | null = null;
|
||||||
/**
|
/**
|
||||||
* 父级节点
|
* 父级节点
|
||||||
*/
|
*/
|
||||||
get parent(): NodeParent | null {
|
get parent(): ParentalNode | null {
|
||||||
return this._parent;
|
return this._parent;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -100,48 +132,71 @@ export class Node {
|
|||||||
return this.componentMeta.title;
|
return this.componentMeta.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isSlotRoot(): boolean {
|
constructor(readonly document: DocumentModel, nodeSchema: Schema) {
|
||||||
return this._slotFor != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
isRoot() {
|
|
||||||
return (this.document.rootNode as any) == this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(readonly document: DocumentModel, nodeSchema: NodeSchema, slotFor?: Prop) {
|
|
||||||
const { componentName, id, children, props, ...extras } = nodeSchema;
|
const { componentName, id, children, props, ...extras } = nodeSchema;
|
||||||
this.id = id || `node$${document.nextId()}`;
|
this.id = id || `node$${document.nextId()}`;
|
||||||
this.componentName = componentName;
|
this.componentName = componentName;
|
||||||
this._slotFor = slotFor;
|
|
||||||
let _props: Props;
|
let _props: Props;
|
||||||
if (isNodeParent(this)) {
|
if (this.componentName === 'Leaf') {
|
||||||
_props = new Props(this, props, extras);
|
|
||||||
this._children = new NodeChildren(this as NodeParent, children || []);
|
|
||||||
this._children.interalInitParent();
|
|
||||||
} else {
|
|
||||||
_props = new Props(this, {
|
_props = new Props(this, {
|
||||||
children: isDOMText(children) || isJSExpression(children) ? children : '',
|
children: isDOMText(children) || isJSExpression(children) ? children : '',
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
_props = new Props(this, this.buildProps(props), extras);
|
||||||
|
this._children = new NodeChildren(this as ParentalNode, children || []);
|
||||||
|
this._children.interalInitParent();
|
||||||
}
|
}
|
||||||
this.props = _props;
|
this.props = _props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildProps(props: any): any {
|
||||||
|
// TODO: run componentMeta(initials|initialValue|accessor)
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
isContainer(): boolean {
|
||||||
|
return this.isParental() && this.componentMeta.isContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
isRoot(): this is RootNode {
|
||||||
|
return this.document.rootNode == this as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
isPage(): this is PageNode {
|
||||||
|
return this.isRoot() && this.componentName === 'Page';
|
||||||
|
}
|
||||||
|
|
||||||
|
isComponent(): this is ComponentNode {
|
||||||
|
return this.isRoot() && this.componentName === 'Component';
|
||||||
|
}
|
||||||
|
|
||||||
|
isSlot(): this is SlotNode {
|
||||||
|
return this._slotFor != null && this.componentName === 'Slot';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否一个父亲类节点
|
* 是否一个父亲类节点
|
||||||
*/
|
*/
|
||||||
get isNodeParent(): boolean {
|
isParental(): this is ParentalNode {
|
||||||
return this.componentName !== 'Leaf';
|
return !this.isLeaf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终端节点,内容一般为 文字 或者 表达式
|
||||||
|
*/
|
||||||
|
isLeaf(): this is LeafNode {
|
||||||
|
return this.componentName === 'Leaf';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部方法,请勿使用
|
* 内部方法,请勿使用
|
||||||
*/
|
*/
|
||||||
internalSetParent(parent: NodeParent | null) {
|
internalSetParent(parent: ParentalNode | null) {
|
||||||
if (this._parent === parent) {
|
if (this._parent === parent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._parent && !this.isSlotRoot) {
|
if (!this.isSlot() && this._parent) {
|
||||||
this._parent.children.delete(this);
|
this._parent.children.delete(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +215,9 @@ export class Node {
|
|||||||
this._slotFor = slotFor;
|
this._slotFor = slotFor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联属性
|
||||||
|
*/
|
||||||
get slotFor() {
|
get slotFor() {
|
||||||
return this._slotFor;
|
return this._slotFor;
|
||||||
}
|
}
|
||||||
@ -168,7 +226,7 @@ export class Node {
|
|||||||
* 移除当前节点
|
* 移除当前节点
|
||||||
*/
|
*/
|
||||||
remove() {
|
remove() {
|
||||||
if (this.parent && !this.isSlotRoot) {
|
if (!this.isSlot() && this.parent) {
|
||||||
this.parent.children.delete(this, true);
|
this.parent.children.delete(this, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,17 +257,13 @@ export class Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@computed get propsData(): PropsMap | PropsList | null {
|
@computed get propsData(): PropsMap | PropsList | null {
|
||||||
if (!this.isNodeParent || this.componentName === 'Fragment') {
|
if (!this.isParental() || this.componentName === 'Fragment') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.props.export(true).props || null;
|
return this.props.export(ExportType.ForSerilize).props || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isContainer() {
|
@computed hasSlots() {
|
||||||
return this.isNodeParent && this.componentMeta.isContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@computed isSlotContainer() {
|
|
||||||
for (const item of this.props) {
|
for (const item of this.props) {
|
||||||
if (item.type === 'slot') {
|
if (item.type === 'slot') {
|
||||||
return true;
|
return true;
|
||||||
@ -280,11 +334,11 @@ export class Node {
|
|||||||
return v != null && v !== '';
|
return v != null && v !== '';
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapWith(schema: NodeSchema) {
|
wrapWith(schema: Schema) {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceWith(schema: NodeSchema, migrate = true) {
|
replaceWith(schema: Schema, migrate = true) {
|
||||||
// reuse the same id? or replaceSelection
|
// reuse the same id? or replaceSelection
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
@ -366,22 +420,18 @@ export class Node {
|
|||||||
/**
|
/**
|
||||||
* 获取符合搭建协议-节点 schema 结构
|
* 获取符合搭建协议-节点 schema 结构
|
||||||
*/
|
*/
|
||||||
get schema(): NodeSchema {
|
get schema(): Schema {
|
||||||
// FIXME! serilize?
|
return this.export(ExportType.ForSave);
|
||||||
// for design - pass to Renderer
|
|
||||||
// for save production data
|
|
||||||
// for serilize mutation record
|
|
||||||
return this.export(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set schema(data: NodeSchema) {
|
set schema(data: Schema) {
|
||||||
this.import(data);
|
this.import(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
import(data: NodeSchema, checkId = false) {
|
import(data: Schema, checkId = false) {
|
||||||
const { componentName, id, children, props, ...extras } = data;
|
const { componentName, id, children, props, ...extras } = data;
|
||||||
|
|
||||||
if (isNodeParent(this)) {
|
if (this.isParental()) {
|
||||||
this.props.import(props, extras);
|
this.props.import(props, extras);
|
||||||
(this._children as NodeChildren).import(children, checkId);
|
(this._children as NodeChildren).import(children, checkId);
|
||||||
} else {
|
} else {
|
||||||
@ -391,32 +441,32 @@ export class Node {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出 schema
|
* 导出 schema
|
||||||
* @param serialize 序列化,加 id 标识符,用于储存为操作记录
|
|
||||||
*/
|
*/
|
||||||
export(serialize = false): NodeSchema {
|
export(exportType: ExportType = ExportType.ForSave): Schema {
|
||||||
|
// run transducers
|
||||||
|
// run
|
||||||
const baseSchema: any = {
|
const baseSchema: any = {
|
||||||
componentName: this.componentName === 'Leaf' ? 'Fragment' : this.componentName,
|
componentName: this.componentName,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (serialize) {
|
if (exportType !== ExportType.ForSave) {
|
||||||
baseSchema.id = this.id;
|
baseSchema.id = this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNodeParent(this)) {
|
if (this.isLeaf()) {
|
||||||
baseSchema.children = this.props.get('children')?.export(serialize);
|
baseSchema.children = this.props.get('children')?.export(exportType);
|
||||||
// FIXME!
|
return baseSchema;
|
||||||
return baseSchema.children;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { props = {}, extras } = this.props.export(serialize) || {};
|
const { props = {}, extras } = this.props.export(exportType) || {};
|
||||||
const schema: any = {
|
const schema: any = {
|
||||||
...baseSchema,
|
...baseSchema,
|
||||||
props,
|
props,
|
||||||
...extras,
|
...extras,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.children.size > 0) {
|
if (this.isParental() && this.children.size > 0) {
|
||||||
schema.children = this.children.export(serialize);
|
schema.children = this.children.export(exportType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
@ -468,7 +518,7 @@ export class Node {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.purged = true;
|
this.purged = true;
|
||||||
if (isNodeParent(this)) {
|
if (this.isParental()) {
|
||||||
this.children.purge();
|
this.children.purge();
|
||||||
}
|
}
|
||||||
this.props.purge();
|
this.props.purge();
|
||||||
@ -510,7 +560,7 @@ export class Node {
|
|||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
getDOMNode() {
|
getDOMNode(): any {
|
||||||
const instance = this.document.simulator?.getComponentInstances(this)?.[0];
|
const instance = this.document.simulator?.getComponentInstances(this)?.[0];
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
return;
|
return;
|
||||||
@ -535,17 +585,24 @@ export class Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NodeParent extends Node {
|
export interface ParentalNode<T extends NodeSchema = NodeSchema> extends Node<T> {
|
||||||
readonly children: NodeChildren;
|
readonly children: NodeChildren;
|
||||||
readonly props: Props;
|
|
||||||
}
|
}
|
||||||
|
export interface LeafNode extends Node {
|
||||||
|
readonly children: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlotNode extends ParentalNode<SlotSchema> {}
|
||||||
|
export interface PageNode extends ParentalNode<PageSchema> {}
|
||||||
|
export interface ComponentNode extends ParentalNode<ComponentSchema> {}
|
||||||
|
export type RootNode = PageNode | ComponentNode;
|
||||||
|
|
||||||
export function isNode(node: any): node is Node {
|
export function isNode(node: any): node is Node {
|
||||||
return node && node.isNode;
|
return node && node.isNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNodeParent(node: Node): node is NodeParent {
|
export function isRootNode(node: Node): node is RootNode {
|
||||||
return node.isNodeParent;
|
return node && node.isRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getZLevelTop(child: Node, zLevel: number): Node | null {
|
export function getZLevelTop(child: Node, zLevel: number): Node | null {
|
||||||
@ -568,7 +625,7 @@ export function contains(node1: Node, node2: Node): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node1.isNodeParent || !node2.parent) {
|
if (!node1.isParental || !node2.parent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,10 +674,10 @@ export function comparePosition(node1: Node, node2: Node): PositionNO {
|
|||||||
return PositionNO.BeforeOrAfter;
|
return PositionNO.BeforeOrAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function insertChild(container: NodeParent, thing: Node | NodeData, at?: number | null, copy?: boolean): Node {
|
export function insertChild(container: ParentalNode, thing: Node | NodeData, at?: number | null, copy?: boolean): Node {
|
||||||
let node: Node;
|
let node: Node;
|
||||||
if (isNode(thing) && (copy || thing.isSlotRoot)) {
|
if (isNode(thing) && (copy || thing.isSlot())) {
|
||||||
thing = thing.export(false);
|
thing = thing.export(ExportType.ForSave);
|
||||||
}
|
}
|
||||||
if (isNode(thing)) {
|
if (isNode(thing)) {
|
||||||
node = thing;
|
node = thing;
|
||||||
@ -634,7 +691,7 @@ export function insertChild(container: NodeParent, thing: Node | NodeData, at?:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function insertChildren(
|
export function insertChildren(
|
||||||
container: NodeParent,
|
container: ParentalNode,
|
||||||
nodes: Node[] | NodeData[],
|
nodes: Node[] | NodeData[],
|
||||||
at?: number | null,
|
at?: number | null,
|
||||||
copy?: boolean,
|
copy?: boolean,
|
||||||
|
|||||||
@ -2,11 +2,11 @@ import {
|
|||||||
CompositeValue,
|
CompositeValue,
|
||||||
isJSExpression,
|
isJSExpression,
|
||||||
isJSSlot,
|
isJSSlot,
|
||||||
NodeData,
|
|
||||||
isNodeSchema,
|
|
||||||
untracked,
|
untracked,
|
||||||
computed,
|
computed,
|
||||||
obx
|
obx,
|
||||||
|
JSSlot,
|
||||||
|
SlotSchema
|
||||||
} from '@ali/lowcode-globals';
|
} from '@ali/lowcode-globals';
|
||||||
import { uniqueId } from '@ali/lowcode-globals';
|
import { uniqueId } from '@ali/lowcode-globals';
|
||||||
import { isPlainObject } from '@ali/lowcode-globals';
|
import { isPlainObject } from '@ali/lowcode-globals';
|
||||||
@ -14,7 +14,8 @@ import { hasOwnProperty } from '@ali/lowcode-globals';
|
|||||||
import { PropStash } from './prop-stash';
|
import { PropStash } from './prop-stash';
|
||||||
import { valueToSource } from './value-to-source';
|
import { valueToSource } from './value-to-source';
|
||||||
import { Props } from './props';
|
import { Props } from './props';
|
||||||
import { Node } from '../node';
|
import { SlotNode } from '../node';
|
||||||
|
import { ExportType } from '../export-type';
|
||||||
|
|
||||||
export const UNSET = Symbol.for('unset');
|
export const UNSET = Symbol.for('unset');
|
||||||
export type UNSET = typeof UNSET;
|
export type UNSET = typeof UNSET;
|
||||||
@ -45,10 +46,10 @@ export class Prop implements IPropParent {
|
|||||||
* 属性值
|
* 属性值
|
||||||
*/
|
*/
|
||||||
@computed get value(): CompositeValue | UNSET {
|
@computed get value(): CompositeValue | UNSET {
|
||||||
return this.export(true);
|
return this.export(ExportType.ForSerilize);
|
||||||
}
|
}
|
||||||
|
|
||||||
export(serialize = false): CompositeValue | UNSET {
|
export(exporType: ExportType = ExportType.ForSave): CompositeValue | UNSET {
|
||||||
const type = this._type;
|
const type = this._type;
|
||||||
|
|
||||||
if (type === 'unset') {
|
if (type === 'unset') {
|
||||||
@ -60,9 +61,18 @@ export class Prop implements IPropParent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'slot') {
|
if (type === 'slot') {
|
||||||
|
const schema = this._slotNode!.export(exporType);
|
||||||
|
if (exporType === ExportType.ForSave) {
|
||||||
return {
|
return {
|
||||||
type: 'JSSlot',
|
type: 'JSSlot',
|
||||||
value: this._slotNode!.export(serialize),
|
params: schema.params,
|
||||||
|
value: schema.children,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'JSSlot',
|
||||||
|
params: schema.params,
|
||||||
|
value: schema,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +82,7 @@ export class Prop implements IPropParent {
|
|||||||
}
|
}
|
||||||
const maps: any = {};
|
const maps: any = {};
|
||||||
this.items!.forEach((prop, key) => {
|
this.items!.forEach((prop, key) => {
|
||||||
const v = prop.export(serialize);
|
const v = prop.export(exporType);
|
||||||
if (v !== UNSET) {
|
if (v !== UNSET) {
|
||||||
maps[key] = v;
|
maps[key] = v;
|
||||||
}
|
}
|
||||||
@ -85,7 +95,7 @@ export class Prop implements IPropParent {
|
|||||||
return this._value;
|
return this._value;
|
||||||
}
|
}
|
||||||
return this.items!.map((prop) => {
|
return this.items!.map((prop) => {
|
||||||
const v = prop.export(serialize);
|
const v = prop.export(exporType);
|
||||||
return v === UNSET ? null : v;
|
return v === UNSET ? null : v;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -103,7 +113,7 @@ export class Prop implements IPropParent {
|
|||||||
}
|
}
|
||||||
// todo: JSFunction ...
|
// todo: JSFunction ...
|
||||||
if (this.type === 'slot') {
|
if (this.type === 'slot') {
|
||||||
return JSON.stringify(this._slotNode!.export(false));
|
return JSON.stringify(this._slotNode!.export(ExportType.ForSave));
|
||||||
}
|
}
|
||||||
return this._code != null ? this._code : JSON.stringify(this.value);
|
return this._code != null ? this._code : JSON.stringify(this.value);
|
||||||
}
|
}
|
||||||
@ -161,7 +171,7 @@ export class Prop implements IPropParent {
|
|||||||
this._type = 'list';
|
this._type = 'list';
|
||||||
} else if (isPlainObject(val)) {
|
} else if (isPlainObject(val)) {
|
||||||
if (isJSSlot(val)) {
|
if (isJSSlot(val)) {
|
||||||
this.setAsSlot(val.value);
|
this.setAsSlot(val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isJSExpression(val)) {
|
if (isJSExpression(val)) {
|
||||||
@ -181,7 +191,7 @@ export class Prop implements IPropParent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@computed getValue(): CompositeValue {
|
@computed getValue(): CompositeValue {
|
||||||
const v = this.export(true);
|
const v = this.export(ExportType.ForSerilize);
|
||||||
if (v === UNSET) {
|
if (v === UNSET) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -204,24 +214,25 @@ export class Prop implements IPropParent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _slotNode?: Node;
|
private _slotNode?: SlotNode;
|
||||||
get slotNode() {
|
get slotNode() {
|
||||||
return this._slotNode;
|
return this._slotNode;
|
||||||
}
|
}
|
||||||
setAsSlot(data: NodeData) {
|
setAsSlot(data: JSSlot) {
|
||||||
this._type = 'slot';
|
this._type = 'slot';
|
||||||
if (
|
const slotSchema: SlotSchema = {
|
||||||
this._slotNode &&
|
componentName: 'Slot',
|
||||||
isNodeSchema(data) &&
|
title: data.title,
|
||||||
(!data.id || this._slotNode.id === data.id) &&
|
params: data.params,
|
||||||
this._slotNode.componentName === data.componentName
|
children: data.value,
|
||||||
) {
|
};
|
||||||
this._slotNode.import(data);
|
if (this._slotNode) {
|
||||||
|
this._slotNode.import(slotSchema);
|
||||||
} else {
|
} else {
|
||||||
this._slotNode?.internalSetParent(null);
|
|
||||||
const owner = this.props.owner;
|
const owner = this.props.owner;
|
||||||
this._slotNode = owner.document.createNode(data, this);
|
this._slotNode = owner.document.createNode<SlotNode>(slotSchema);
|
||||||
this._slotNode.internalSetParent(owner as any);
|
this._slotNode.internalSetParent(owner as any);
|
||||||
|
this._slotNode.internalSetSlotFor(this);
|
||||||
}
|
}
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { PropsMap, PropsList, CompositeValue, computed, obx, uniqueId } from '@a
|
|||||||
import { PropStash } from './prop-stash';
|
import { PropStash } from './prop-stash';
|
||||||
import { Prop, IPropParent, UNSET } from './prop';
|
import { Prop, IPropParent, UNSET } from './prop';
|
||||||
import { Node } from '../node';
|
import { Node } from '../node';
|
||||||
|
import { ExportType } from '../export-type';
|
||||||
|
|
||||||
export const EXTRA_KEY_PREFIX = '__';
|
export const EXTRA_KEY_PREFIX = '__';
|
||||||
|
|
||||||
@ -79,7 +80,7 @@ export class Props implements IPropParent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export(serialize = false): { props?: PropsMap | PropsList; extras?: object } {
|
export(exportType: ExportType = ExportType.ForSave): { props?: PropsMap | PropsList; extras?: object } {
|
||||||
if (this.items.length < 1) {
|
if (this.items.length < 1) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -88,7 +89,7 @@ export class Props implements IPropParent {
|
|||||||
if (this.type === 'list') {
|
if (this.type === 'list') {
|
||||||
props = [];
|
props = [];
|
||||||
this.items.forEach(item => {
|
this.items.forEach(item => {
|
||||||
let value = item.export(serialize);
|
let value = item.export(exportType);
|
||||||
if (value === UNSET) {
|
if (value === UNSET) {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
@ -111,7 +112,7 @@ export class Props implements IPropParent {
|
|||||||
// todo ...spread
|
// todo ...spread
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let value = item.export(serialize);
|
let value = item.export(exportType);
|
||||||
if (value === UNSET) {
|
if (value === UNSET) {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,81 +0,0 @@
|
|||||||
import { RootSchema } from '@ali/lowcode-globals';
|
|
||||||
import { Node, NodeParent } from './node';
|
|
||||||
import { DocumentModel } from '../document-model';
|
|
||||||
import { NodeChildren } from './node-children';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根容器节点
|
|
||||||
*
|
|
||||||
* [Node Properties]
|
|
||||||
* componentName: Page/Block/Component
|
|
||||||
* props
|
|
||||||
* children
|
|
||||||
*
|
|
||||||
* [Root Container Extra Properties]
|
|
||||||
* fileName
|
|
||||||
* meta
|
|
||||||
* state
|
|
||||||
* defaultProps
|
|
||||||
* dataSource
|
|
||||||
* lifeCycles
|
|
||||||
* methods
|
|
||||||
* css
|
|
||||||
*
|
|
||||||
* [Directives **not used**]
|
|
||||||
* loop
|
|
||||||
* loopArgs
|
|
||||||
* condition
|
|
||||||
* ------- future support -----
|
|
||||||
* conditionGroup
|
|
||||||
* title
|
|
||||||
* ignore
|
|
||||||
* locked
|
|
||||||
* hidden
|
|
||||||
*/
|
|
||||||
export class RootNode extends Node implements NodeParent {
|
|
||||||
readonly isRootNode = true;
|
|
||||||
get isNodeParent() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
get index() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
get nextSibling() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
get prevSibling() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
get zLevel() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
get parent() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
get children(): NodeChildren {
|
|
||||||
return this._children as NodeChildren;
|
|
||||||
}
|
|
||||||
internalSetParent(parent: null) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(readonly document: DocumentModel, rootSchema: RootSchema) {
|
|
||||||
super(document, rootSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
isPage() {
|
|
||||||
return this.componentName === 'Page';
|
|
||||||
}
|
|
||||||
|
|
||||||
isComponent() {
|
|
||||||
return this.componentName === 'Component';
|
|
||||||
}
|
|
||||||
|
|
||||||
isBlock() {
|
|
||||||
return this.componentName === 'Block';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isRootNode(node: any): node is RootNode {
|
|
||||||
return node && node.isRootNode;
|
|
||||||
}
|
|
||||||
@ -13,6 +13,13 @@ export interface NodeSchema {
|
|||||||
loop?: CompositeValue;
|
loop?: CompositeValue;
|
||||||
loopArgs?: [string, string];
|
loopArgs?: [string, string];
|
||||||
children?: NodeData | NodeData[];
|
children?: NodeData | NodeData[];
|
||||||
|
|
||||||
|
// ------- future support -----
|
||||||
|
conditionGroup?: string;
|
||||||
|
title?: string;
|
||||||
|
ignore?: boolean;
|
||||||
|
locked?: boolean;
|
||||||
|
hidden?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PropsMap = CompositeObject;
|
export type PropsMap = CompositeObject;
|
||||||
@ -30,7 +37,7 @@ export function isDOMText(data: any): data is DOMText {
|
|||||||
|
|
||||||
export type DOMText = string;
|
export type DOMText = string;
|
||||||
|
|
||||||
export interface RootSchema extends NodeSchema {
|
export interface ContainerSchema extends NodeSchema {
|
||||||
componentName: string; // 'Block' | 'Page' | 'Component';
|
componentName: string; // 'Block' | 'Page' | 'Component';
|
||||||
fileName: string;
|
fileName: string;
|
||||||
meta?: object;
|
meta?: object;
|
||||||
@ -48,18 +55,24 @@ export interface RootSchema extends NodeSchema {
|
|||||||
defaultProps?: CompositeObject;
|
defaultProps?: CompositeObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlockSchema extends RootSchema {
|
export interface PageSchema extends ContainerSchema {
|
||||||
componentName: 'Block';
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PageSchema extends RootSchema {
|
|
||||||
componentName: 'Page';
|
componentName: 'Page';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentSchema extends RootSchema {
|
export interface ComponentSchema extends ContainerSchema {
|
||||||
componentName: 'Component';
|
componentName: 'Component';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type RootSchema = PageSchema | ComponentSchema;
|
||||||
|
|
||||||
|
export interface BlockSchema extends NodeSchema {
|
||||||
|
componentName: 'Block';
|
||||||
|
}
|
||||||
|
export interface SlotSchema extends NodeSchema {
|
||||||
|
componentName: 'Slot';
|
||||||
|
params?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface ProjectSchema {
|
export interface ProjectSchema {
|
||||||
version: string;
|
version: string;
|
||||||
componentsMap: ComponentsMap;
|
componentsMap: ComponentsMap;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { NodeSchema } from './schema';
|
import { NodeSchema, NodeData } from './schema';
|
||||||
|
|
||||||
// 表达式
|
// 表达式
|
||||||
export interface JSExpression {
|
export interface JSExpression {
|
||||||
@ -15,9 +15,10 @@ export interface JSExpression {
|
|||||||
|
|
||||||
export interface JSSlot {
|
export interface JSSlot {
|
||||||
type: 'JSSlot';
|
type: 'JSSlot';
|
||||||
|
title?: string;
|
||||||
// 函数的入参
|
// 函数的入参
|
||||||
params?: string[];
|
params?: string[];
|
||||||
value: NodeSchema[];
|
value?: NodeData[] | NodeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON 基本类型
|
// JSON 基本类型
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
import { NodeParent, DropLocation, isLocationChildrenDetail, LocateEvent } from '@ali/lowcode-designer';
|
import { ParentalNode, DropLocation, isLocationChildrenDetail, LocateEvent } from '@ali/lowcode-designer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停留检查计时器
|
* 停留检查计时器
|
||||||
*/
|
*/
|
||||||
export default class DwellTimer {
|
export default class DwellTimer {
|
||||||
private timer: number | undefined;
|
private timer: number | undefined;
|
||||||
private previous?: NodeParent;
|
private previous?: ParentalNode;
|
||||||
private event?: LocateEvent;
|
private event?: LocateEvent;
|
||||||
|
|
||||||
constructor(private decide: (node: NodeParent, event: LocateEvent) => void, private timeout: number = 500) {}
|
constructor(private decide: (node: ParentalNode, event: LocateEvent) => void, private timeout: number = 500) {}
|
||||||
|
|
||||||
focus(node: NodeParent, event: LocateEvent) {
|
focus(node: ParentalNode, event: LocateEvent) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
if (this.previous === node) {
|
if (this.previous === node) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { DropLocation, NodeParent, isLocationChildrenDetail } from '@ali/lowcode-designer';
|
import { DropLocation, ParentalNode, isLocationChildrenDetail } from '@ali/lowcode-designer';
|
||||||
|
|
||||||
const IndentSensitive = 15;
|
const IndentSensitive = 15;
|
||||||
export class IndentTrack {
|
export class IndentTrack {
|
||||||
@ -6,7 +6,7 @@ export class IndentTrack {
|
|||||||
reset() {
|
reset() {
|
||||||
this.indentStart = null;
|
this.indentStart = null;
|
||||||
}
|
}
|
||||||
getIndentParent(lastLoc: DropLocation, loc: DropLocation): [NodeParent, number] | null {
|
getIndentParent(lastLoc: DropLocation, loc: DropLocation): [ParentalNode, number] | null {
|
||||||
if (
|
if (
|
||||||
lastLoc.target !== loc.target ||
|
lastLoc.target !== loc.target ||
|
||||||
!isLocationChildrenDetail(lastLoc.detail) ||
|
!isLocationChildrenDetail(lastLoc.detail) ||
|
||||||
@ -33,7 +33,7 @@ export class IndentTrack {
|
|||||||
const index = loc.detail.index;
|
const index = loc.detail.index;
|
||||||
|
|
||||||
if (direction === 'left') {
|
if (direction === 'left') {
|
||||||
if (!parent.parent || parent.isSlotRoot || index < parent.children.size) {
|
if (parent.isSlot() || !parent.parent || index < parent.children.size) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return [parent.parent, parent.index + 1];
|
return [parent.parent, parent.index + 1];
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import {
|
|||||||
isLocationChildrenDetail,
|
isLocationChildrenDetail,
|
||||||
LocationChildrenDetail,
|
LocationChildrenDetail,
|
||||||
LocationDetailType,
|
LocationDetailType,
|
||||||
NodeParent,
|
ParentalNode,
|
||||||
contains,
|
contains,
|
||||||
Node,
|
Node,
|
||||||
} from '@ali/lowcode-designer';
|
} from '@ali/lowcode-designer';
|
||||||
@ -199,7 +199,7 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
|||||||
let index: any;
|
let index: any;
|
||||||
let focus: any;
|
let focus: any;
|
||||||
let valid = true;
|
let valid = true;
|
||||||
if (target.isSlotContainer()) {
|
if (target.hasSlots()) {
|
||||||
index = null;
|
index = null;
|
||||||
focus = { type: 'slots' };
|
focus = { type: 'slots' };
|
||||||
} else {
|
} else {
|
||||||
@ -301,7 +301,7 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
|||||||
if (focusSlots) {
|
if (focusSlots) {
|
||||||
this.dwell.reset();
|
this.dwell.reset();
|
||||||
return designer.createLocation({
|
return designer.createLocation({
|
||||||
target: node as NodeParent,
|
target: node as ParentalNode,
|
||||||
source: this.id,
|
source: this.id,
|
||||||
event: e,
|
event: e,
|
||||||
detail: {
|
detail: {
|
||||||
@ -342,9 +342,9 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
|||||||
index = node.index;
|
index = node.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.isSlotRoot) {
|
if (node.isSlot()) {
|
||||||
// 是个插槽根节点
|
// 是个插槽根节点
|
||||||
if (!treeNode.isContainer() && !treeNode.isSlotContainer()) {
|
if (!treeNode.isContainer() && !treeNode.hasSlots()) {
|
||||||
return designer.createLocation({
|
return designer.createLocation({
|
||||||
target: node.parent!,
|
target: node.parent!,
|
||||||
source: this.id,
|
source: this.id,
|
||||||
@ -377,7 +377,7 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
|||||||
|
|
||||||
let focusNode: Node | undefined;
|
let focusNode: Node | undefined;
|
||||||
// focus
|
// focus
|
||||||
if (!expanded && (treeNode.isContainer() || treeNode.isSlotContainer())) {
|
if (!expanded && (treeNode.isContainer() || treeNode.hasSlots())) {
|
||||||
focusNode = node;
|
focusNode = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,7 +439,7 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = treeNode.node as NodeParent;
|
const container = treeNode.node as ParentalNode;
|
||||||
const detail: LocationChildrenDetail = {
|
const detail: LocationChildrenDetail = {
|
||||||
type: LocationDetailType.Children,
|
type: LocationDetailType.Children,
|
||||||
};
|
};
|
||||||
@ -449,10 +449,10 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
|||||||
source: this.id,
|
source: this.id,
|
||||||
event: e,
|
event: e,
|
||||||
};
|
};
|
||||||
const isSlotContainer = treeNode.isSlotContainer();
|
const isSlotContainer = treeNode.hasSlots();
|
||||||
const isContainer = treeNode.isContainer();
|
const isContainer = treeNode.isContainer();
|
||||||
|
|
||||||
if (container.isSlotRoot && !treeNode.expanded) {
|
if (container.isSlot() && !treeNode.expanded) {
|
||||||
// 未展开,直接定位到内部第一个节点
|
// 未展开,直接定位到内部第一个节点
|
||||||
if (isSlotContainer) {
|
if (isSlotContainer) {
|
||||||
detail.index = null;
|
detail.index = null;
|
||||||
@ -693,7 +693,7 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRecursion(parent: Node | undefined | null, dragObject: DragObject): parent is NodeParent {
|
function checkRecursion(parent: Node | undefined | null, dragObject: DragObject): parent is ParentalNode {
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export default class TreeNode {
|
|||||||
* 是否可以展开
|
* 是否可以展开
|
||||||
*/
|
*/
|
||||||
@computed get expandable(): boolean {
|
@computed get expandable(): boolean {
|
||||||
return this.hasChildren() || this.isSlotContainer() || this.dropDetail?.index != null;
|
return this.hasChildren() || this.hasSlots() || this.dropDetail?.index != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,51 +169,17 @@ export default class TreeNode {
|
|||||||
/**
|
/**
|
||||||
* 判断是否有"插槽"
|
* 判断是否有"插槽"
|
||||||
*/
|
*/
|
||||||
isSlotContainer(): boolean {
|
hasSlots(): boolean {
|
||||||
return this.node.isSlotContainer();
|
return this.node.hasSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
hasChildren(): boolean {
|
hasChildren(): boolean {
|
||||||
return this.isContainer() && this.node.children?.notEmpty() ? true : false;
|
return this.isContainer() && this.node.children?.notEmpty() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
get xForValue() {
|
|
||||||
const node = this.node;
|
|
||||||
return isElementNode(node) && node.xforValue ? node.xforValue : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get flowHidden() {
|
|
||||||
return (this.node as ElementNode).flowHidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
get flowIndex() {
|
|
||||||
return (this.node as ElementNode).flowIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
get conditionFlow() {
|
|
||||||
return (this.node as ElementNode).conditionFlow;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasXIf() {
|
|
||||||
return hasConditionFlow(this.node);
|
|
||||||
}
|
|
||||||
|
|
||||||
hasXFor() {
|
|
||||||
const node = this.node;
|
|
||||||
return isElementNode(node) && node.xforFn;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
select(isMulti: boolean) {
|
select(isMulti: boolean) {
|
||||||
const node = this.node;
|
const node = this.node;
|
||||||
|
|
||||||
/*
|
|
||||||
if (this.hasXIf()) {
|
|
||||||
(node as ElementNode).setFlowVisible();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
const selection = node.document.selection;
|
const selection = node.document.selection;
|
||||||
if (isMulti) {
|
if (isMulti) {
|
||||||
selection.add(node.id);
|
selection.add(node.id);
|
||||||
|
|||||||
@ -108,7 +108,7 @@ class TreeNodeSlots extends Component<{
|
|||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const { treeNode } = this.props;
|
const { treeNode } = this.props;
|
||||||
if (!treeNode.isSlotContainer()) {
|
if (!treeNode.hasSlots()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -66,7 +66,7 @@ export default class TreeTitle extends Component<{
|
|||||||
const { editing } = this.state;
|
const { editing } = this.state;
|
||||||
const isCNode = !treeNode.isRoot();
|
const isCNode = !treeNode.isRoot();
|
||||||
const { node } = treeNode;
|
const { node } = treeNode;
|
||||||
const isNodeParent = node.isNodeParent;
|
const isNodeParent = node.isParental();
|
||||||
let style: any;
|
let style: any;
|
||||||
if (isCNode) {
|
if (isCNode) {
|
||||||
const depth = treeNode.depth;
|
const depth = treeNode.depth;
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>.next-input {
|
.next-input,.next-date-picker {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
&.lc-block-setter {
|
&.lc-block-setter {
|
||||||
|
|||||||
@ -386,6 +386,7 @@ export default class BaseEngine extends PureComponent {
|
|||||||
__parseProps = (props, self, path, info) => {
|
__parseProps = (props, self, path, info) => {
|
||||||
const { schema, Comp, componentInfo = {} } = info;
|
const { schema, Comp, componentInfo = {} } = info;
|
||||||
const propInfo = getValue(componentInfo.props, path);
|
const propInfo = getValue(componentInfo.props, path);
|
||||||
|
// FIXME! 将这行逻辑外置,解耦,线上环境不要验证参数,调试环境可以有,通过传参自定义
|
||||||
const propType = propInfo && propInfo.extra && propInfo.extra.propType;
|
const propType = propInfo && propInfo.extra && propInfo.extra.propType;
|
||||||
const ignoreParse = schema.__ignoreParse || [];
|
const ignoreParse = schema.__ignoreParse || [];
|
||||||
const checkProps = (value) => {
|
const checkProps = (value) => {
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
|
||||||
|
class Leaf extends Component {
|
||||||
|
static displayName = 'Leaf';
|
||||||
|
static componentMetadata = {
|
||||||
|
componentName: 'Leaf',
|
||||||
|
configure: {
|
||||||
|
props: [{
|
||||||
|
name: 'children',
|
||||||
|
setter: 'StringSetter',
|
||||||
|
}],
|
||||||
|
// events/className/style/general/directives
|
||||||
|
supports: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children } = this.props;
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Leaf;
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
|
||||||
|
class Slot extends Component {
|
||||||
|
static displayName = 'Slot';
|
||||||
|
static componentMetadata = {
|
||||||
|
componentName: 'Slot',
|
||||||
|
configure: {
|
||||||
|
props: [{
|
||||||
|
name: '___title___',
|
||||||
|
title: {
|
||||||
|
type: 'i18n',
|
||||||
|
'en-US': 'Slot Title',
|
||||||
|
'zh-CN': '插槽标题'
|
||||||
|
},
|
||||||
|
setter: 'StringSetter',
|
||||||
|
defaultValue: '插槽容器'
|
||||||
|
}, {
|
||||||
|
name: '___params___',
|
||||||
|
title: {
|
||||||
|
type: 'i18n',
|
||||||
|
'en-US': 'Slot Params',
|
||||||
|
'zh-CN': '插槽入参'
|
||||||
|
},
|
||||||
|
setter: {
|
||||||
|
componentName: 'ArraySetter',
|
||||||
|
props: {
|
||||||
|
itemSetter: {
|
||||||
|
componentName: 'StringSetter',
|
||||||
|
props: {
|
||||||
|
placeholder: {
|
||||||
|
type: 'i18n',
|
||||||
|
'zh-CN': '参数名称',
|
||||||
|
'en-US': 'Argument Name'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
// events/className/style/general/directives
|
||||||
|
supports: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children } = this.props;
|
||||||
|
return (
|
||||||
|
<div className="lc-container">{children}</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Slot;
|
||||||
@ -41,6 +41,7 @@ class Renderer extends Component<{ renderer: SimulatorRenderer }> {
|
|||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const { renderer } = this.props;
|
const { renderer } = this.props;
|
||||||
|
console.info(renderer.schema)
|
||||||
return (
|
return (
|
||||||
<LowCodeRenderer
|
<LowCodeRenderer
|
||||||
schema={renderer.schema}
|
schema={renderer.schema}
|
||||||
|
|||||||
@ -57,6 +57,29 @@ html.engine-blur #engine {
|
|||||||
-webkit-filter: blur(4px);
|
-webkit-filter: blur(4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lc-container {
|
||||||
|
&:empty {
|
||||||
|
background: #f2f3f5;
|
||||||
|
color: #a7b1bd;
|
||||||
|
outline: 1px dashed rgba(31, 56, 88, 0.2);
|
||||||
|
outline-offset: -1px !important;
|
||||||
|
height: 66px;
|
||||||
|
max-height: 100%;
|
||||||
|
min-width: 140px;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
&:before {
|
||||||
|
content: '\62D6\62FD\7EC4\4EF6\6216\6A21\677F\5230\8FD9\91CC';
|
||||||
|
font-size: 14px;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.engine-empty {
|
.engine-empty {
|
||||||
background: #f2f3f5;
|
background: #f2f3f5;
|
||||||
color: #a7b1bd;
|
color: #a7b1bd;
|
||||||
|
|||||||
@ -13,6 +13,8 @@ import { cursor } from '@ali/lowcode-globals';
|
|||||||
import { setNativeSelection } from '@ali/lowcode-globals';
|
import { setNativeSelection } from '@ali/lowcode-globals';
|
||||||
import { RootSchema, NpmInfo } from '@ali/lowcode-globals';
|
import { RootSchema, NpmInfo } from '@ali/lowcode-globals';
|
||||||
import { BuiltinSimulatorRenderer, NodeInstance } from '@ali/lowcode-designer';
|
import { BuiltinSimulatorRenderer, NodeInstance } from '@ali/lowcode-designer';
|
||||||
|
import Slot from './builtin-components/slot';
|
||||||
|
import Leaf from './builtin-components/leaf';
|
||||||
|
|
||||||
export class SimulatorRenderer implements BuiltinSimulatorRenderer {
|
export class SimulatorRenderer implements BuiltinSimulatorRenderer {
|
||||||
readonly isSimulatorRenderer = true;
|
readonly isSimulatorRenderer = true;
|
||||||
@ -25,7 +27,7 @@ export class SimulatorRenderer implements BuiltinSimulatorRenderer {
|
|||||||
// sync layout config
|
// sync layout config
|
||||||
|
|
||||||
// sync schema
|
// sync schema
|
||||||
this._schema = host.document.schema;
|
this._schema = host.document.export(1);
|
||||||
|
|
||||||
// todo: split with others, not all should recompute
|
// todo: split with others, not all should recompute
|
||||||
if (this._libraryMap !== host.libraryMap || this._componentsMap !== host.designer.componentsMap) {
|
if (this._libraryMap !== host.libraryMap || this._componentsMap !== host.designer.componentsMap) {
|
||||||
@ -311,8 +313,17 @@ export interface LibraryMap {
|
|||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Slot/Leaf and Fragment|FunctionComponent polyfill(ref)
|
||||||
|
|
||||||
|
const builtinComponents = {
|
||||||
|
Slot,
|
||||||
|
Leaf,
|
||||||
|
};
|
||||||
|
|
||||||
function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo | ComponentType<any> }) {
|
function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo | ComponentType<any> }) {
|
||||||
const components: any = {};
|
const components: any = {
|
||||||
|
...builtinComponents
|
||||||
|
};
|
||||||
Object.keys(componentsMap).forEach((componentName) => {
|
Object.keys(componentsMap).forEach((componentName) => {
|
||||||
let component = componentsMap[componentName];
|
let component = componentsMap[componentName];
|
||||||
if (isReactComponent(component)) {
|
if (isReactComponent(component)) {
|
||||||
|
|||||||
@ -304,13 +304,24 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
extraProps.defaultValue = initialValue;
|
extraProps.defaultValue = initialValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialFn = initial || initialValue;
|
let initialFn = initial || initialValue;
|
||||||
|
|
||||||
|
if (accessor) {
|
||||||
|
extraProps.getValue = (field: Field, fieldValue: any) => {
|
||||||
|
return accessor.call(field, fieldValue);
|
||||||
|
};
|
||||||
|
if (!initialFn) {
|
||||||
|
// FIXME!
|
||||||
|
initialFn
|
||||||
|
}
|
||||||
|
}
|
||||||
extraProps.initialValue = (field: Field, defaultValue?: any) => {
|
extraProps.initialValue = (field: Field, defaultValue?: any) => {
|
||||||
if (defaultValue === undefined) {
|
if (defaultValue === undefined) {
|
||||||
defaultValue = extraProps.defaultValue;
|
defaultValue = extraProps.defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof initialFn === 'function') {
|
if (typeof initialFn === 'function') {
|
||||||
|
// ?
|
||||||
return initialFn(null, defaultValue);
|
return initialFn(null, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,11 +336,6 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (accessor) {
|
|
||||||
extraProps.getValue = (field: Field, fieldValue: any) => {
|
|
||||||
return accessor.call(field, fieldValue);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (mutator) {
|
if (mutator) {
|
||||||
extraProps.setValue = (field: Field, value: any) => {
|
extraProps.setValue = (field: Field, value: any) => {
|
||||||
mutator.call(field, value);
|
mutator.call(field, value);
|
||||||
@ -535,9 +541,17 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
|
|||||||
experimental.context = context;
|
experimental.context = context;
|
||||||
}
|
}
|
||||||
if (snippets) {
|
if (snippets) {
|
||||||
experimental.snippets = snippets;
|
experimental.snippets = snippets.map(data => {
|
||||||
|
const { schema = {} } = data;
|
||||||
|
if (initialChildren && !schema.children) {
|
||||||
|
schema.children = initialChildren;
|
||||||
}
|
}
|
||||||
if (defaultProps || initialChildren) {
|
return {
|
||||||
|
...data,
|
||||||
|
schema,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else if (defaultProps || initialChildren) {
|
||||||
const snippet = {
|
const snippet = {
|
||||||
screenshot: icon,
|
screenshot: icon,
|
||||||
label: title,
|
label: title,
|
||||||
|
|||||||
@ -19,6 +19,7 @@ export class Bus {
|
|||||||
// alias to unsub
|
// alias to unsub
|
||||||
off(event: string, func: (...args: any[]) => any) {
|
off(event: string, func: (...args: any[]) => any) {
|
||||||
this.unsub(event, func);
|
this.unsub(event, func);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// alias to pub
|
// alias to pub
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { designer } from './editor';
|
import { designer } from './editor';
|
||||||
import { DragObjectType, isNode } from '@ali/lowcode-designer';
|
import { DragObjectType, isNode, ExportType } from '@ali/lowcode-designer';
|
||||||
|
|
||||||
const dragon = designer.dragon;
|
const dragon = designer.dragon;
|
||||||
const DragEngine = {
|
const DragEngine = {
|
||||||
@ -12,14 +12,16 @@ const DragEngine = {
|
|||||||
if (isNode(r)) {
|
if (isNode(r)) {
|
||||||
return {
|
return {
|
||||||
type: DragObjectType.NodeData,
|
type: DragObjectType.NodeData,
|
||||||
data: r.export(false),
|
data: r.export(ExportType.ForSave),
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME! designer has bug
|
// FIXME! designer has bug
|
||||||
/*
|
/*
|
||||||
return {
|
return {
|
||||||
type: DragObjectType.Node,
|
type: DragObjectType.Node,
|
||||||
nodes: [r],
|
nodes: [r],
|
||||||
};*/
|
};
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
type: DragObjectType.NodeData,
|
type: DragObjectType.NodeData,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user