mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-19 22:58:15 +00:00
Merge branch 'polyfill/vision' of gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine into polyfill/vision
# Conflicts: # packages/designer/src/document/node/node.ts
This commit is contained in:
commit
6a1dc24146
@ -15,7 +15,7 @@
|
|||||||
"commit": "git-cz",
|
"commit": "git-cz",
|
||||||
"pub": "lerna publish --cd-version patch",
|
"pub": "lerna publish --cd-version patch",
|
||||||
"setup": "./scripts/setup.sh",
|
"setup": "./scripts/setup.sh",
|
||||||
"start": "lerna exec --scope @ali/lowcode-vision-polyfill -- npm start",
|
"start": "./scripts/start.sh",
|
||||||
"test": "lerna run test --stream",
|
"test": "lerna run test --stream",
|
||||||
"test:snapshot": "lerna run test:snapshot"
|
"test:snapshot": "lerna run test:snapshot"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -64,7 +64,7 @@ class Clipboard {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const copyPaster = document.createElement<'textarea'>('textarea');
|
const copyPaster = document.createElement<'textarea'>('textarea');
|
||||||
copyPaster.style.cssText = 'position: relative;left: -9999px;';
|
copyPaster.style.cssText = 'position: absolute;left: -9999px;top:-100px';
|
||||||
document.body.appendChild(copyPaster);
|
document.body.appendChild(copyPaster);
|
||||||
const dispose = this.initCopyPaster(copyPaster);
|
const dispose = this.initCopyPaster(copyPaster);
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { ComponentType } from 'react';
|
import { ComponentType } from 'react';
|
||||||
import { EventEmitter } from 'events';
|
|
||||||
import {
|
import {
|
||||||
ProjectSchema,
|
ProjectSchema,
|
||||||
ComponentMetadata,
|
ComponentMetadata,
|
||||||
@ -9,9 +8,11 @@ import {
|
|||||||
computed,
|
computed,
|
||||||
autorun,
|
autorun,
|
||||||
IEditor,
|
IEditor,
|
||||||
|
CompositeObject,
|
||||||
|
PropsList,
|
||||||
} from '@ali/lowcode-globals';
|
} from '@ali/lowcode-globals';
|
||||||
import { Project } from '../project';
|
import { Project } from '../project';
|
||||||
import { Node, DocumentModel, insertChildren, isRootNode, ParentalNode } from '../document';
|
import { Node, DocumentModel, insertChildren, isRootNode, ParentalNode, TransformStage } 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';
|
||||||
@ -24,6 +25,7 @@ import { focusing } from './focusing';
|
|||||||
import { SettingTopEntry } from './setting';
|
import { SettingTopEntry } from './setting';
|
||||||
|
|
||||||
export interface DesignerProps {
|
export interface DesignerProps {
|
||||||
|
editor: IEditor;
|
||||||
className?: string;
|
className?: string;
|
||||||
style?: object;
|
style?: object;
|
||||||
defaultSchema?: ProjectSchema;
|
defaultSchema?: ProjectSchema;
|
||||||
@ -33,7 +35,6 @@ export interface DesignerProps {
|
|||||||
dragGhostComponent?: ComponentType<any>;
|
dragGhostComponent?: ComponentType<any>;
|
||||||
suspensed?: boolean;
|
suspensed?: boolean;
|
||||||
componentMetadatas?: ComponentMetadata[];
|
componentMetadatas?: ComponentMetadata[];
|
||||||
eventPipe?: EventEmitter;
|
|
||||||
globalComponentActions?: ComponentAction[];
|
globalComponentActions?: ComponentAction[];
|
||||||
onMount?: (designer: Designer) => void;
|
onMount?: (designer: Designer) => void;
|
||||||
onDragstart?: (e: LocateEvent) => void;
|
onDragstart?: (e: LocateEvent) => void;
|
||||||
@ -47,6 +48,7 @@ export class Designer {
|
|||||||
readonly activeTracker = new ActiveTracker();
|
readonly activeTracker = new ActiveTracker();
|
||||||
readonly hovering = new Hovering();
|
readonly hovering = new Hovering();
|
||||||
readonly project: Project;
|
readonly project: Project;
|
||||||
|
readonly editor: IEditor;
|
||||||
|
|
||||||
get currentDocument() {
|
get currentDocument() {
|
||||||
return this.project.currentDocument;
|
return this.project.currentDocument;
|
||||||
@ -61,6 +63,8 @@ export class Designer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(props: DesignerProps) {
|
constructor(props: DesignerProps) {
|
||||||
|
const { editor } = props;
|
||||||
|
this.editor = editor;
|
||||||
this.setProps(props);
|
this.setProps(props);
|
||||||
|
|
||||||
this.project = new Project(this, props.defaultSchema);
|
this.project = new Project(this, props.defaultSchema);
|
||||||
@ -164,7 +168,7 @@ export class Designer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
postEvent(event: string, ...args: any[]) {
|
postEvent(event: string, ...args: any[]) {
|
||||||
this.props?.eventPipe?.emit(`designer.${event}`, ...args);
|
this.editor.emit(`designer.${event}`, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _dropLocation?: DropLocation;
|
private _dropLocation?: DropLocation;
|
||||||
@ -312,7 +316,6 @@ export class Designer {
|
|||||||
private _lostComponentMetasMap = new Map<string, ComponentMeta>();
|
private _lostComponentMetasMap = new Map<string, ComponentMeta>();
|
||||||
|
|
||||||
private buildComponentMetasMap(metas: ComponentMetadata[]) {
|
private buildComponentMetasMap(metas: ComponentMetadata[]) {
|
||||||
console.info(this._componentMetasMap);
|
|
||||||
metas.forEach((data) => this.createComponentMeta(data));
|
metas.forEach((data) => this.createComponentMeta(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,6 +375,30 @@ export class Designer {
|
|||||||
return maps;
|
return maps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private propsReducers = new Map<TransformStage, PropsReducer[]>();
|
||||||
|
transformProps(props: CompositeObject | PropsList, node: Node, stage: TransformStage) {
|
||||||
|
if (Array.isArray(props)) {
|
||||||
|
// current not support, make this future
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reducers = this.propsReducers.get(stage);
|
||||||
|
if (!reducers) {
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reducers.reduce((xprops, reducer) => reducer(xprops, node), props);
|
||||||
|
}
|
||||||
|
|
||||||
|
addPropsReducer(reducer: PropsReducer, stage: TransformStage) {
|
||||||
|
const reducers = this.propsReducers.get(stage);
|
||||||
|
if (reducers) {
|
||||||
|
reducers.push(reducer);
|
||||||
|
} else {
|
||||||
|
this.propsReducers.set(stage, [reducer]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
autorun(action: (context: { firstRun: boolean }) => void, sync = false): () => void {
|
autorun(action: (context: { firstRun: boolean }) => void, sync = false): () => void {
|
||||||
return autorun(action, sync as true);
|
return autorun(action, sync as true);
|
||||||
}
|
}
|
||||||
@ -380,3 +407,5 @@ export class Designer {
|
|||||||
// todo:
|
// todo:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type PropsReducer = (props: CompositeObject, node: Node) => CompositeObject;
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (isDynamicSetter(this._setter)) {
|
if (isDynamicSetter(this._setter)) {
|
||||||
return this._setter(this);
|
return this._setter.call(this,this);
|
||||||
}
|
}
|
||||||
return this._setter;
|
return this._setter;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,7 +157,7 @@ export class SettingPropEntry implements SettingEntry {
|
|||||||
|
|
||||||
// ======= compatibles for vision ======
|
// ======= compatibles for vision ======
|
||||||
getNode() {
|
getNode() {
|
||||||
return this.top;
|
return this.nodes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
getName(): string {
|
getName(): string {
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import { isDragNodeDataObject, DragNodeObject, DragNodeDataObject, DropLocation
|
|||||||
import { Node, insertChildren, insertChild, isNode, RootNode, ParentalNode } from './node/node';
|
import { Node, insertChildren, insertChild, isNode, RootNode, ParentalNode } from './node/node';
|
||||||
import { Selection } from './selection';
|
import { Selection } from './selection';
|
||||||
import { History } from './history';
|
import { History } from './history';
|
||||||
import { ExportType } from './node';
|
import { TransformStage } from './node';
|
||||||
|
|
||||||
export type GetDataType<T, NodeType> = T extends undefined
|
export type GetDataType<T, NodeType> = T extends undefined
|
||||||
? NodeType extends {
|
? NodeType extends {
|
||||||
@ -78,13 +78,13 @@ export class DocumentModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(readonly project: Project, schema?: RootSchema) {
|
constructor(readonly project: Project, schema?: RootSchema) {
|
||||||
|
/*
|
||||||
|
// TODO
|
||||||
|
// use special purge process
|
||||||
autorun(() => {
|
autorun(() => {
|
||||||
this.nodes.forEach((item) => {
|
console.info(this.willPurgeSpace);
|
||||||
if (item.parent == null && item !== this.rootNode) {
|
|
||||||
item.purge();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, true);
|
}, true);
|
||||||
|
*/
|
||||||
|
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
this._blank = true;
|
this._blank = true;
|
||||||
@ -103,6 +103,17 @@ export class DocumentModel {
|
|||||||
this.setupListenActiveNodes();
|
this.setupListenActiveNodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@obx.val private willPurgeSpace: Node[] = [];
|
||||||
|
addWillPurge(node: Node) {
|
||||||
|
this.willPurgeSpace.push(node);
|
||||||
|
}
|
||||||
|
removeWillPurge(node: Node) {
|
||||||
|
const i = this.willPurgeSpace.indexOf(node);
|
||||||
|
if (i > -1) {
|
||||||
|
this.willPurgeSpace.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@computed isBlank() {
|
@computed isBlank() {
|
||||||
return this._blank && !this.isModified();
|
return this._blank && !this.isModified();
|
||||||
}
|
}
|
||||||
@ -171,8 +182,10 @@ export class DocumentModel {
|
|||||||
// todo: this.activeNodes?.push(node);
|
// todo: this.activeNodes?.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.nodesMap.has(node.id)) {
|
const origin = this.nodesMap.get(node.id);
|
||||||
this.nodesMap.get(node.id)!.internalSetParent(null);
|
if (origin && origin !== node) {
|
||||||
|
// almost will not go here, ensure the id is unique
|
||||||
|
origin.internalSetWillPurge();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nodesMap.set(node.id, node);
|
this.nodesMap.set(node.id, node);
|
||||||
@ -277,8 +290,8 @@ export class DocumentModel {
|
|||||||
// todo: select added and active track added
|
// todo: select added and active track added
|
||||||
}
|
}
|
||||||
|
|
||||||
export(exportType: ExportType = ExportType.ForSerilize) {
|
export(stage: TransformStage = TransformStage.Serilize) {
|
||||||
return this.rootNode.export(exportType);
|
return this.rootNode.export(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
export enum ExportType {
|
|
||||||
ForRender = 1,
|
|
||||||
ForSerilize = 2,
|
|
||||||
ForSave = 3,
|
|
||||||
}
|
|
||||||
@ -4,4 +4,4 @@ export * from './node-children';
|
|||||||
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';
|
export * from './transform-stage';
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { NodeData, isNodeSchema, obx, computed } from '@ali/lowcode-globals';
|
import { NodeData, isNodeSchema, obx, computed } from '@ali/lowcode-globals';
|
||||||
import { Node, ParentalNode } from './node';
|
import { Node, ParentalNode } from './node';
|
||||||
import { ExportType } from './export-type';
|
import { TransformStage } from './transform-stage';
|
||||||
|
|
||||||
export class NodeChildren {
|
export class NodeChildren {
|
||||||
@obx.val private children: Node[];
|
@obx.val private children: Node[];
|
||||||
@ -17,10 +17,10 @@ export class NodeChildren {
|
|||||||
/**
|
/**
|
||||||
* 导出 schema
|
* 导出 schema
|
||||||
*/
|
*/
|
||||||
export(exportType: ExportType = ExportType.ForSave): NodeData[] {
|
export(stage: TransformStage = TransformStage.Save): NodeData[] {
|
||||||
return this.children.map(node => {
|
return this.children.map(node => {
|
||||||
const data = node.export(exportType);
|
const data = node.export(stage);
|
||||||
if (node.isLeaf() && ExportType.ForSave === exportType) {
|
if (node.isLeaf() && TransformStage.Save === stage) {
|
||||||
// FIXME: filter empty
|
// FIXME: filter empty
|
||||||
return data.children as NodeData;
|
return data.children as NodeData;
|
||||||
}
|
}
|
||||||
@ -202,6 +202,46 @@ export class NodeChildren {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
some(fn: (item: Node, index: number) => any): boolean {
|
||||||
|
return this.children.some((child, index) => fn(child, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeChildren(remover: () => any, adder: (children: Node[]) => NodeData[] | null, sorter: () => any) {
|
||||||
|
/*
|
||||||
|
const children = this.children.slice();
|
||||||
|
children.forEach(child => child.internalSetParent(null));
|
||||||
|
|
||||||
|
this.children = children;
|
||||||
|
this.interalInitParent();
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (remover) {
|
||||||
|
const willRemove = this.children.filter(remover);
|
||||||
|
if (willRemove.length > 0) {
|
||||||
|
willRemove.forEach((node) => {
|
||||||
|
const i = this.children.indexOf(node);
|
||||||
|
if (i > -1) {
|
||||||
|
this.children.splice(i, 1);
|
||||||
|
node.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (adder) {
|
||||||
|
const items = adder(this.children);
|
||||||
|
if (items && items.length > 0) {
|
||||||
|
items.forEach((child: NodeData) => {
|
||||||
|
const node = this.owner.document.createNode(child);
|
||||||
|
this.children.push(node);
|
||||||
|
node.internalSetParent(this.owner);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sorter) {
|
||||||
|
this.children = this.children.sort(sorter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private purged = false;
|
private purged = false;
|
||||||
/**
|
/**
|
||||||
* 回收销毁
|
* 回收销毁
|
||||||
|
|||||||
@ -18,7 +18,9 @@ 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';
|
import { TransformStage } from './transform-stage';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基础节点
|
* 基础节点
|
||||||
@ -136,28 +138,36 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
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;
|
||||||
let _props: Props;
|
|
||||||
if (this.componentName === 'Leaf') {
|
if (this.componentName === 'Leaf') {
|
||||||
_props = new Props(this, {
|
this.props = new Props(this, {
|
||||||
children: isDOMText(children) || isJSExpression(children) ? children : '',
|
children: isDOMText(children) || isJSExpression(children) ? children : '',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// run initialChildren
|
this.props = new Props(this, props, extras);
|
||||||
this._children = new NodeChildren(this as ParentalNode, children || []);
|
this._children = new NodeChildren(this as ParentalNode, this.initialChildren(children));
|
||||||
this._children.interalInitParent();
|
this._children.interalInitParent();
|
||||||
_props = new Props(this, this.upgradeProps(props), extras);
|
this.props.import(this.transformProps(props || {}), extras);
|
||||||
}
|
}
|
||||||
this.props = _props;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private upgradeProps(props: any): any {
|
private transformProps(props: any): any {
|
||||||
// TODO: run componentMeta(initials|initialValue|accessor)
|
// FIXME! support PropsList
|
||||||
// run transform
|
return this.document.designer.transformProps(props, this, TransformStage.Init);
|
||||||
return props;
|
// TODO: run transducers in metadata.experimental
|
||||||
}
|
}
|
||||||
|
|
||||||
private transformOut() {
|
private initialChildren(children: any): NodeData[] {
|
||||||
|
// FIXME! this is dirty code
|
||||||
|
if (children == null) {
|
||||||
|
const initialChildren = this.componentMeta.getMetadata().experimental?.initialChildren;
|
||||||
|
if (initialChildren) {
|
||||||
|
if (typeof initialChildren === 'function') {
|
||||||
|
return initialChildren(this as any) || [];
|
||||||
|
}
|
||||||
|
return initialChildren;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return children || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
isContainer(): boolean {
|
isContainer(): boolean {
|
||||||
@ -194,6 +204,10 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
return this.componentName === 'Leaf';
|
return this.componentName === 'Leaf';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internalSetWillPurge() {
|
||||||
|
this.internalSetParent(null);
|
||||||
|
this.document.addWillPurge(this);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 内部方法,请勿使用
|
* 内部方法,请勿使用
|
||||||
*/
|
*/
|
||||||
@ -207,7 +221,9 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._parent = parent;
|
this._parent = parent;
|
||||||
if (parent && !this.conditionGroup) {
|
if (parent) {
|
||||||
|
this.document.removeWillPurge(this);
|
||||||
|
if (!this.conditionGroup) {
|
||||||
// initial conditionGroup
|
// initial conditionGroup
|
||||||
const grp = this.getExtraProp('conditionGroup', false)?.getAsString();
|
const grp = this.getExtraProp('conditionGroup', false)?.getAsString();
|
||||||
if (grp) {
|
if (grp) {
|
||||||
@ -215,6 +231,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _slotFor?: Prop | null = null;
|
private _slotFor?: Prop | null = null;
|
||||||
internalSetSlotFor(slotFor: Prop | null | undefined) {
|
internalSetSlotFor(slotFor: Prop | null | undefined) {
|
||||||
@ -266,7 +283,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
if (!this.isParental() || this.componentName === 'Fragment') {
|
if (!this.isParental() || this.componentName === 'Fragment') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.props.export(ExportType.ForSerilize).props || null;
|
return this.props.export(TransformStage.Serilize).props || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed hasSlots() {
|
@computed hasSlots() {
|
||||||
@ -427,7 +444,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
* 获取符合搭建协议-节点 schema 结构
|
* 获取符合搭建协议-节点 schema 结构
|
||||||
*/
|
*/
|
||||||
get schema(): Schema {
|
get schema(): Schema {
|
||||||
return this.export(ExportType.ForSave);
|
return this.export(TransformStage.Save);
|
||||||
}
|
}
|
||||||
|
|
||||||
set schema(data: Schema) {
|
set schema(data: Schema) {
|
||||||
@ -448,31 +465,32 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
/**
|
/**
|
||||||
* 导出 schema
|
* 导出 schema
|
||||||
*/
|
*/
|
||||||
export(exportType: ExportType = ExportType.ForSave): Schema {
|
export(stage: TransformStage = TransformStage.Save): Schema {
|
||||||
// run transducers
|
// run transducers
|
||||||
// run
|
// run
|
||||||
const baseSchema: any = {
|
const baseSchema: any = {
|
||||||
componentName: this.componentName,
|
componentName: this.componentName,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (exportType !== ExportType.ForSave) {
|
if (stage !== TransformStage.Save) {
|
||||||
baseSchema.id = this.id;
|
baseSchema.id = this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isLeaf()) {
|
if (this.isLeaf()) {
|
||||||
baseSchema.children = this.props.get('children')?.export(exportType);
|
baseSchema.children = this.props.get('children')?.export(stage);
|
||||||
return baseSchema;
|
return baseSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { props = {}, extras } = this.props.export(exportType) || {};
|
const { props = {}, extras } = this.props.export(stage) || {};
|
||||||
|
|
||||||
const schema: any = {
|
const schema: any = {
|
||||||
...baseSchema,
|
...baseSchema,
|
||||||
props,
|
props: this.document.designer.transformProps(props, this, stage),
|
||||||
...extras,
|
...extras,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.isParental() && this.children.size > 0) {
|
if (this.isParental() && this.children.size > 0) {
|
||||||
schema.children = this.children.export(exportType);
|
schema.children = this.children.export(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
@ -556,6 +574,16 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
getNode() {
|
getNode() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
getRoot() {
|
||||||
|
return this.document.rootNode;
|
||||||
|
}
|
||||||
|
getProps() {
|
||||||
|
return this.props;
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeChildren(remover: () => any, adder: (children: Node[]) => NodeData[] | null, sorter: () => any) {
|
||||||
|
this.children?.mergeChildren(remover, adder, sorter);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
@ -595,10 +623,16 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
}
|
}
|
||||||
return { container: this.parent, ref: this };
|
return { container: this.parent, ref: this };
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
getAddonData(key: string) {
|
getAddonData(key: string) {
|
||||||
return this.getExtraProp(key)?.value;
|
return this.getExtraProp(key)?.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ParentalNode<T extends NodeSchema = NodeSchema> extends Node<T> {
|
export interface ParentalNode<T extends NodeSchema = NodeSchema> extends Node<T> {
|
||||||
@ -693,7 +727,7 @@ export function comparePosition(node1: Node, node2: Node): PositionNO {
|
|||||||
export function insertChild(container: ParentalNode, 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.isSlot())) {
|
if (isNode(thing) && (copy || thing.isSlot())) {
|
||||||
thing = thing.export(ExportType.ForSave);
|
thing = thing.export(TransformStage.Save);
|
||||||
}
|
}
|
||||||
if (isNode(thing)) {
|
if (isNode(thing)) {
|
||||||
node = thing;
|
node = thing;
|
||||||
|
|||||||
@ -15,7 +15,7 @@ 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 { SlotNode } from '../node';
|
import { SlotNode } from '../node';
|
||||||
import { ExportType } from '../export-type';
|
import { TransformStage } from '../transform-stage';
|
||||||
|
|
||||||
export const UNSET = Symbol.for('unset');
|
export const UNSET = Symbol.for('unset');
|
||||||
export type UNSET = typeof UNSET;
|
export type UNSET = typeof UNSET;
|
||||||
@ -46,10 +46,10 @@ export class Prop implements IPropParent {
|
|||||||
* 属性值
|
* 属性值
|
||||||
*/
|
*/
|
||||||
@computed get value(): CompositeValue | UNSET {
|
@computed get value(): CompositeValue | UNSET {
|
||||||
return this.export(ExportType.ForSerilize);
|
return this.export(TransformStage.Serilize);
|
||||||
}
|
}
|
||||||
|
|
||||||
export(exporType: ExportType = ExportType.ForSave): CompositeValue | UNSET {
|
export(stage: TransformStage = TransformStage.Save): CompositeValue | UNSET {
|
||||||
const type = this._type;
|
const type = this._type;
|
||||||
|
|
||||||
if (type === 'unset') {
|
if (type === 'unset') {
|
||||||
@ -61,8 +61,8 @@ export class Prop implements IPropParent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'slot') {
|
if (type === 'slot') {
|
||||||
const schema = this._slotNode!.export(exporType);
|
const schema = this._slotNode!.export(stage);
|
||||||
if (exporType === ExportType.ForSave) {
|
if (stage === TransformStage.Save) {
|
||||||
return {
|
return {
|
||||||
type: 'JSSlot',
|
type: 'JSSlot',
|
||||||
params: schema.params,
|
params: schema.params,
|
||||||
@ -82,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(exporType);
|
const v = prop.export(stage);
|
||||||
if (v !== UNSET) {
|
if (v !== UNSET) {
|
||||||
maps[key] = v;
|
maps[key] = v;
|
||||||
}
|
}
|
||||||
@ -95,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(exporType);
|
const v = prop.export(stage);
|
||||||
return v === UNSET ? null : v;
|
return v === UNSET ? null : v;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -113,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(ExportType.ForSave));
|
return JSON.stringify(this._slotNode!.export(TransformStage.Save));
|
||||||
}
|
}
|
||||||
return this._code != null ? this._code : JSON.stringify(this.value);
|
return this._code != null ? this._code : JSON.stringify(this.value);
|
||||||
}
|
}
|
||||||
@ -191,7 +191,7 @@ export class Prop implements IPropParent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@computed getValue(): CompositeValue {
|
@computed getValue(): CompositeValue {
|
||||||
const v = this.export(ExportType.ForSerilize);
|
const v = this.export(TransformStage.Serilize);
|
||||||
if (v === UNSET) {
|
if (v === UNSET) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +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';
|
import { TransformStage } from '../transform-stage';
|
||||||
|
|
||||||
export const EXTRA_KEY_PREFIX = '___';
|
export const EXTRA_KEY_PREFIX = '___';
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ export class Props implements IPropParent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export(exportType: ExportType = ExportType.ForSave): { props?: PropsMap | PropsList; extras?: object } {
|
export(stage: TransformStage = TransformStage.Save): { props?: PropsMap | PropsList; extras?: object } {
|
||||||
if (this.items.length < 1) {
|
if (this.items.length < 1) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -89,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(exportType);
|
let value = item.export(stage);
|
||||||
if (value === UNSET) {
|
if (value === UNSET) {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ export class Props implements IPropParent {
|
|||||||
// todo ...spread
|
// todo ...spread
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let value = item.export(exportType);
|
let value = item.export(stage);
|
||||||
if (value === UNSET) {
|
if (value === UNSET) {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
@ -296,4 +296,15 @@ export class Props implements IPropParent {
|
|||||||
this.stash.purge();
|
this.stash.purge();
|
||||||
this.items.forEach(item => item.purge());
|
this.items.forEach(item => item.purge());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getProp(path: string, stash = true): Prop | null {
|
||||||
|
return this.query(path, stash as any) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个属性值
|
||||||
|
*/
|
||||||
|
getPropValue(path: string): any {
|
||||||
|
return this.getProp(path, false)?.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
packages/designer/src/document/node/transform-stage.ts
Normal file
6
packages/designer/src/document/node/transform-stage.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export enum TransformStage {
|
||||||
|
Render = 1,
|
||||||
|
Serilize = 2,
|
||||||
|
Save = 3,
|
||||||
|
Init = 4,
|
||||||
|
}
|
||||||
@ -12,6 +12,9 @@ export interface FieldExtraProps {
|
|||||||
* default value of target prop for setter use
|
* default value of target prop for setter use
|
||||||
*/
|
*/
|
||||||
defaultValue?: any;
|
defaultValue?: any;
|
||||||
|
/**
|
||||||
|
* get value for field
|
||||||
|
*/
|
||||||
getValue?: (target: SettingTarget, fieldValue: any) => any;
|
getValue?: (target: SettingTarget, fieldValue: any) => any;
|
||||||
setValue?: (target: SettingTarget, value: any) => void;
|
setValue?: (target: SettingTarget, value: any) => void;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import { TitleContent } from './title';
|
|||||||
import { PropConfig } from './prop-config';
|
import { PropConfig } from './prop-config';
|
||||||
import { NpmInfo } from './npm';
|
import { NpmInfo } from './npm';
|
||||||
import { FieldConfig } from './field-config';
|
import { FieldConfig } from './field-config';
|
||||||
import { NodeSchema } from './schema';
|
import { NodeSchema, NodeData } from './schema';
|
||||||
|
import { SettingTarget } from './setting-target';
|
||||||
|
|
||||||
export type NestingFilter = (testNode: any, currentNode: any) => boolean;
|
export type NestingFilter = (testNode: any, currentNode: any) => boolean;
|
||||||
export interface NestingRule {
|
export interface NestingRule {
|
||||||
@ -40,12 +41,20 @@ export interface Snippet {
|
|||||||
schema: NodeSchema;
|
schema: NodeSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface InitialItem {
|
||||||
|
name: string;
|
||||||
|
initial: (target: SettingTarget, currentValue: any) => any;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Experimental {
|
export interface Experimental {
|
||||||
context?: { [contextInfoName: string]: any };
|
context?: { [contextInfoName: string]: any };
|
||||||
snippets?: Snippet[];
|
snippets?: Snippet[];
|
||||||
view?: ComponentType<any>;
|
view?: ComponentType<any>;
|
||||||
transducers?: any; // ? should support
|
transducers?: any; // ? should support
|
||||||
|
initials?: InitialItem[];
|
||||||
callbacks?: Callbacks;
|
callbacks?: Callbacks;
|
||||||
|
// TODO: thinkof function
|
||||||
|
initialChildren?: NodeData[] | ((target: SettingTarget) => NodeData[]);
|
||||||
|
|
||||||
// 样式 及 位置,handle上必须有明确的标识以便事件路由判断,或者主动设置事件独占模式
|
// 样式 及 位置,handle上必须有明确的标识以便事件路由判断,或者主动设置事件独占模式
|
||||||
// NWSE 是交给引擎计算放置位置,ReactElement 必须自己控制初始位置
|
// NWSE 是交给引擎计算放置位置,ReactElement 必须自己控制初始位置
|
||||||
|
|||||||
@ -21,6 +21,11 @@ export interface JSSlot {
|
|||||||
value?: NodeData[] | NodeData;
|
value?: NodeData[] | NodeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface JSBlock {
|
||||||
|
type: 'JSBlock';
|
||||||
|
value: NodeSchema;
|
||||||
|
}
|
||||||
|
|
||||||
// JSON 基本类型
|
// JSON 基本类型
|
||||||
export type JSONValue = boolean | string | number | null | JSONArray | JSONObject;
|
export type JSONValue = boolean | string | number | null | JSONArray | JSONObject;
|
||||||
export type JSONArray = JSONValue[];
|
export type JSONArray = JSONValue[];
|
||||||
@ -43,3 +48,7 @@ export function isJSExpression(data: any): data is JSExpression {
|
|||||||
export function isJSSlot(data: any): data is JSSlot {
|
export function isJSSlot(data: any): data is JSSlot {
|
||||||
return data && data.type === 'JSSlot';
|
return data && data.type === 'JSSlot';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isJSBlock(data: any): data is JSBlock {
|
||||||
|
return data && data.type === 'JSBlock'
|
||||||
|
}
|
||||||
|
|||||||
@ -63,13 +63,11 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info('metadatas', componentMetadatas);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DesignerView
|
<DesignerView
|
||||||
onMount={this.handleDesignerMount}
|
onMount={this.handleDesignerMount}
|
||||||
className="lowcode-plugin-designer"
|
className="lowcode-plugin-designer"
|
||||||
eventPipe={editor}
|
editor={editor}
|
||||||
designer={editor.get(Designer)}
|
designer={editor.get(Designer)}
|
||||||
componentMetadatas={componentMetadatas}
|
componentMetadatas={componentMetadatas}
|
||||||
simulatorProps={{
|
simulatorProps={{
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { Component, Fragment } from 'react';
|
import { Component, Fragment } from 'react';
|
||||||
import { Icon, Button, Message } from '@alifd/next';
|
import { Icon, Button, Message } from '@alifd/next';
|
||||||
import { Title, SetterType, FieldConfig, SetterConfig } from '@ali/lowcode-globals';
|
import { Title, SetterType, FieldConfig, SetterConfig } from '@ali/lowcode-globals';
|
||||||
import { SettingField } from '../../settings/setting-field';
|
|
||||||
import { createSettingFieldView } from '../../settings/settings-pane';
|
import { createSettingFieldView } from '../../settings/settings-pane';
|
||||||
import { PopupContext, PopupPipe } from '../../popup';
|
import { PopupContext, PopupPipe } from '../../popup';
|
||||||
import Sortable from './sortable';
|
import Sortable from './sortable';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
|
import { SettingField } from '@ali/lowcode-designer';
|
||||||
|
|
||||||
interface ArraySetterState {
|
interface ArraySetterState {
|
||||||
items: SettingField[];
|
items: SettingField[];
|
||||||
|
|||||||
@ -20,10 +20,10 @@ import {
|
|||||||
EmbedTip,
|
EmbedTip,
|
||||||
isI18nData,
|
isI18nData,
|
||||||
} from '@ali/lowcode-globals';
|
} from '@ali/lowcode-globals';
|
||||||
import { SettingField } from '../../settings/setting-field';
|
|
||||||
import { IconConvert } from '../../icons/convert';
|
import { IconConvert } from '../../icons/convert';
|
||||||
|
|
||||||
import './style.less';
|
import './style.less';
|
||||||
|
import { SettingField } from '@ali/lowcode-designer';
|
||||||
|
|
||||||
export interface SetterItem {
|
export interface SetterItem {
|
||||||
name: string;
|
name: string;
|
||||||
@ -180,7 +180,7 @@ export default class MixedSetter extends Component<{
|
|||||||
let setterProps: any = {};
|
let setterProps: any = {};
|
||||||
let setterType: any;
|
let setterType: any;
|
||||||
if (isDynamicSetter(setter)) {
|
if (isDynamicSetter(setter)) {
|
||||||
setterType = setter(field);
|
setterType = setter.call(field, field);
|
||||||
} else {
|
} else {
|
||||||
setterType = setter;
|
setterType = setter;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import { Component, Fragment } from 'react';
|
|||||||
import { Icon, Button } from '@alifd/next';
|
import { Icon, Button } from '@alifd/next';
|
||||||
import { Title, SetterType, FieldConfig } from '@ali/lowcode-globals';
|
import { Title, SetterType, FieldConfig } from '@ali/lowcode-globals';
|
||||||
import { createSettingFieldView } from '../../settings/settings-pane';
|
import { createSettingFieldView } from '../../settings/settings-pane';
|
||||||
import { SettingField } from '../../settings/setting-field';
|
|
||||||
import { PopupContext, PopupPipe } from '../../popup';
|
import { PopupContext, PopupPipe } from '../../popup';
|
||||||
|
import { SettingField } from '@ali/lowcode-designer';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
|
|
||||||
export default class ObjectSetter extends Component<{
|
export default class ObjectSetter extends Component<{
|
||||||
|
|||||||
@ -4,23 +4,24 @@ import PropTypes from 'prop-types';
|
|||||||
import Debug from 'debug';
|
import Debug from 'debug';
|
||||||
import AppContext from '../context/appContext';
|
import AppContext from '../context/appContext';
|
||||||
import { isFileSchema, goldlog } from '../utils';
|
import { isFileSchema, goldlog } from '../utils';
|
||||||
import Page from './pageEngine';
|
import PageEngine from './pageEngine';
|
||||||
import Component from './compEngine';
|
import ComponentEngine from './compEngine';
|
||||||
import Block from './blockEngine';
|
import BlockEngine from './blockEngine';
|
||||||
import Addon from './addonEngine';
|
import AddonEngine from './addonEngine';
|
||||||
import Temp from './tempEngine';
|
import TempEngine from './tempEngine';
|
||||||
import { isEmpty } from '@ali/b3-one/lib/obj';
|
import { isEmpty } from '@ali/b3-one/lib/obj';
|
||||||
|
import BaseEngine from './base';
|
||||||
|
|
||||||
window.React = React;
|
window.React = React;
|
||||||
window.ReactDom = ReactDOM;
|
window.ReactDom = ReactDOM;
|
||||||
|
|
||||||
const debug = Debug('engine:entry');
|
const debug = Debug('engine:entry');
|
||||||
const ENGINE_COMPS = {
|
const ENGINE_COMPS = {
|
||||||
Page,
|
PageEngine,
|
||||||
Component,
|
ComponentEngine,
|
||||||
Block,
|
BlockEngine,
|
||||||
Addon,
|
AddonEngine,
|
||||||
Temp,
|
TempEngine,
|
||||||
};
|
};
|
||||||
export default class Engine extends PureComponent {
|
export default class Engine extends PureComponent {
|
||||||
static dislayName = 'engine';
|
static dislayName = 'engine';
|
||||||
@ -98,8 +99,15 @@ export default class Engine extends PureComponent {
|
|||||||
return '模型结构异常';
|
return '模型结构异常';
|
||||||
}
|
}
|
||||||
debug('entry.render');
|
debug('entry.render');
|
||||||
const allComponents = { ...components, ...ENGINE_COMPS };
|
const { componentName } = schema;
|
||||||
const Comp = allComponents[schema.componentName];
|
const allComponents = { ...ENGINE_COMPS, ...components };
|
||||||
|
let Comp = allComponents[componentName];
|
||||||
|
if (Comp && Comp.prototype) {
|
||||||
|
const proto = Comp.prototype;
|
||||||
|
if (!(Comp.prototype instanceof BaseEngine)) {
|
||||||
|
Comp = ENGINE_COMPS[`${componentName}Engine`];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Comp) {
|
if (Comp) {
|
||||||
return (
|
return (
|
||||||
<AppContext.Provider
|
<AppContext.Provider
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export default class PageEngine extends BaseEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { __schema } = this.props;
|
const { __schema, __components } = this.props;
|
||||||
if (!isSchema(__schema, true) || __schema.componentName !== 'Page') {
|
if (!isSchema(__schema, true) || __schema.componentName !== 'Page') {
|
||||||
return '页面schema结构异常!';
|
return '页面schema结构异常!';
|
||||||
}
|
}
|
||||||
@ -72,7 +72,34 @@ export default class PageEngine extends BaseEngine {
|
|||||||
});
|
});
|
||||||
this.__render();
|
this.__render();
|
||||||
|
|
||||||
const { id, className, style, autoLoading, defaultHeight = 300, loading } = this.__parseData(__schema.props);
|
const props = this.__parseData(__schema.props);
|
||||||
|
const { id, className, style, autoLoading, defaultHeight = 300, loading } = props;
|
||||||
|
|
||||||
|
const { Page } = __components;
|
||||||
|
if (Page) {
|
||||||
|
const { engine } = this.context || {};
|
||||||
|
return (
|
||||||
|
<AppContext.Provider
|
||||||
|
value={{
|
||||||
|
...this.context,
|
||||||
|
pageContext: this,
|
||||||
|
blockContext: this,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{engine.createElement(
|
||||||
|
Page,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
ref: this.__getRef,
|
||||||
|
className: classnames(getFileCssName(__schema.fileName), className, this.props.className),
|
||||||
|
__id: __schema.id,
|
||||||
|
},
|
||||||
|
this.__createDom(),
|
||||||
|
)}
|
||||||
|
</AppContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const renderContent = () => (
|
const renderContent = () => (
|
||||||
<AppContext.Provider
|
<AppContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
|||||||
@ -41,7 +41,6 @@ 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}
|
||||||
@ -55,7 +54,11 @@ class Renderer extends Component<{ renderer: SimulatorRenderer }> {
|
|||||||
const { __id, __desingMode, ...viewProps } = props;
|
const { __id, __desingMode, ...viewProps } = props;
|
||||||
viewProps.componentId = __id;
|
viewProps.componentId = __id;
|
||||||
viewProps._leaf = host.document.getNode(__id);
|
viewProps._leaf = host.document.getNode(__id);
|
||||||
return createElement(Component, viewProps, children);
|
return createElement(
|
||||||
|
Component,
|
||||||
|
viewProps,
|
||||||
|
children == null ? null : Array.isArray(children) ? children : [children],
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
onCompGetRef={(schema: any, ref: ReactInstance | null) => {
|
onCompGetRef={(schema: any, ref: ReactInstance | null) => {
|
||||||
renderer.mountInstance(schema.id, ref);
|
renderer.mountInstance(schema.id, ref);
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
html {
|
|
||||||
padding-bottom: 30px;
|
|
||||||
background: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body, html {
|
body, html {
|
||||||
display: block;
|
display: block;
|
||||||
min-height: 100%;
|
|
||||||
background: white;
|
background: white;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
html.engine-design-mode {
|
||||||
|
padding-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.engine-cursor-move, html.engine-cursor-move * {
|
html.engine-cursor-move, html.engine-cursor-move * {
|
||||||
@ -21,28 +20,6 @@ html.engine-cursor-ew-resize, html.engine-cursor-ew-resize * {
|
|||||||
cursor: ew-resize !important
|
cursor: ew-resize !important
|
||||||
}
|
}
|
||||||
|
|
||||||
body, #engine {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
top: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-webkit-user-drag: none;
|
|
||||||
-webkit-text-size-adjust: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
min-width: 1024px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 5px;
|
width: 5px;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
@ -53,10 +30,6 @@ html {
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.engine-blur #engine {
|
|
||||||
-webkit-filter: blur(4px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.lc-container {
|
.lc-container {
|
||||||
&:empty {
|
&:empty {
|
||||||
background: #f2f3f5;
|
background: #f2f3f5;
|
||||||
@ -101,3 +74,17 @@ html.engine-blur #engine {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.engine-document {
|
||||||
|
&:after, &:before {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
&:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|||||||
@ -244,6 +244,9 @@ export class SimulatorRenderer implements BuiltinSimulatorRenderer {
|
|||||||
document.body.appendChild(container);
|
document.body.appendChild(container);
|
||||||
container.id = containerId;
|
container.id = containerId;
|
||||||
}
|
}
|
||||||
|
// ==== compatiable vision
|
||||||
|
document.documentElement.classList.add('engine-page');
|
||||||
|
document.body.classList.add('engine-document'); // important! Stylesheet.invoke depends
|
||||||
|
|
||||||
reactRender(createElement(SimulatorRendererView, { renderer: this }), container);
|
reactRender(createElement(SimulatorRendererView, { renderer: this }), container);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { registerSetter } from '@ali/lowcode-globals';
|
import { registerSetter, isJSSlot } from '@ali/lowcode-globals';
|
||||||
import { DatePicker, Input, Radio, Select, Switch, NumberPicker } from '@alifd/next';
|
import { DatePicker, Input, Radio, Select, Switch, NumberPicker } from '@alifd/next';
|
||||||
import ExpressionSetter from './expression-setter';
|
import ExpressionSetter from './expression-setter';
|
||||||
import MixinSetter from './mixin-setter';
|
import MixinSetter from './mixin-setter';
|
||||||
@ -10,12 +10,7 @@ import EventsSetter from './events-setter';
|
|||||||
export const StringSetter = {
|
export const StringSetter = {
|
||||||
component: Input,
|
component: Input,
|
||||||
defaultProps: { placeholder: '请输入' },
|
defaultProps: { placeholder: '请输入' },
|
||||||
title: 'StringSetter', // TODO
|
title: 'StringSetter',
|
||||||
condition: (field: any) => {
|
|
||||||
const v = field.getValue();
|
|
||||||
return v == null || typeof v === 'string';
|
|
||||||
},
|
|
||||||
initialValue: '',
|
|
||||||
recommend: true,
|
recommend: true,
|
||||||
};
|
};
|
||||||
export const NumberSetter = NumberPicker;
|
export const NumberSetter = NumberPicker;
|
||||||
@ -43,12 +38,38 @@ export const ClassNameSetter = () => {
|
|||||||
return <div className="lc-block-setter">这里是类名绑定</div>;
|
return <div className="lc-block-setter">这里是类名绑定</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const builtinSetters = {
|
export const SlotSetter = () => {
|
||||||
|
return <div>这里是 SlotSetter</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const builtinSetters: any = {
|
||||||
StringSetter,
|
StringSetter,
|
||||||
NumberSetter,
|
NumberSetter,
|
||||||
BoolSetter,
|
BoolSetter,
|
||||||
SelectSetter,
|
SelectSetter,
|
||||||
ExpressionSetter: ExpressionSetter as any,
|
ExpressionSetter: {
|
||||||
|
component: ExpressionSetter,
|
||||||
|
defaultProps: { placeholder: '请输入表达式' },
|
||||||
|
title: '表达式输入',
|
||||||
|
recommend: true,
|
||||||
|
},
|
||||||
|
SlotSetter: {
|
||||||
|
component: SlotSetter,
|
||||||
|
title: '插槽输入',
|
||||||
|
condition: (field: any) => {
|
||||||
|
return isJSSlot(field.getValue());
|
||||||
|
},
|
||||||
|
initialValue: (field: any, value: any) => {
|
||||||
|
if (isJSSlot(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'JSSlot',
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
},
|
||||||
|
recommend: true,
|
||||||
|
},
|
||||||
MixinSetter,
|
MixinSetter,
|
||||||
RadioGroupSetter,
|
RadioGroupSetter,
|
||||||
TextAreaSetter,
|
TextAreaSetter,
|
||||||
|
|||||||
@ -70,6 +70,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<!-- lowcode engine globals -->
|
<!-- lowcode engine globals -->
|
||||||
<script src="/js/vision.js"></script>
|
<script src="/js/vision.js"></script>
|
||||||
<script src="https://g.alicdn.com/vision/visualengine-utils/4.3.1/engine-utils.js"></script>
|
<!-- <script src="https://g.alicdn.com/vision/visualengine-utils/4.3.1/engine-utils.js"></script> -->
|
||||||
|
<script src="https://dev.g.alicdn.com/vision/visualengine-utils/5.0.0/engine-utils.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -14,128 +14,5 @@
|
|||||||
"padding": 20
|
"padding": 20
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"children": [{
|
"children": []
|
||||||
"componentName": "Form",
|
|
||||||
"props": {
|
|
||||||
"labelCol": 3,
|
|
||||||
"style": {},
|
|
||||||
"ref": "testForm"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"props": {
|
|
||||||
"label": "姓名:",
|
|
||||||
"name": "name",
|
|
||||||
"initValue": "李雷"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Input",
|
|
||||||
"props": {
|
|
||||||
"placeholder": "请输入",
|
|
||||||
"size": "medium",
|
|
||||||
"style": {
|
|
||||||
"width": 320
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"props": {
|
|
||||||
"label": "年龄:",
|
|
||||||
"name": "age",
|
|
||||||
"initValue": "22"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "NumberPicker",
|
|
||||||
"props": {
|
|
||||||
"size": "medium",
|
|
||||||
"type": "normal"
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Form.Item",
|
|
||||||
"props": {
|
|
||||||
"label": "职业:",
|
|
||||||
"name": "profession"
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Select",
|
|
||||||
"props": {
|
|
||||||
"dataSource": [{
|
|
||||||
"label": "教师",
|
|
||||||
"value": "t"
|
|
||||||
}, {
|
|
||||||
"label": "医生",
|
|
||||||
"value": "d"
|
|
||||||
}, {
|
|
||||||
"label": "歌手",
|
|
||||||
"value": "s"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
"componentName": "Div",
|
|
||||||
"props": {
|
|
||||||
"style": {
|
|
||||||
"textAlign": "center"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Div",
|
|
||||||
"props": {},
|
|
||||||
"children": [{
|
|
||||||
"componentName": "Button",
|
|
||||||
"props": {
|
|
||||||
"type": "primary",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "submit"
|
|
||||||
},
|
|
||||||
"children": "提交"
|
|
||||||
}, {
|
|
||||||
"componentName": "Button",
|
|
||||||
"props": {
|
|
||||||
"type": "normal",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "reset",
|
|
||||||
"children": {
|
|
||||||
"type": "JSSlot",
|
|
||||||
"value": {
|
|
||||||
"componentName": "Div",
|
|
||||||
"children": "重置"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"loop": [1,2,3]
|
|
||||||
}, {
|
|
||||||
"componentName": "Button",
|
|
||||||
"props": {
|
|
||||||
"type": "normal",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "reset"
|
|
||||||
},
|
|
||||||
"children": "重置",
|
|
||||||
"condition": true,
|
|
||||||
"conditionGroup": "1"
|
|
||||||
}, {
|
|
||||||
"componentName": "Button",
|
|
||||||
"props": {
|
|
||||||
"type": "normal",
|
|
||||||
"style": {
|
|
||||||
"margin": "0 5px 0 5px"
|
|
||||||
},
|
|
||||||
"htmlType": "reset"
|
|
||||||
},
|
|
||||||
"children": "重置",
|
|
||||||
"condition": false,
|
|
||||||
"conditionGroup": "1"
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import lg from '@ali/vu-logger';
|
import lg from '@ali/vu-logger';
|
||||||
import { ComponentClass, ComponentType } from 'react';
|
import { ComponentClass, ComponentType } from 'react';
|
||||||
import Prototype from './prototype';
|
import Prototype from './prototype';
|
||||||
import { ComponentMeta } from '@ali/lowcode-designer';
|
|
||||||
import { designer } from '../editor';
|
import { designer } from '../editor';
|
||||||
|
|
||||||
function basename(name: string) {
|
function basename(name: string) {
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
import { ComponentType, ReactElement } from 'react';
|
import { ComponentType, ReactElement } from 'react';
|
||||||
import { ComponentMetadata, uniqueId, registerMetadataTransducer, FieldConfig } from '@ali/lowcode-globals';
|
import {
|
||||||
|
ComponentMetadata,
|
||||||
|
uniqueId,
|
||||||
|
registerMetadataTransducer,
|
||||||
|
FieldConfig,
|
||||||
|
InitialItem,
|
||||||
|
} from '@ali/lowcode-globals';
|
||||||
import { ComponentMeta, addBuiltinComponentAction, isComponentMeta } from '@ali/lowcode-designer';
|
import { ComponentMeta, addBuiltinComponentAction, isComponentMeta } from '@ali/lowcode-designer';
|
||||||
import {
|
import {
|
||||||
OldPropConfig,
|
OldPropConfig,
|
||||||
@ -11,25 +17,41 @@ import {
|
|||||||
} from './upgrade-metadata';
|
} from './upgrade-metadata';
|
||||||
import { designer } from '../editor';
|
import { designer } from '../editor';
|
||||||
|
|
||||||
const GlobalPropsConfigure: Array<FieldConfig & { position: string }> = [];
|
const GlobalPropsConfigure: Array<{ position: string; initials?: InitialItem[]; config: FieldConfig }> = [];
|
||||||
const Overrides: any = {};
|
const Overrides: {
|
||||||
|
[componentName: string]: {
|
||||||
|
initials?: InitialItem[];
|
||||||
|
config: any;
|
||||||
|
};
|
||||||
|
} = {};
|
||||||
|
|
||||||
function addGlobalPropsConfigure(config: OldGlobalPropConfig) {
|
function addGlobalPropsConfigure(config: OldGlobalPropConfig) {
|
||||||
|
const initials: InitialItem[] = [];
|
||||||
GlobalPropsConfigure.push({
|
GlobalPropsConfigure.push({
|
||||||
position: config.position,
|
position: config.position || 'bottom',
|
||||||
...upgradePropConfig(config),
|
initials,
|
||||||
|
config: upgradePropConfig(config, (item) => {
|
||||||
|
initials.push(item);
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function removeGlobalPropsConfigure(name: string) {
|
function removeGlobalPropsConfigure(name: string) {
|
||||||
let l = GlobalPropsConfigure.length;
|
let l = GlobalPropsConfigure.length;
|
||||||
while (l-- > 0) {
|
while (l-- > 0) {
|
||||||
if (GlobalPropsConfigure[l].name === name) {
|
if (GlobalPropsConfigure[l].config.name === name) {
|
||||||
GlobalPropsConfigure.splice(l, 1);
|
GlobalPropsConfigure.splice(l, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function overridePropsConfigure(componentName: string, config: OldPropConfig | OldPropConfig[]) {
|
function overridePropsConfigure(componentName: string, config: OldPropConfig | OldPropConfig[]) {
|
||||||
Overrides[componentName] = Array.isArray(config) ? upgradeConfigure(config) : upgradePropConfig(config);
|
const initials: InitialItem[] = [];
|
||||||
|
const addInitial = (item: InitialItem) => {
|
||||||
|
initials.push(item);
|
||||||
|
};
|
||||||
|
Overrides[componentName] = {
|
||||||
|
initials,
|
||||||
|
config: Array.isArray(config) ? upgradeConfigure(config, addInitial) : upgradePropConfig(config, addInitial),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
registerMetadataTransducer(
|
registerMetadataTransducer(
|
||||||
(metadata) => {
|
(metadata) => {
|
||||||
@ -49,28 +71,28 @@ registerMetadataTransducer(
|
|||||||
metadata.configure.props = top = bottom = [];
|
metadata.configure.props = top = bottom = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalPropsConfigure.forEach((config) => {
|
GlobalPropsConfigure.forEach((item) => {
|
||||||
const position = config.position || 'bottom';
|
const position = item.position || 'bottom';
|
||||||
|
|
||||||
if (position === 'top') {
|
if (position === 'top') {
|
||||||
top.unshift(config);
|
top.unshift(item.config);
|
||||||
} else if (position === 'bottom') {
|
} else if (position === 'bottom') {
|
||||||
bottom.push(config);
|
bottom.push(item.config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const override = Overrides[componentName];
|
const override = Overrides[componentName];
|
||||||
if (override) {
|
if (override) {
|
||||||
if (Array.isArray(override)) {
|
if (Array.isArray(override.config)) {
|
||||||
metadata.configure.combined = override;
|
metadata.configure.combined = override.config;
|
||||||
} else {
|
} else {
|
||||||
let l = top.length;
|
let l = top.length;
|
||||||
let item;
|
let item;
|
||||||
while (l-- > 0) {
|
while (l-- > 0) {
|
||||||
item = top[l];
|
item = top[l];
|
||||||
if (item.name in override) {
|
if (item.name in override) {
|
||||||
if (override[item.name]) {
|
if (override.config[item.name]) {
|
||||||
top.splice(l, 1, override[item.name]);
|
top.splice(l, 1, override.config[item.name]);
|
||||||
} else {
|
} else {
|
||||||
top.splice(l, 1);
|
top.splice(l, 1);
|
||||||
}
|
}
|
||||||
@ -78,6 +100,8 @@ registerMetadataTransducer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO FIXME! append override & globalConfigure initials and then unique
|
||||||
return metadata;
|
return metadata;
|
||||||
},
|
},
|
||||||
100,
|
100,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { ComponentType, ReactElement, isValidElement, ComponentClass } from 'react';
|
import { ComponentType, ReactElement, isValidElement, ComponentClass } from 'react';
|
||||||
import { isI18nData, SettingTarget } from '@ali/lowcode-globals';
|
import { isI18nData, SettingTarget, InitialItem, isPlainObject, isJSSlot, isJSExpression } from '@ali/lowcode-globals';
|
||||||
|
|
||||||
type Field = SettingTarget;
|
type Field = SettingTarget;
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ export interface OldPropConfig {
|
|||||||
url?: string;
|
url?: string;
|
||||||
};
|
};
|
||||||
defaultValue?: any; // => extraProps.defaultValue
|
defaultValue?: any; // => extraProps.defaultValue
|
||||||
initialValue?: any | ((value: any, defaultValue: any) => any); // => extraProps.initialValue
|
initialValue?: any | ((value: any, defaultValue: any) => any); // => initials.initialValue
|
||||||
initial?: (value: any, defaultValue: any) => any // => extraProps.initialValue
|
initial?: (value: any, defaultValue: any) => any // => initials.initialValue
|
||||||
|
|
||||||
display?: DISPLAY_TYPE; // => fieldExtraProps
|
display?: DISPLAY_TYPE; // => fieldExtraProps
|
||||||
fieldStyle?: DISPLAY_TYPE; // => fieldExtraProps
|
fieldStyle?: DISPLAY_TYPE; // => fieldExtraProps
|
||||||
@ -175,7 +175,7 @@ type SetterGetter = (this: Field, value: any) => ComponentClass;
|
|||||||
|
|
||||||
type ReturnBooleanFunction = (this: Field, value: any) => boolean;
|
type ReturnBooleanFunction = (this: Field, value: any) => boolean;
|
||||||
|
|
||||||
export function upgradePropConfig(config: OldPropConfig) {
|
export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) {
|
||||||
const {
|
const {
|
||||||
type,
|
type,
|
||||||
name,
|
name,
|
||||||
@ -258,6 +258,7 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
extraProps.condition = (field: Field) => !(isHidden(field) || isDisabled(field));
|
extraProps.condition = (field: Field) => !(isHidden(field) || isDisabled(field));
|
||||||
}
|
}
|
||||||
if (ignore != null || disabled != null) {
|
if (ignore != null || disabled != null) {
|
||||||
|
// FIXME! addFilter
|
||||||
extraProps.virtual = (field: Field) => {
|
extraProps.virtual = (field: Field) => {
|
||||||
if (isDisabled(field)) { return true; }
|
if (isDisabled(field)) { return true; }
|
||||||
|
|
||||||
@ -269,31 +270,7 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'group') {
|
if (type === 'group') {
|
||||||
newConfig.items = items ? upgradeConfigure(items) : [];
|
newConfig.items = items ? upgradeConfigure(items, addInitial) : [];
|
||||||
return newConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slotName) {
|
|
||||||
newConfig.name = slotName;
|
|
||||||
if (!newConfig.title && slotTitle) {
|
|
||||||
newConfig.title = slotTitle;
|
|
||||||
}
|
|
||||||
const slotSetter = {
|
|
||||||
componentName: 'SlotSetter',
|
|
||||||
initialValue: () => ({
|
|
||||||
type: 'JSSlot',
|
|
||||||
value: initialChildren
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
if (allowTextInput === false) {
|
|
||||||
newConfig.setter = slotSetter;
|
|
||||||
} else {
|
|
||||||
newConfig.setter = [{
|
|
||||||
componentName: 'StringSetter',
|
|
||||||
initialValue,
|
|
||||||
}, slotSetter];
|
|
||||||
}
|
|
||||||
|
|
||||||
return newConfig;
|
return newConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,29 +280,30 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
extraProps.defaultValue = initialValue;
|
extraProps.defaultValue = initialValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let initialFn = initial || initialValue;
|
let initialFn = (slotName ? null : initial) || initialValue;
|
||||||
|
|
||||||
if (accessor) {
|
if (accessor && !slotName) {
|
||||||
extraProps.getValue = (field: Field, fieldValue: any) => {
|
extraProps.getValue = (field: Field, fieldValue: any) => {
|
||||||
return accessor.call(field, fieldValue);
|
return accessor.call(field, fieldValue);
|
||||||
};
|
};
|
||||||
if (!initialFn) {
|
if (!initialFn) {
|
||||||
// FIXME!
|
initialFn = accessor;
|
||||||
initialFn
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extraProps.initialValue = (field: Field, currentValue: any, defaultValue?: any) => {
|
|
||||||
if (defaultValue === undefined) {
|
addInitial({
|
||||||
defaultValue = extraProps.defaultValue;
|
name: slotName || name,
|
||||||
}
|
initial: (field: Field, currentValue: any) => {
|
||||||
|
// FIXME! read from prototype.defaultProps
|
||||||
|
const defaults = extraProps.defaultValue;
|
||||||
|
|
||||||
if (typeof initialFn === 'function') {
|
if (typeof initialFn === 'function') {
|
||||||
// ?
|
return initialFn.call(field, currentValue, defaults);
|
||||||
return initialFn.call(field, currentValue, defaultValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultValue;
|
return currentValue == null ? defaults : currentValue;
|
||||||
};
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
extraProps.autorun = (field: Field) => {
|
extraProps.autorun = (field: Field) => {
|
||||||
@ -335,15 +313,61 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mutator) {
|
if (mutator && !slotName) {
|
||||||
extraProps.setValue = (field: Field, value: any) => {
|
extraProps.setValue = (field: Field, value: any) => {
|
||||||
mutator.call(field, value);
|
mutator.call(field, value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (slotName) {
|
||||||
|
newConfig.name = slotName;
|
||||||
|
if (!newConfig.title && slotTitle) {
|
||||||
|
newConfig.title = slotTitle;
|
||||||
|
}
|
||||||
|
const setters: any[] = [{
|
||||||
|
componentName: 'SlotSetter',
|
||||||
|
initialValue: (field: any, value: any) => {
|
||||||
|
if (isJSSlot(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'JSSlot',
|
||||||
|
value: value == null ? initialChildren : value
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
if (allowTextInput !== false) {
|
||||||
|
setters.unshift('StringSetter');
|
||||||
|
// FIXME: use I18nSetter
|
||||||
|
}
|
||||||
|
if (supportVariable) {
|
||||||
|
setters.push('ExpressionSetter');
|
||||||
|
}
|
||||||
|
newConfig.setter = setters.length > 1 ? setters : setters[0];
|
||||||
|
|
||||||
|
return newConfig;
|
||||||
|
}
|
||||||
|
|
||||||
let primarySetter: any;
|
let primarySetter: any;
|
||||||
if (type === 'composite') {
|
if (type === 'composite') {
|
||||||
const objItems = items ? upgradeConfigure(items) : [];
|
const initials: InitialItem[] = [];
|
||||||
|
const objItems = items ? upgradeConfigure(items, (item) => {
|
||||||
|
initials.push(item);
|
||||||
|
}) : [];
|
||||||
|
const initial = (target: SettingTarget, value?: any) => {
|
||||||
|
// TODO:
|
||||||
|
const defaults = extraProps.defaultValue;
|
||||||
|
const data: any = {};
|
||||||
|
initials.forEach(item => {
|
||||||
|
// FIXME! Target may be a wrong
|
||||||
|
data[item.name] = item.initial(target, isPlainObject(value) ? value[item.name] : null);
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
addInitial({
|
||||||
|
name,
|
||||||
|
initial,
|
||||||
|
});
|
||||||
primarySetter = {
|
primarySetter = {
|
||||||
componentName: 'ObjectSetter',
|
componentName: 'ObjectSetter',
|
||||||
props: {
|
props: {
|
||||||
@ -352,12 +376,12 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
initialValue: (field: Field) => {
|
initialValue: (field: Field) => {
|
||||||
// FIXME: read from objItems
|
return initial(field, field.getValue());
|
||||||
return extraProps.initialValue(field, {});
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else if (setter) {
|
} else if (setter) {
|
||||||
if (Array.isArray(setter)) {
|
if (Array.isArray(setter)) {
|
||||||
|
// FIXME! read initial from setter
|
||||||
primarySetter = setter.map(({ setter, condition }) => {
|
primarySetter = setter.map(({ setter, condition }) => {
|
||||||
return {
|
return {
|
||||||
componentName: setter,
|
componentName: setter,
|
||||||
@ -393,7 +417,9 @@ export function upgradePropConfig(config: OldPropConfig) {
|
|||||||
return newConfig;
|
return newConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function upgradeConfigure(items: OldPropConfig[]) {
|
type AddIntial = (initialItem: InitialItem) => void;
|
||||||
|
|
||||||
|
export function upgradeConfigure(items: OldPropConfig[], addInitial: AddIntial) {
|
||||||
const configure: any[] = [];
|
const configure: any[] = [];
|
||||||
let ignoreSlotName: any = null;
|
let ignoreSlotName: any = null;
|
||||||
items.forEach((config) => {
|
items.forEach((config) => {
|
||||||
@ -406,7 +432,7 @@ export function upgradeConfigure(items: OldPropConfig[]) {
|
|||||||
}
|
}
|
||||||
ignoreSlotName = null;
|
ignoreSlotName = null;
|
||||||
}
|
}
|
||||||
configure.push(upgradePropConfig(config));
|
configure.push(upgradePropConfig(config, addInitial));
|
||||||
});
|
});
|
||||||
return configure;
|
return configure;
|
||||||
}
|
}
|
||||||
@ -542,7 +568,7 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
|
|||||||
if (snippets) {
|
if (snippets) {
|
||||||
experimental.snippets = snippets.map(data => {
|
experimental.snippets = snippets.map(data => {
|
||||||
const { schema = {} } = data;
|
const { schema = {} } = data;
|
||||||
if (initialChildren && !schema.children) {
|
if (!schema.children && initialChildren && typeof initialChildren !== 'function') {
|
||||||
schema.children = initialChildren;
|
schema.children = initialChildren;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -550,7 +576,10 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
|
|||||||
schema,
|
schema,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else if (defaultProps || initialChildren) {
|
}
|
||||||
|
// FIXME! defaultProps for initial input
|
||||||
|
// initialChildren maybe a function
|
||||||
|
else if (defaultProps || initialChildren) {
|
||||||
const snippet = {
|
const snippet = {
|
||||||
screenshot: icon,
|
screenshot: icon,
|
||||||
label: title,
|
label: title,
|
||||||
@ -566,6 +595,11 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
|
|||||||
experimental.snippets = [snippet];
|
experimental.snippets = [snippet];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (initialChildren) {
|
||||||
|
experimental.initialChildren = typeof initialChildren === 'function' ? (field: Field) => {
|
||||||
|
return initialChildren.call(field, (field as any).props);
|
||||||
|
} : initialChildren;
|
||||||
|
}
|
||||||
if (view) {
|
if (view) {
|
||||||
experimental.view = view;
|
experimental.view = view;
|
||||||
}
|
}
|
||||||
@ -629,7 +663,12 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
|
|||||||
|
|
||||||
experimental.callbacks = callbacks;
|
experimental.callbacks = callbacks;
|
||||||
|
|
||||||
const props = upgradeConfigure(configure || []);
|
const initials: InitialItem[] = [];
|
||||||
|
const props = upgradeConfigure(configure || [], (item) => {
|
||||||
|
initials.push(item);
|
||||||
|
});
|
||||||
|
experimental.initials = initials;
|
||||||
|
|
||||||
const events = {};
|
const events = {};
|
||||||
const styles = {};
|
const styles = {};
|
||||||
meta.configure = { props, component, events, styles };
|
meta.configure = { props, component, events, styles };
|
||||||
|
|||||||
@ -148,7 +148,6 @@ async function loadAssets() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
await Promise.all(tasks);
|
await Promise.all(tasks);
|
||||||
|
|
||||||
// proccess snippets
|
// proccess snippets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,19 +23,18 @@ export function upgradeAssetsBundle(assets) {
|
|||||||
props: [],
|
props: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.push({
|
|
||||||
urls: item.urls,
|
|
||||||
library: item.library,
|
|
||||||
package: item.packageName,
|
|
||||||
version: item.version,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (item.prototypeConfigsUrl) {
|
if (item.prototypeConfigsUrl) {
|
||||||
xPrototypes.push({
|
xPrototypes.push({
|
||||||
package: item.packageName,
|
package: item.packageName,
|
||||||
urls: item.prototypeConfigsUrl,
|
urls: item.prototypeConfigsUrl,
|
||||||
});
|
});
|
||||||
} else if (item.components) {
|
} else if (item.components) {
|
||||||
|
packages.push({
|
||||||
|
urls: item.urls,
|
||||||
|
library: item.library,
|
||||||
|
package: item.packageName,
|
||||||
|
version: item.version,
|
||||||
|
});
|
||||||
const meta = item.components[0];
|
const meta = item.components[0];
|
||||||
metadata.componentName = meta.componentName;
|
metadata.componentName = meta.componentName;
|
||||||
metadata.configure = meta.configure;
|
metadata.configure = meta.configure;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { designer } from './editor';
|
import { designer } from './editor';
|
||||||
import { DragObjectType, isNode, ExportType } from '@ali/lowcode-designer';
|
import { DragObjectType, isNode, TransformStage } from '@ali/lowcode-designer';
|
||||||
|
|
||||||
const dragon = designer.dragon;
|
const dragon = designer.dragon;
|
||||||
const DragEngine = {
|
const DragEngine = {
|
||||||
@ -10,18 +10,10 @@ const DragEngine = {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (isNode(r)) {
|
if (isNode(r)) {
|
||||||
return {
|
|
||||||
type: DragObjectType.NodeData,
|
|
||||||
data: r.export(ExportType.ForSave),
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { globalContext } from '@ali/lowcode-globals';
|
import { globalContext, isPlainObject, isJSBlock } from '@ali/lowcode-globals';
|
||||||
import Editor from '@ali/lowcode-editor-core';
|
import Editor from '@ali/lowcode-editor-core';
|
||||||
import { Designer } from '@ali/lowcode-designer';
|
import { Designer, TransformStage } from '@ali/lowcode-designer';
|
||||||
import { registerSetters } from '@ali/lowcode-setters';
|
import { registerSetters } from '@ali/lowcode-setters';
|
||||||
import Outline from '@ali/lowcode-plugin-outline-pane';
|
import Outline from '@ali/lowcode-plugin-outline-pane';
|
||||||
import SettingsPane from '@ali/lowcode-plugin-settings-pane';
|
import SettingsPane from '@ali/lowcode-plugin-settings-pane';
|
||||||
@ -10,6 +10,7 @@ import { Skeleton } from './skeleton/skeleton';
|
|||||||
|
|
||||||
import Preview from '@ali/lowcode-plugin-sample-preview';
|
import Preview from '@ali/lowcode-plugin-sample-preview';
|
||||||
import SourceEditor from '@ali/lowcode-plugin-source-editor';
|
import SourceEditor from '@ali/lowcode-plugin-source-editor';
|
||||||
|
import { i18nReducer } from './i18n-reducer';
|
||||||
|
|
||||||
registerSetters();
|
registerSetters();
|
||||||
|
|
||||||
@ -19,9 +20,54 @@ globalContext.register(editor, Editor);
|
|||||||
export const skeleton = new Skeleton(editor);
|
export const skeleton = new Skeleton(editor);
|
||||||
editor.set(Skeleton, skeleton);
|
editor.set(Skeleton, skeleton);
|
||||||
|
|
||||||
export const designer = new Designer({ eventPipe: editor });
|
export const designer = new Designer({ editor: editor });
|
||||||
editor.set(Designer, designer);
|
editor.set(Designer, designer);
|
||||||
|
|
||||||
|
designer.addPropsReducer((props, node) => {
|
||||||
|
// run initials
|
||||||
|
const initials = node.componentMeta.getMetadata().experimental?.initials;
|
||||||
|
if (initials) {
|
||||||
|
const newProps: any = {};
|
||||||
|
initials.forEach((item) => {
|
||||||
|
// FIXME! this implements SettingTarget
|
||||||
|
const v = item.initial(node as any, props[item.name]);
|
||||||
|
if (v !== undefined) {
|
||||||
|
newProps[item.name] = v;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return newProps;
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
}, TransformStage.Init);
|
||||||
|
|
||||||
|
designer.addPropsReducer(i18nReducer, TransformStage.Render);
|
||||||
|
|
||||||
|
function upgradePropsReducer(props: any) {
|
||||||
|
if (!isPlainObject(props)) {
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
const newProps: any = {};
|
||||||
|
Object.entries<any>(props).forEach(([key, val]) => {
|
||||||
|
if (/^__slot__/.test(key) && val === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isJSBlock(val)) {
|
||||||
|
if (val.value.componentName === 'Slot') {
|
||||||
|
val = {
|
||||||
|
type: 'JSSlot',
|
||||||
|
title: (val.value.props as any)?.slotTitle,
|
||||||
|
value: val.value.children
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
val = val.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newProps[key] = val;
|
||||||
|
});
|
||||||
|
return newProps;
|
||||||
|
}
|
||||||
|
designer.addPropsReducer(upgradePropsReducer, TransformStage.Init);
|
||||||
|
|
||||||
skeleton.add({
|
skeleton.add({
|
||||||
area: 'mainArea',
|
area: 'mainArea',
|
||||||
name: 'designer',
|
name: 'designer',
|
||||||
@ -44,7 +90,6 @@ skeleton.add({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
skeleton.add({
|
skeleton.add({
|
||||||
area: 'topArea',
|
area: 'topArea',
|
||||||
type: 'Dock',
|
type: 'Dock',
|
||||||
|
|||||||
35
packages/vision-polyfill/src/i18n-reducer.ts
Normal file
35
packages/vision-polyfill/src/i18n-reducer.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
const I18nUtil = require('@ali/ve-i18n-util');
|
||||||
|
import Env from './env';
|
||||||
|
|
||||||
|
interface I18nObject {
|
||||||
|
type?: string;
|
||||||
|
use?: string;
|
||||||
|
key?: string;
|
||||||
|
[lang: string]: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function i18nReducer(obj?: any): any {
|
||||||
|
if (!obj) { return obj; }
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
return obj.map((item) => i18nReducer(item));
|
||||||
|
}
|
||||||
|
if (typeof obj === 'object') {
|
||||||
|
if (obj.type === 'i18n') {
|
||||||
|
// FIXME! use editor.get
|
||||||
|
let locale = Env.getLocale();
|
||||||
|
if (obj.key) {
|
||||||
|
return I18nUtil.get(obj.key, locale);
|
||||||
|
}
|
||||||
|
if (locale !== 'zh_CN' && locale !== 'zh_TW' && !obj[locale]) {
|
||||||
|
locale = 'en_US';
|
||||||
|
}
|
||||||
|
return obj[obj.use || locale] || obj.zh_CN;
|
||||||
|
}
|
||||||
|
const out: I18nObject = {};
|
||||||
|
Object.keys(obj).forEach((key) => {
|
||||||
|
out[key] = i18nReducer(obj[key]);
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
# FIXME! do not run build
|
# FIXME! do not run build
|
||||||
lerna exec --scope @ali/lowcode-react-renderer -- npm run build
|
lerna exec --scope @ali/lowcode-react-renderer -- npm run build
|
||||||
lerna exec --scope @ali/lowcode-demo -- npm start
|
lerna exec --scope @ali/lowcode-vision-polyfill -- npm start
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user