joint bind dialog

This commit is contained in:
kangwei 2020-04-22 16:39:44 +08:00
parent a21490a379
commit 741552e5f7
12 changed files with 186 additions and 111 deletions

View File

@ -1,16 +1,126 @@
// @ts-ignore // @ts-ignore
import { createElement } from 'react';
import { Button } from '@alifd/next';
import Engine, { Panes } from '@ali/visualengine'; import Engine, { Panes } from '@ali/visualengine';
import getTrunkPane from '@ali/ve-trunk-pane'; import getTrunkPane from '@ali/ve-trunk-pane';
import Preview from '@ali/lowcode-plugin-sample-preview';
import SourceEditor from '@ali/lowcode-plugin-source-editor';
import EventBindDialog from '@ali/lowcode-plugin-event-bind-dialog';
import loadUrls from './loader'; import loadUrls from './loader';
import { upgradeAssetsBundle } from './upgrade-assets'; import { upgradeAssetsBundle } from './upgrade-assets';
const { editor } = Engine; const { editor, skeleton } = Engine;
// demo
skeleton.add({
name: 'eventBindDialog',
type: 'Widget',
content: EventBindDialog,
});
skeleton.add({
name: 'sourceEditor',
type: 'PanelDock',
props: {
align: 'top',
icon: 'code',
description: '组件库',
},
panelProps: {
width: 500
// area: 'leftFixedArea'
},
content: SourceEditor,
});
skeleton.add({
area: 'leftArea',
name: 'icon1',
type: 'Dock',
props: {
align: 'bottom',
icon: 'set',
description: '设置',
},
});
skeleton.add({
area: 'leftArea',
name: 'icon2',
type: 'Dock',
props: {
align: 'bottom',
icon: 'help',
description: '帮助',
},
});
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'preview',
props: {
align: 'right',
},
content: Preview,
});
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'publish',
props: {
align: 'right',
},
content: createElement(Button, {
size: 'small',
type: 'secondary',
children: '发布',
}),
});
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'save',
props: {
align: 'right',
},
content: createElement(Button, {
size: 'small',
type: 'primary',
children: '保存',
}),
});
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'preview4',
props: {
align: 'center',
},
content: createElement('img', {
src: 'https://img.alicdn.com/tfs/TB1WW.VC.z1gK0jSZLeXXb9kVXa-486-64.png',
style: {
height: 32,
},
}),
});
skeleton.add({
area: 'topArea',
type: 'Dock',
name: 'preview1',
props: {
align: 'left',
},
content: createElement('img', {
src: 'https://img.alicdn.com/tfs/TB1zqBfDlr0gK0jSZFnXXbRRXXa-440-64.png',
style: {
height: 32,
},
}),
});
initTrunkPane(); initTrunkPane();
Engine.init(); Engine.init();
load(); load();
Engine.Env.setEnv('RE_VERSION', "5.0.1"); Engine.Env.setEnv('RE_VERSION', '5.0.1');
async function load() { async function load() {
await loadAssets(); await loadAssets();

View File

@ -2,16 +2,11 @@ import { globalContext } 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 } from '@ali/lowcode-designer';
import { registerSetters } from '@ali/lowcode-setters'; import { registerSetters } from '@ali/lowcode-setters';
import Outline, { Pane } 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';
import DesignerPlugin from '@ali/lowcode-plugin-designer'; import DesignerPlugin from '@ali/lowcode-plugin-designer';
import { Skeleton } from './skeleton/skeleton'; import { Skeleton } from './skeleton/skeleton';
// demo
import Preview from '@ali/lowcode-plugin-sample-preview';
import { createElement } from 'react';
import { Button } from '@alifd/next';
registerSetters(); registerSetters();
export const editor = new Editor(); export const editor = new Editor();
@ -23,101 +18,26 @@ editor.set(Skeleton, skeleton);
export const designer = new Designer({ eventPipe: editor }); export const designer = new Designer({ eventPipe: editor });
editor.set(Designer, designer); editor.set(Designer, designer);
skeleton.mainArea.add({ skeleton.add({
area: 'mainArea',
name: 'designer', name: 'designer',
type: 'Widget', type: 'Widget',
content: DesignerPlugin, content: DesignerPlugin,
}); });
skeleton.rightArea.add({ skeleton.add({
area: 'rightArea',
name: 'settingsPane', name: 'settingsPane',
type: 'Panel', type: 'Panel',
content: SettingsPane, content: SettingsPane,
}); });
skeleton.leftArea.add({ skeleton.add({
area: 'leftArea',
name: 'outlinePane', name: 'outlinePane',
type: 'PanelDock', type: 'PanelDock',
...Outline, content: Outline,
panelProps: { panelProps: {
area: 'leftFixedArea', area: 'leftFixedArea',
}, },
}); });
// demo
skeleton.leftArea.add({
name: 'icon1',
type: 'Dock',
props: {
align: 'bottom',
icon: 'set',
description: '设置',
}
});
skeleton.leftArea.add({
name: 'icon2',
type: 'Dock',
props: {
align: 'bottom',
icon: 'help',
description: '帮助',
}
});
skeleton.topArea.add({
type: "Dock",
name: 'preview',
props: {
align: "right",
},
content: Preview,
});
skeleton.topArea.add({
type: "Dock",
name: 'publish',
props: {
align: "right",
},
content: createElement(Button, {
size: 'small',
type: 'secondary',
children: '发布'
}),
});
skeleton.topArea.add({
type: "Dock",
name: 'save',
props: {
align: "right",
},
content: createElement(Button, {
size: 'small',
type: 'primary',
children: '保存'
}),
});
skeleton.topArea.add({
type: "Dock",
name: 'preview4',
props: {
align: "center",
},
content: createElement('img', {
src: "https://img.alicdn.com/tfs/TB1WW.VC.z1gK0jSZLeXXb9kVXa-486-64.png",
style: {
height: 32
}
}),
});
skeleton.topArea.add({
type: "Dock",
name: 'preview1',
props: {
align: "left",
},
content: createElement('img', {
src: "https://img.alicdn.com/tfs/TB1zqBfDlr0gK0jSZFnXXbRRXXa-440-64.png",
style: {
height: 32
}
}),
});

View File

@ -14,6 +14,13 @@ export default class Area<C extends IWidgetBaseConfig = any, T extends IWidget =
return this._visible; return this._visible;
} }
get current() {
if (this.exclusive) {
return this.container.current;
}
return null;
}
readonly container: WidgetContainer<T, C>; readonly container: WidgetContainer<T, C>;
constructor(readonly skeleton: Skeleton, readonly name: string, handle: (item: T | C) => T, private exclusive?: boolean, defaultSetCurrent: boolean = false) { constructor(readonly skeleton: Skeleton, readonly name: string, handle: (item: T | C) => T, private exclusive?: boolean, defaultSetCurrent: boolean = false) {
this.container = skeleton.createContainer(name, handle, exclusive, () => this.visible, defaultSetCurrent); this.container = skeleton.createContainer(name, handle, exclusive, () => this.visible, defaultSetCurrent);

View File

@ -38,7 +38,7 @@ export default class Dock implements IWidget {
if (content) { if (content) {
this._body = createContent(content, { this._body = createContent(content, {
...contentProps, ...contentProps,
config: this.content, config: this.config,
editor: this.skeleton.editor, editor: this.skeleton.editor,
}); });
} else { } else {
@ -47,7 +47,7 @@ export default class Dock implements IWidget {
return this._body; return this._body;
} }
constructor(readonly skeleton: Skeleton, private config: DockConfig) { constructor(readonly skeleton: Skeleton, readonly config: DockConfig) {
const { props = {}, name } = config; const { props = {}, name } = config;
this.name = name; this.name = name;
this.align = props.align; this.align = props.align;

View File

@ -31,11 +31,16 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }>
// focusin set focus (push|replace) // focusin set focus (push|replace)
// focusout remove focus // focusout remove focus
// onEsc // onEsc
const width = area.current?.config.props?.width;
const style = width ? {
width
} : undefined;
return ( return (
<div <div
className={classNames('lc-left-float-pane', { className={classNames('lc-left-float-pane', {
'lc-area-visible': area.visible, 'lc-area-visible': area.visible,
})} })}
style={style}
> >
<Button <Button
text text

View File

@ -52,7 +52,7 @@ export default class PanelDock implements IWidget {
return this._panel || this.skeleton.getPanel(this.panelName); return this._panel || this.skeleton.getPanel(this.panelName);
} }
constructor(readonly skeleton: Skeleton, private config: PanelDockConfig) { constructor(readonly skeleton: Skeleton, readonly config: PanelDockConfig) {
const { content, contentProps, panelProps, name, props } = config; const { content, contentProps, panelProps, name, props } = config;
this.name = name; this.name = name;
this.id = uniqueId(`dock:${name}$`); this.id = uniqueId(`dock:${name}$`);
@ -62,13 +62,13 @@ export default class PanelDock implements IWidget {
type: "Panel", type: "Panel",
name: this.panelName, name: this.panelName,
props: { props: {
// FIXME! give default title for panel
// title: props ? composeTitle(props?.title, props?.icon, props?.description, true) : '', // title: props ? composeTitle(props?.title, props?.icon, props?.description, true) : '',
...panelProps, ...panelProps,
}, },
contentProps, contentProps,
content, content,
// FIXME! dirty fixed area: panelProps?.area
area: panelProps?.area || 'leftFloatArea'
}) as Panel; }) as Panel;
} }
} }

View File

@ -49,7 +49,7 @@ export default class Panel implements IWidget {
private container?: WidgetContainer<Panel, PanelConfig>; private container?: WidgetContainer<Panel, PanelConfig>;
private parent?: WidgetContainer; private parent?: WidgetContainer;
constructor(readonly skeleton: Skeleton, private config: PanelConfig) { constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) {
const { name, content, props = {} } = config; const { name, content, props = {} } = config;
const { hideTitleBar, title, icon, description, help, shortcut } = props; const { hideTitleBar, title, icon, description, help, shortcut } = props;
this.name = name; this.name = name;

View File

@ -193,10 +193,13 @@ export class Skeleton {
if (isWidget(config)) { if (isWidget(config)) {
return config; return config;
} }
config = this.parseConfig(config);
if (isDockConfig(config)) { if (isDockConfig(config)) {
if (isPanelDockConfig(config)) { if (isPanelDockConfig(config)) {
return new PanelDock(this, config); return new PanelDock(this, config);
} }
// others...
return new Dock(this, config); return new Dock(this, config);
} }
@ -207,6 +210,7 @@ export class Skeleton {
} }
createPanel(config: PanelConfig) { createPanel(config: PanelConfig) {
config = this.parseConfig(config);
const panel = new Panel(this, config); const panel = new Panel(this, config);
this.panels.set(panel.name, panel); this.panels.set(panel.name, panel);
return panel; return panel;
@ -228,7 +232,10 @@ export class Skeleton {
return container; return container;
} }
add(config: IWidgetBaseConfig & { area: string }) { private parseConfig(config: IWidgetBaseConfig): any {
if ((config as any).parsed) {
return config;
}
const { content, ...restConfig } = config; const { content, ...restConfig } = config;
if (content) { if (content) {
if (isPlainObject(content) && !isValidElement(content)) { if (isPlainObject(content) && !isValidElement(content)) {
@ -246,33 +253,52 @@ export class Skeleton {
restConfig.content = content; restConfig.content = content;
} }
} }
const { area } = restConfig; restConfig.pluginKey = restConfig.name;
restConfig.parsed = true;
return restConfig;
}
add(config: IWidgetBaseConfig & { area?: string }, extraConfig?: object) {
const parsedConfig: any = {
...this.parseConfig(config),
...extraConfig,
};
let { area } = parsedConfig;
if (!area) {
if (parsedConfig.type === 'Panel') {
area = 'leftFloatArea'
} else if (parsedConfig.type === 'Widget') {
area = 'mainArea';
} else {
area = 'leftArea';
}
}
switch (area) { switch (area) {
case 'leftArea': case 'leftArea':
case 'left': case 'left':
return this.leftArea.add(restConfig as any); return this.leftArea.add(parsedConfig);
case 'rightArea': case 'rightArea':
case 'right': case 'right':
return this.rightArea.add(restConfig as any); return this.rightArea.add(parsedConfig);
case 'topArea': case 'topArea':
case 'top': case 'top':
return this.topArea.add(restConfig as any); return this.topArea.add(parsedConfig);
case 'toolbar': case 'toolbar':
return this.toolbar.add(restConfig as any); return this.toolbar.add(parsedConfig);
case 'mainArea': case 'mainArea':
case 'main': case 'main':
case 'center': case 'center':
case 'centerArea': case 'centerArea':
return this.mainArea.add(restConfig as any); return this.mainArea.add(parsedConfig);
case 'bottomArea': case 'bottomArea':
case 'bottom': case 'bottom':
return this.bottomArea.add(restConfig as any); return this.bottomArea.add(parsedConfig);
case 'leftFixedArea': case 'leftFixedArea':
return this.leftFixedArea.add(restConfig as any); return this.leftFixedArea.add(parsedConfig);
case 'leftFloatArea': case 'leftFloatArea':
return this.leftFloatArea.add(restConfig as any); return this.leftFloatArea.add(parsedConfig);
case 'stages': case 'stages':
return this.stages.add(restConfig as any); return this.stages.add(parsedConfig);
} }
} }
} }

View File

@ -1,7 +1,7 @@
import { IconType, TitleContent, I18nData, isI18nData } from '@ali/lowcode-globals'; import { IconType, TitleContent, isI18nData, TipContent } from '@ali/lowcode-globals';
import { isValidElement } from 'react'; import { isValidElement } from 'react';
export function composeTitle(title?: TitleContent, icon?: IconType, tip?: string | I18nData, tipAsTitle?: boolean) { export function composeTitle(title?: TitleContent, icon?: IconType, tip?: TipContent, tipAsTitle?: boolean) {
if (!title) { if (!title) {
title = {}; title = {};
if (!icon || tipAsTitle) { if (!icon || tipAsTitle) {

View File

@ -120,8 +120,12 @@ export class PanelView extends Component<{ panel: Panel }> {
this.lastVisible = currentVisible; this.lastVisible = currentVisible;
if (this.lastVisible) { if (this.lastVisible) {
panel.skeleton.postEvent(SkeletonEvents.PANEL_SHOW, panel.name, panel); panel.skeleton.postEvent(SkeletonEvents.PANEL_SHOW, panel.name, panel);
// FIXME! remove this line
panel.skeleton.postEvent('leftPanel.show' as any, panel.name, panel);
} else { } else {
panel.skeleton.postEvent(SkeletonEvents.PANEL_HIDE, panel.name, panel); panel.skeleton.postEvent(SkeletonEvents.PANEL_HIDE, panel.name, panel);
// FIXME! remove this line
panel.skeleton.postEvent('leftPanel.hide' as any, panel.name, panel);
} }
} }
} }

View File

@ -1,6 +1,6 @@
import { ReactNode, createElement } from 'react'; import { ReactNode, createElement } from 'react';
import { createContent, uniqueId, obx } from '@ali/lowcode-globals'; import { createContent, uniqueId, obx } from '@ali/lowcode-globals';
import { WidgetConfig } from './types'; import { WidgetConfig, IWidgetBaseConfig } from './types';
import { Skeleton } from './skeleton'; import { Skeleton } from './skeleton';
import { WidgetView } from './widget-views'; import { WidgetView } from './widget-views';
@ -12,6 +12,7 @@ export interface IWidget {
readonly visible: boolean; readonly visible: boolean;
readonly body: ReactNode; readonly body: ReactNode;
readonly skeleton: Skeleton; readonly skeleton: Skeleton;
readonly config: IWidgetBaseConfig;
getName(): string; getName(): string;
getContent(): any; getContent(): any;
@ -41,6 +42,7 @@ export default class Widget implements IWidget {
const { content, contentProps } = this.config; const { content, contentProps } = this.config;
this._body = createContent(content, { this._body = createContent(content, {
...contentProps, ...contentProps,
config: this.config,
editor: this.skeleton.editor, editor: this.skeleton.editor,
}); });
return this._body; return this._body;
@ -53,7 +55,7 @@ export default class Widget implements IWidget {
}); });
} }
constructor(readonly skeleton: Skeleton, private config: WidgetConfig) { constructor(readonly skeleton: Skeleton, readonly config: WidgetConfig) {
const { props = {}, name } = config; const { props = {}, name } = config;
this.name = name; this.name = name;
this.align = props.align; this.align = props.align;

View File

@ -61,6 +61,7 @@ const context = new VisualEngineContext();
const VisualEngine = { const VisualEngine = {
editor, editor,
skeleton,
/** /**
* VE.Popup * VE.Popup
*/ */