mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-04-20 12:28:08 +00:00
feat: merge live mode
This commit is contained in:
parent
dc950336b5
commit
92c303967a
@ -15,8 +15,14 @@ export class BemTools extends Component<{ host: BuiltinSimulatorHost }> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const host = this.props.host;
|
// yiyi
|
||||||
|
// live 模式选中,画布会不会有相关交互
|
||||||
|
const { host } = this.props;
|
||||||
|
const { designMode } = host;
|
||||||
const { scrollX, scrollY, scale } = host.viewport;
|
const { scrollX, scrollY, scale } = host.viewport;
|
||||||
|
if (designMode === 'live') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="lc-bem-tools" style={{ transform: `translate(${-scrollX * scale}px,${-scrollY * scale}px)` }}>
|
<div className="lc-bem-tools" style={{ transform: `translate(${-scrollX * scale}px,${-scrollY * scale}px)` }}>
|
||||||
<BorderDetecting key="hovering" host={host} />
|
<BorderDetecting key="hovering" host={host} />
|
||||||
|
|||||||
@ -288,7 +288,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupDragAndClick() {
|
setupDragAndClick() {
|
||||||
const designer = this.designer;
|
const documentModel = this.project.currentDocument;
|
||||||
|
if (!documentModel) return;
|
||||||
|
const selection = documentModel.selection;
|
||||||
|
const designer = documentModel.designer;
|
||||||
const doc = this.contentDocument!;
|
const doc = this.contentDocument!;
|
||||||
|
|
||||||
// TODO: think of lock when edit a node
|
// TODO: think of lock when edit a node
|
||||||
@ -299,10 +302,17 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
// fix for popups close logic
|
// fix for popups close logic
|
||||||
document.dispatchEvent(new Event('mousedown'));
|
document.dispatchEvent(new Event('mousedown'));
|
||||||
const documentModel = this.project.currentDocument;
|
const documentModel = this.project.currentDocument;
|
||||||
if (this.liveEditing.editing || !documentModel) {
|
let isMulti = false;
|
||||||
|
if (this.designMode === 'design') {
|
||||||
|
isMulti = downEvent.metaKey || downEvent.ctrlKey;
|
||||||
|
} else if (!downEvent.metaKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const selection = documentModel.selection;
|
|
||||||
|
if (this.liveEditing.editing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const selection = documentModel?.selection;
|
||||||
// stop response document focus event
|
// stop response document focus event
|
||||||
downEvent.stopPropagation();
|
downEvent.stopPropagation();
|
||||||
downEvent.preventDefault();
|
downEvent.preventDefault();
|
||||||
@ -312,23 +322,29 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
|
|
||||||
|
|
||||||
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
|
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
|
||||||
const node = nodeInst?.node || documentModel.rootNode;
|
const node = nodeInst?.node || documentModel?.rootNode;
|
||||||
if (!node?.isValidComponent()) {
|
if (!node?.isValidComponent()) {
|
||||||
// 对于未注册组件直接返回
|
// 对于未注册组件直接返回
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMulti = downEvent.metaKey || downEvent.ctrlKey;
|
|
||||||
const isLeftButton = downEvent.which === 1 || downEvent.button === 0;
|
const isLeftButton = downEvent.which === 1 || downEvent.button === 0;
|
||||||
const checkSelect = (e: MouseEvent) => {
|
const checkSelect = (e: MouseEvent) => {
|
||||||
doc.removeEventListener('mouseup', checkSelect, true);
|
doc.removeEventListener('mouseup', checkSelect, true);
|
||||||
|
// 鼠标是否移动
|
||||||
if (!isShaken(downEvent, e)) {
|
if (!isShaken(downEvent, e)) {
|
||||||
const id = node.id;
|
let id = node.id;
|
||||||
designer.activeTracker.track({ node, instance: nodeInst?.instance });
|
designer.activeTracker.track({ node, instance: nodeInst?.instance });
|
||||||
if (isMulti && !isRootNode(node) && selection.has(id)) {
|
if (isMulti && !isRootNode(node) && selection?.has(id)) {
|
||||||
selection.remove(id);
|
selection.remove(id);
|
||||||
} else {
|
} else {
|
||||||
selection.select(id);
|
if (node.isPage() && node.getChildren()?.notEmpty()) {
|
||||||
|
const firstChildId = node
|
||||||
|
.getChildren()
|
||||||
|
?.get(0)
|
||||||
|
?.getId();
|
||||||
|
if (firstChildId) id = firstChildId;
|
||||||
|
}
|
||||||
|
selection?.select(id);
|
||||||
|
|
||||||
// dirty code should refector
|
// dirty code should refector
|
||||||
const editor = this.designer?.editor;
|
const editor = this.designer?.editor;
|
||||||
@ -349,15 +365,15 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
let ignoreUpSelected = false;
|
let ignoreUpSelected = false;
|
||||||
if (isMulti) {
|
if (isMulti) {
|
||||||
// multi select mode, directily add
|
// multi select mode, directily add
|
||||||
if (!selection.has(node.id)) {
|
if (!selection?.has(node.id)) {
|
||||||
designer.activeTracker.track({ node, instance: nodeInst?.instance });
|
designer.activeTracker.track({ node, instance: nodeInst?.instance });
|
||||||
selection.add(node.id);
|
selection?.add(node.id);
|
||||||
ignoreUpSelected = true;
|
ignoreUpSelected = true;
|
||||||
}
|
}
|
||||||
selection.remove(documentModel.rootNode.id);
|
selection?.remove(documentModel.rootNode.id);
|
||||||
// 获得顶层 nodes
|
// 获得顶层 nodes
|
||||||
nodes = selection.getTopNodes();
|
nodes = selection?.getTopNodes();
|
||||||
} else if (selection.containsNode(node, true)) {
|
} else if (selection?.containsNode(node, true)) {
|
||||||
nodes = selection.getTopNodes();
|
nodes = selection.getTopNodes();
|
||||||
} else {
|
} else {
|
||||||
// will clear current selection & select dragment in dragstart
|
// will clear current selection & select dragment in dragstart
|
||||||
@ -412,7 +428,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
const doc = this.contentDocument!;
|
const doc = this.contentDocument!;
|
||||||
const detecting = this.designer.detecting;
|
const detecting = this.designer.detecting;
|
||||||
const hover = (e: MouseEvent) => {
|
const hover = (e: MouseEvent) => {
|
||||||
if (!detecting.enable) {
|
if (!detecting.enable || this.designMode !== 'design') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const nodeInst = this.getNodeInstanceFromElement(e.target as Element);
|
const nodeInst = this.getNodeInstanceFromElement(e.target as Element);
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export class DesignerView extends Component<DesignerProps & {
|
|||||||
if (onMount) {
|
if (onMount) {
|
||||||
onMount(this.designer);
|
onMount(this.designer);
|
||||||
}
|
}
|
||||||
clipboard.injectCopyPaster(document)
|
clipboard.injectCopyPaster(document);
|
||||||
this.designer.postEvent('mount', this.designer);
|
this.designer.postEvent('mount', this.designer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,15 @@ export class Project {
|
|||||||
return this.documents.find((doc) => doc.actived);
|
return this.documents.find((doc) => doc.actived);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@obx private _config: any = {};
|
||||||
|
@computed get config(): any {
|
||||||
|
// TODO: parse layout Component
|
||||||
|
return this._config;
|
||||||
|
}
|
||||||
|
set config(value: any) {
|
||||||
|
this._config = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取项目整体 schema
|
* 获取项目整体 schema
|
||||||
*/
|
*/
|
||||||
@ -55,6 +64,7 @@ export class Project {
|
|||||||
componentsTree: [],
|
componentsTree: [],
|
||||||
...schema,
|
...schema,
|
||||||
};
|
};
|
||||||
|
this.config = schema?.config;
|
||||||
|
|
||||||
if (autoOpen) {
|
if (autoOpen) {
|
||||||
if (autoOpen === true) {
|
if (autoOpen === true) {
|
||||||
@ -91,9 +101,14 @@ export class Project {
|
|||||||
| 'i18n'
|
| 'i18n'
|
||||||
| 'css'
|
| 'css'
|
||||||
| 'dataSource'
|
| 'dataSource'
|
||||||
|
| 'config'
|
||||||
| string,
|
| string,
|
||||||
value: any,
|
value: any,
|
||||||
): void {}
|
): void {
|
||||||
|
if (key === 'config') {
|
||||||
|
this.config = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分字段设置储存数据
|
* 分字段设置储存数据
|
||||||
@ -108,8 +123,13 @@ export class Project {
|
|||||||
| 'i18n'
|
| 'i18n'
|
||||||
| 'css'
|
| 'css'
|
||||||
| 'dataSource'
|
| 'dataSource'
|
||||||
|
| 'config'
|
||||||
| string,
|
| string,
|
||||||
): any {}
|
): any {
|
||||||
|
if (key === 'config') {
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private documentsMap = new Map<string, DocumentModel>();
|
private documentsMap = new Map<string, DocumentModel>();
|
||||||
|
|||||||
@ -20,6 +20,7 @@ globalContext.register(editor, Editor);
|
|||||||
export const skeleton = new Skeleton(editor);
|
export const skeleton = new Skeleton(editor);
|
||||||
editor.set(Skeleton, skeleton);
|
editor.set(Skeleton, skeleton);
|
||||||
editor.set('skeleton', skeleton);
|
editor.set('skeleton', skeleton);
|
||||||
|
editor.set('designMode', 'live');
|
||||||
|
|
||||||
export const designer = new Designer({ editor: editor });
|
export const designer = new Designer({ editor: editor });
|
||||||
editor.set(Designer, designer);
|
editor.set(Designer, designer);
|
||||||
@ -279,6 +280,9 @@ skeleton.add({
|
|||||||
name: 'settingsPane',
|
name: 'settingsPane',
|
||||||
type: 'Panel',
|
type: 'Panel',
|
||||||
content: SettingsPrimaryPane,
|
content: SettingsPrimaryPane,
|
||||||
|
props: {
|
||||||
|
ignoreRoot: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
skeleton.add({
|
skeleton.add({
|
||||||
area: 'leftArea',
|
area: 'leftArea',
|
||||||
|
|||||||
@ -52,6 +52,15 @@ const pages = Object.assign(project, {
|
|||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
componentsMap: [],
|
componentsMap: [],
|
||||||
componentsTree,
|
componentsTree,
|
||||||
|
config: {
|
||||||
|
layout: {
|
||||||
|
componentName: 'MiniappTabNav',
|
||||||
|
props: {
|
||||||
|
logo: '',
|
||||||
|
name: '测试网站',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}, true);
|
}, true);
|
||||||
},
|
},
|
||||||
addPage(data: OldPageData | RootSchema) {
|
addPage(data: OldPageData | RootSchema) {
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
export class Project {
|
import { designer } from './editor';
|
||||||
private schema: any;
|
|
||||||
|
|
||||||
constructor() {
|
const { project } = designer;
|
||||||
this.schema = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
getSchema() {
|
Object.assign(project, {
|
||||||
return this.schema;
|
getSchema(): any {
|
||||||
}
|
return this.schema || {};
|
||||||
|
},
|
||||||
|
|
||||||
setSchema(schema: any) {
|
setSchema(schema: any) {
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
}
|
},
|
||||||
}
|
});
|
||||||
|
|
||||||
export default new Project();
|
export default project;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { SettingsPane } from './settings-pane';
|
|||||||
import { createIcon } from '@ali/lowcode-utils';
|
import { createIcon } from '@ali/lowcode-utils';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
|
export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any }> {
|
||||||
private main = new SettingsMain(this.props.editor);
|
private main = new SettingsMain(this.props.editor);
|
||||||
|
|
||||||
@obx.ref private _activeKey?: any;
|
@obx.ref private _activeKey?: any;
|
||||||
@ -22,6 +22,8 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
|
|||||||
|
|
||||||
renderBreadcrumb() {
|
renderBreadcrumb() {
|
||||||
const { settings } = this.main;
|
const { settings } = this.main;
|
||||||
|
const { config } = this.props;
|
||||||
|
const shouldIgnoreRoot = config.props?.ignoreRoot;
|
||||||
if (!settings) {
|
if (!settings) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -43,6 +45,10 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor }> {
|
|||||||
let l = 3;
|
let l = 3;
|
||||||
while (l-- > 0 && node) {
|
while (l-- > 0 && node) {
|
||||||
const _node = node;
|
const _node = node;
|
||||||
|
if (shouldIgnoreRoot && node.isRoot()) {
|
||||||
|
node = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const props =
|
const props =
|
||||||
l === 2
|
l === 2
|
||||||
? {}
|
? {}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ interface DesignerPluginState {
|
|||||||
extraEnvironment?: any[] | null;
|
extraEnvironment?: any[] | null;
|
||||||
renderEnv?: string;
|
renderEnv?: string;
|
||||||
device?: string;
|
device?: string;
|
||||||
|
designMode?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DesignerPlugin extends PureComponent<PluginProps, DesignerPluginState> {
|
export default class DesignerPlugin extends PureComponent<PluginProps, DesignerPluginState> {
|
||||||
@ -24,6 +25,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
|||||||
extraEnvironment: null,
|
extraEnvironment: null,
|
||||||
renderEnv: 'default',
|
renderEnv: 'default',
|
||||||
device: 'default',
|
device: 'default',
|
||||||
|
designMode: 'live',
|
||||||
};
|
};
|
||||||
|
|
||||||
private _mounted = true;
|
private _mounted = true;
|
||||||
@ -39,6 +41,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
|||||||
const assets = await editor.onceGot('assets');
|
const assets = await editor.onceGot('assets');
|
||||||
const renderEnv = await editor.get('renderEnv');
|
const renderEnv = await editor.get('renderEnv');
|
||||||
const device = await editor.get('device');
|
const device = await editor.get('device');
|
||||||
|
const designMode = await editor.get('designMode');
|
||||||
if (!this._mounted) {
|
if (!this._mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -49,6 +52,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
|||||||
extraEnvironment,
|
extraEnvironment,
|
||||||
renderEnv,
|
renderEnv,
|
||||||
device,
|
device,
|
||||||
|
designMode,
|
||||||
};
|
};
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -71,7 +75,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
|||||||
|
|
||||||
render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
const { editor } = this.props;
|
const { editor } = this.props;
|
||||||
const { componentMetadatas, library, extraEnvironment, renderEnv, device } = this.state;
|
const { componentMetadatas, library, extraEnvironment, renderEnv, device, designMode } = this.state;
|
||||||
|
|
||||||
if (!library || !componentMetadatas) {
|
if (!library || !componentMetadatas) {
|
||||||
// TODO: use a Loading
|
// TODO: use a Loading
|
||||||
@ -90,6 +94,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
|||||||
extraEnvironment,
|
extraEnvironment,
|
||||||
renderEnv,
|
renderEnv,
|
||||||
device,
|
device,
|
||||||
|
designMode,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -90,8 +90,13 @@ class Layout extends Component<{ rendererContainer: SimulatorRendererContainer }
|
|||||||
const layout = rendererContainer.layout;
|
const layout = rendererContainer.layout;
|
||||||
|
|
||||||
if (layout) {
|
if (layout) {
|
||||||
const { Component, props } = layout;
|
const { Component, props, componentName } = layout;
|
||||||
return <Component props={props}>{children}</Component>;
|
if (Component) {
|
||||||
|
return <Component props={props}>{children}</Component>;
|
||||||
|
}
|
||||||
|
if (componentName) {
|
||||||
|
return createElement(rendererContainer.getComponent(componentName), {}, [children]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Fragment>{children}</Fragment>;
|
return <Fragment>{children}</Fragment>;
|
||||||
|
|||||||
19
packages/types/src/app-config.ts
Normal file
19
packages/types/src/app-config.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
export interface AppConfig {
|
||||||
|
sdkVersion?: string;
|
||||||
|
historyMode?: string;
|
||||||
|
targetRootID?: string;
|
||||||
|
layout?: Layout;
|
||||||
|
theme?: Theme;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Theme {
|
||||||
|
package: string;
|
||||||
|
version: string;
|
||||||
|
primary: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Layout {
|
||||||
|
componentName?: string;
|
||||||
|
props?: Record<string, any>;
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ import { CompositeValue, JSExpression, CompositeObject, JSONObject } from './val
|
|||||||
import { DataSource } from './data-source';
|
import { DataSource } from './data-source';
|
||||||
import { I18nMap } from './i18n';
|
import { I18nMap } from './i18n';
|
||||||
import { UtilsMap } from './utils';
|
import { UtilsMap } from './utils';
|
||||||
|
import { AppConfig } from './app-config';
|
||||||
|
|
||||||
export interface NodeSchema {
|
export interface NodeSchema {
|
||||||
id?: string;
|
id?: string;
|
||||||
@ -83,6 +84,7 @@ export interface ProjectSchema {
|
|||||||
constants?: JSONObject;
|
constants?: JSONObject;
|
||||||
css?: string;
|
css?: string;
|
||||||
dataSource?: DataSource;
|
dataSource?: DataSource;
|
||||||
|
config?: AppConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNodeSchema(data: any): data is NodeSchema {
|
export function isNodeSchema(data: any): data is NodeSchema {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user