feat: merge live mode

This commit is contained in:
wanying.jwy 2020-08-16 15:28:25 +08:00
parent dc950336b5
commit 92c303967a
12 changed files with 124 additions and 34 deletions

View File

@ -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} />

View File

@ -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);

View File

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

View File

@ -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>();

View File

@ -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',

View File

@ -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) {

View File

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

View File

@ -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
? {} ? {}

View File

@ -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,
}} }}
/> />
); );

View File

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

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

View File

@ -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 {