mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-02-28 04:40:32 +00:00
fix: plugin-designer
This commit is contained in:
parent
e49a02e37c
commit
2dfbcd4fff
@ -82,6 +82,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
||||
onMount={this.handleDesignerMount}
|
||||
className="lowcode-plugin-designer"
|
||||
eventPipe={editor}
|
||||
designer={editor.get('designer')}
|
||||
componentMetadatas={componentMetadatas}
|
||||
simulatorProps={{
|
||||
library,
|
||||
|
||||
@ -150,7 +150,8 @@ export class OutlineMain implements ISensor, IScrollBoard, IScrollable {
|
||||
if (at === '__IN_SETTINGS__') {
|
||||
setup();
|
||||
} else {
|
||||
editor.on('leftPanel.show', (key: string) => {
|
||||
editor.on('skeleton.panel.show', (key: string) => {
|
||||
console.info('show', key);
|
||||
if (key === at) {
|
||||
setup();
|
||||
if (this.master) {
|
||||
|
||||
@ -6,10 +6,10 @@ import TreeView from './tree';
|
||||
import './style.less';
|
||||
|
||||
@observer
|
||||
export default class OutlinePane extends Component<{ config?: any; editor: any; inSettings?: boolean }> {
|
||||
export default class OutlinePane extends Component<{ config: any; editor: any; inSettings?: boolean }> {
|
||||
private main = new OutlineMain(
|
||||
this.props.editor,
|
||||
this.props.config ? this.props.config.pluginKey : this.props.inSettings ? '__IN_SETTINGS__' : null,
|
||||
this.props.config.name || this.props.config.pluginKey,
|
||||
);
|
||||
|
||||
shouldComponentUpdate() {
|
||||
@ -21,6 +21,7 @@ export default class OutlinePane extends Component<{ config?: any; editor: any;
|
||||
}
|
||||
|
||||
render() {
|
||||
console.info(this.props);
|
||||
const tree = this.main.currentTree;
|
||||
|
||||
if (!tree) {
|
||||
|
||||
@ -138,7 +138,9 @@ class OutlinePaneEntry extends PureComponent<{ main: SettingsMain }> {
|
||||
if (!this.state.outlineInited) {
|
||||
return null;
|
||||
}
|
||||
return <OutlinePane editor={this.props.main.editor} inSettings />;
|
||||
return <OutlinePane editor={this.props.main.editor} config={{
|
||||
name: '__IN_SETTINGS__'
|
||||
}} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { camelCase, find, findIndex, upperFirst } from 'lodash';
|
||||
import { ComponentClass, ReactElement, ComponentType } from 'react';
|
||||
|
||||
import { UnknownComponent } from '../../ui/placeholders';
|
||||
import Trunk, { IComponentBundle } from '../bak/trunk';
|
||||
import Trunk, { IComponentBundle } from './trunk';
|
||||
import Prototype from './prototype';
|
||||
|
||||
function basename(name: string) {
|
||||
|
||||
@ -2,8 +2,8 @@ import lg from '@ali/vu-logger';
|
||||
import { EventEmitter } from 'events';
|
||||
import { ComponentClass } from 'react';
|
||||
|
||||
import Bundle from '../bundle/bundle';
|
||||
import Prototype, { setPackages } from '../bundle/prototype';
|
||||
import Bundle from './bundle';
|
||||
import Prototype, { setPackages } from './prototype';
|
||||
import Bus from '../bus';
|
||||
|
||||
interface IComponentInfo {
|
||||
220
packages/vision-polyfill/src/bundle/upgrade-metadata.ts
Normal file
220
packages/vision-polyfill/src/bundle/upgrade-metadata.ts
Normal file
@ -0,0 +1,220 @@
|
||||
export interface IPropConfig {
|
||||
/**
|
||||
* composite share the namespace
|
||||
* group just be tie up together
|
||||
*/
|
||||
type?: 'composite' | 'group';
|
||||
/**
|
||||
* when type is composite or group
|
||||
*/
|
||||
items?: IPropConfig[];
|
||||
/**
|
||||
* property name: the field key in props of schema
|
||||
*/
|
||||
name: string;
|
||||
title?: string;
|
||||
tip?: {
|
||||
title?: string;
|
||||
content?: string;
|
||||
url?: string;
|
||||
};
|
||||
initialValue?: any;
|
||||
defaultValue?: any;
|
||||
display?: DISPLAY_TYPE;
|
||||
fieldStyle?: DISPLAY_TYPE;
|
||||
setter?: ComponentClass | ISetterConfig[] | string | SetterGetter;
|
||||
/**
|
||||
* if a prop is dynamicProp, every-time while rendering setting field
|
||||
* - getValue() will not include value of getHotValue()
|
||||
* - getValue() will trigger accessor() to calculate a new value
|
||||
* this prop usually work out when we need to generate prop value
|
||||
* from node of current page
|
||||
*/
|
||||
isDynamicProp?: boolean;
|
||||
supportVariable?: boolean;
|
||||
/**
|
||||
* the prop should be collapsed while display value is accordion
|
||||
*/
|
||||
collapse?: boolean;
|
||||
/**
|
||||
* alias to collapse
|
||||
*/
|
||||
collapsed?: boolean;
|
||||
fieldCollapsed?: boolean;
|
||||
/**
|
||||
* if a prop is declared as disabled, it will not be saved into
|
||||
* schema
|
||||
*/
|
||||
disabled?: boolean | ReturnBooleanFunction;
|
||||
/**
|
||||
* will not export data to schema
|
||||
*/
|
||||
ignore?: boolean | ReturnBooleanFunction;
|
||||
/**
|
||||
* if a prop is declared as virtual, it will not be saved in
|
||||
* schema props, instead it will be saved into context field
|
||||
*/
|
||||
virtual?: boolean | ReturnBooleanFunction;
|
||||
hidden?: boolean | ReturnBooleanFunction;
|
||||
/**
|
||||
* if a prop is a lifeCycle function
|
||||
*/
|
||||
lifeCycle?: boolean;
|
||||
destroy?: () => any;
|
||||
initial?(this: Prop, value: any, initialValue: any): any;
|
||||
/**
|
||||
* when use getValue(), accessor shall be called as initializer
|
||||
*/
|
||||
accessor?(this: Prop): any;
|
||||
/**
|
||||
* when current prop value mutate, the mutator function shall be called
|
||||
*/
|
||||
mutator?(
|
||||
this: Prop,
|
||||
value: any,
|
||||
hotValue: any,
|
||||
preValue: any,
|
||||
preHotValue: any,
|
||||
): void;
|
||||
/**
|
||||
* other values' change will trigger sync function here
|
||||
*/
|
||||
sync?(this: Prop, value: any): void;
|
||||
/**
|
||||
* transform runtime data between view and setter
|
||||
* @param toHotValue hot value for the setter
|
||||
* @param toViewValue static value for the view
|
||||
*/
|
||||
transformer?(
|
||||
toHotValue: (data: any) => any,
|
||||
toViewValue: (str: string) => any,
|
||||
): any;
|
||||
/**
|
||||
* user click var to change current field to
|
||||
* variable setting field
|
||||
*/
|
||||
useVariableChange?(data: { isUseVariable: boolean }): any;
|
||||
}
|
||||
|
||||
|
||||
export interface SettingFieldConfig {
|
||||
type?: 'field';
|
||||
title?: string;
|
||||
name: string;
|
||||
setter: ComponentClass | ISetterConfig[] | string | SetterGetter;
|
||||
extraProps?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface SettingGroupConfig {
|
||||
type: 'group';
|
||||
title?: string;
|
||||
items: Array<SettingGroupConfig | SettingFieldConfig>;
|
||||
extraProps?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export declare interface IComponentPrototypeConfigure {
|
||||
packageName: string; // => npm.package
|
||||
uri?: string;
|
||||
/**
|
||||
* category display in the component pane
|
||||
* component will be hidden while the value is: null
|
||||
*/
|
||||
category: string; // => tags
|
||||
componentName: string;// =>
|
||||
docUrl?: string; // =>
|
||||
defaultProps?: any; // => ?
|
||||
/**
|
||||
* extra actions on the outline of current selected node
|
||||
* by default we have: remove / clone
|
||||
*/
|
||||
extraActions?: Component[]; // => configure.component.actions
|
||||
title?: string; // =>
|
||||
icon?: Component; // =>
|
||||
view: Component; // => ?
|
||||
initialChildren?: (props: any) => any[]; // => snippets
|
||||
|
||||
/**
|
||||
* Props configurations of node
|
||||
*/
|
||||
configure: IPropConfig[]; // => configure.props
|
||||
snippets?: ISnippet[]; // => snippets
|
||||
transducers?: any; // => ?
|
||||
reducers?: any; // ?
|
||||
/**
|
||||
* Selector expression rectangle of a node, it is usually a querySelector string
|
||||
* @example '.classname > div'
|
||||
*/
|
||||
rectSelector?: string; // => configure.component.rectSelector
|
||||
context?: { // => ?
|
||||
[contextInfoName: string]: any;
|
||||
};
|
||||
|
||||
isContainer?: boolean; // => configure.component.isContainer
|
||||
isInline?: boolean; // x
|
||||
isModal?: boolean; // => configure.component.isModal
|
||||
isFloating?: boolean; // => configure.component.isFloating
|
||||
descriptor?: string; // => configure.component.descriptor
|
||||
|
||||
/**
|
||||
* enable slot-mode
|
||||
* @see https://yuque.antfin-inc.com/legao/solutions/atgtdl
|
||||
*/
|
||||
hasSlot?: boolean; // => ?
|
||||
|
||||
// alias to canDragging
|
||||
canDraging?: boolean; // => ?
|
||||
canDragging?: boolean; // => ?
|
||||
|
||||
canOperating?: boolean; // => disabledActions
|
||||
canHovering?: boolean; // x
|
||||
canSelecting?: boolean;
|
||||
canUseCondition?: boolean; // x
|
||||
canLoop?: boolean; // x
|
||||
canContain?: (dragment: Node) => boolean; // => nestingRule
|
||||
|
||||
canDropTo?: ((container: Node) => boolean) | string | string[]; // => nestingRule
|
||||
canDropto?: (container: Node) => boolean; // => nestingRule
|
||||
|
||||
canDropIn?: ((dragment: Node) => boolean) | string | string[]; // => nestingRule
|
||||
canDroping?: (dragment: Node) => boolean; // => nestingRule
|
||||
|
||||
didDropOut?: (container: any | Prototype, dragment: any) => boolean; // => hooks
|
||||
didDropIn?: (container: any | Prototype, dragment: any) => boolean; // => hooks
|
||||
|
||||
// => ?
|
||||
canResizing?:
|
||||
| ((dragment: Node, triggerDirection: string) => boolean)
|
||||
| boolean;
|
||||
onResizeStart?: (
|
||||
e: MouseEvent,
|
||||
triggerDirection: string,
|
||||
dragment: Node,
|
||||
) => void;
|
||||
onResize?: (
|
||||
e: MouseEvent,
|
||||
triggerDirection: string,
|
||||
dragment: Node,
|
||||
moveX: number,
|
||||
moveY: number,
|
||||
) => void;
|
||||
onResizeEnd?: (
|
||||
e: MouseEvent,
|
||||
triggerDirection: string,
|
||||
dragment: Node,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* when sub-node of the current node changed
|
||||
* including: sub-node insert / remove
|
||||
*/
|
||||
subtreeModified?(this: Node): any; // => ?
|
||||
}
|
||||
|
||||
export interface IComponentPrototypeExtraConfigs {
|
||||
autoGenerated?: boolean;
|
||||
}
|
||||
@ -11,6 +11,10 @@ export const editor = new Editor();
|
||||
|
||||
export const skeleton = new Skeleton(editor);
|
||||
|
||||
export const designer = new Designer();
|
||||
|
||||
editor.set('designer', designer)
|
||||
|
||||
skeleton.mainArea.add({
|
||||
name: 'designer',
|
||||
type: 'Widget',
|
||||
@ -31,7 +35,7 @@ skeleton.leftArea.add({
|
||||
},
|
||||
content: OutlinePane,
|
||||
panelProps: {
|
||||
area: 'leftFloatArea'
|
||||
area: 'leftFixedArea'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Selection, DocumentModel, Node } from '@ali/lowcode-designer';
|
||||
import editor from './editor';
|
||||
import { editor, designer } from './editor';
|
||||
|
||||
let currentSelection: Selection;
|
||||
// let currentDocument: DocumentModel;
|
||||
@ -27,7 +27,7 @@ editor.once('designer.ready', () => {
|
||||
export default {
|
||||
select: (node: Node) => {
|
||||
if (!node) {
|
||||
return currentSelection.clear();
|
||||
return designer.currentSelection?.clear();
|
||||
}
|
||||
currentSelection.select(node.id);
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { skeleton } from './editor';
|
||||
import { skeleton, editor } from './editor';
|
||||
import { ReactElement } from 'react';
|
||||
import { IWidgetBaseConfig } from './skeleton/types';
|
||||
|
||||
@ -151,11 +151,27 @@ const dockPane = Object.assign(skeleton.leftArea, {
|
||||
/**
|
||||
* compatible *VE.dockPane.onDockShow*
|
||||
*/
|
||||
onDockShow() {},
|
||||
onDockShow(fn: (dock: any) => void): () => void {
|
||||
const f = (_: any, dock: any) => {
|
||||
fn(dock);
|
||||
};
|
||||
editor.on('skeleton.panel-dock.show', f);
|
||||
return () => {
|
||||
editor.removeListener('skeleton.panel-dock.show', f);
|
||||
};
|
||||
},
|
||||
/**
|
||||
* compatible *VE.dockPane.onDockHide*
|
||||
*/
|
||||
onDockHide() {},
|
||||
onDockHide(fn: (dock: any) => void): () => void {
|
||||
const f = (_: any, dock: any) => {
|
||||
fn(dock);
|
||||
};
|
||||
editor.on('skeleton.panel-dock.hide', f);
|
||||
return () => {
|
||||
editor.removeListener('skeleton.panel-dock.hide', f);
|
||||
};
|
||||
},
|
||||
/**
|
||||
* compatible *VE.dockPane.setFixed*
|
||||
*/
|
||||
|
||||
@ -45,4 +45,8 @@ export default class Area<C extends IWidgetBaseConfig = any, T extends IWidget =
|
||||
hide() {
|
||||
this.setVisible(false);
|
||||
}
|
||||
|
||||
show() {
|
||||
this.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { Component, Fragment } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { observer } from '@ali/recore';
|
||||
import { observer } from '@ali/lowcode-globals';
|
||||
import Area from './area';
|
||||
import Panel from './panel';
|
||||
import { PanelWrapper } from './widget-views';
|
||||
|
||||
@observer
|
||||
export default class BottomArea extends Component<{ area: Area<any, Panel> }> {
|
||||
@ -31,7 +30,7 @@ class Contents extends Component<{ area: Area<any, Panel> }> {
|
||||
const { area } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
{area.container.items.map((item) => <PanelWrapper key={item.id} panel={item} />)}
|
||||
{area.container.items.map((item) => item.content)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { ReactNode, createElement } from 'react';
|
||||
import { uniqueId, createContent, obx } from '@ali/lowcode-globals';
|
||||
import { DockConfig } from "./types";
|
||||
import { Skeleton } from './skeleton';
|
||||
import { DockView } from './widget-views';
|
||||
import { DockView, WidgetView } from './widget-views';
|
||||
import { IWidget } from './widget';
|
||||
|
||||
/**
|
||||
@ -19,30 +19,34 @@ export default class Dock implements IWidget {
|
||||
return this._visible;
|
||||
}
|
||||
|
||||
get content(): ReactNode {
|
||||
return createElement(WidgetView, {
|
||||
widget: this,
|
||||
key: this.id,
|
||||
});
|
||||
}
|
||||
|
||||
private inited: boolean = false;
|
||||
private _content: ReactNode;
|
||||
get content() {
|
||||
private _body: ReactNode;
|
||||
get body() {
|
||||
if (this.inited) {
|
||||
return this._content;
|
||||
return this._body;
|
||||
}
|
||||
this.inited = true;
|
||||
|
||||
const { props, content, contentProps } = this.config;
|
||||
|
||||
if (content) {
|
||||
this._content = createContent(content, {
|
||||
this._body = createContent(content, {
|
||||
...contentProps,
|
||||
config: this.content,
|
||||
editor: this.skeleton.editor,
|
||||
key: this.id,
|
||||
});
|
||||
} else {
|
||||
this._content = createElement(DockView, {
|
||||
...props,
|
||||
key: this.id,
|
||||
});
|
||||
this._body = createElement(DockView, props);
|
||||
}
|
||||
|
||||
return this._content;
|
||||
return this._body;
|
||||
}
|
||||
|
||||
constructor(readonly skeleton: Skeleton, private config: DockConfig) {
|
||||
const { props = {}, name } = config;
|
||||
this.name = name;
|
||||
@ -75,4 +79,8 @@ export default class Dock implements IWidget {
|
||||
show() {
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setVisible(!this._visible);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ import { Button } from '@alifd/next';
|
||||
import Area from './area';
|
||||
import { PanelConfig } from './types';
|
||||
import Panel from './panel';
|
||||
import { PanelWrapper } from './widget-views';
|
||||
|
||||
@observer
|
||||
export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> {
|
||||
@ -41,9 +40,7 @@ class Contents extends Component<{ area: Area<PanelConfig, Panel> }> {
|
||||
const { area } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
{area.container.items.map((panel) => (
|
||||
<PanelWrapper key={panel.id} panel={panel} />
|
||||
))}
|
||||
{area.container.items.map((panel) => panel.content)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ import { observer } from '@ali/lowcode-globals';
|
||||
import { Button } from '@alifd/next';
|
||||
import Area from './area';
|
||||
import Panel from './panel';
|
||||
import { PanelWrapper } from './widget-views';
|
||||
|
||||
@observer
|
||||
export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> {
|
||||
@ -42,9 +41,7 @@ class Contents extends Component<{ area: Area<any, Panel> }> {
|
||||
const { area } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
{area.container.items.map((panel) => (
|
||||
<PanelWrapper key={panel.id} panel={panel} />
|
||||
))}
|
||||
{area.container.items.map((panel) => panel.content)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { Component } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { observer } from '@ali/recore';
|
||||
import { observer } from '@ali/lowcode-globals';
|
||||
import Area from './area';
|
||||
import Panel, { isPanel } from './panel';
|
||||
import { PanelWrapper } from './widget-views';
|
||||
import Panel from './panel';
|
||||
import Widget from './widget';
|
||||
|
||||
@observer
|
||||
@ -15,13 +14,7 @@ export default class MainArea extends Component<{ area: Area<any, Panel | Widget
|
||||
const { area } = this.props;
|
||||
return (
|
||||
<div className={classNames('lc-main-area')}>
|
||||
{area.container.items.map((item) => {
|
||||
// todo?
|
||||
if (isPanel(item)) {
|
||||
return <PanelWrapper key={item.id} panel={item} />;
|
||||
}
|
||||
return item.content;
|
||||
})}
|
||||
{area.container.items.map((item) => item.content)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { createElement, ReactNode } from 'react';
|
||||
import { Skeleton } from './skeleton';
|
||||
import { PanelDockConfig } from './types';
|
||||
import Panel from './panel';
|
||||
import { PanelDockView } from './widget-views';
|
||||
import { PanelDockView, WidgetView } from './widget-views';
|
||||
import { IWidget } from './widget';
|
||||
|
||||
export default class PanelDock implements IWidget {
|
||||
@ -13,21 +13,32 @@ export default class PanelDock implements IWidget {
|
||||
readonly align?: string;
|
||||
|
||||
private inited: boolean = false;
|
||||
private _content: ReactNode;
|
||||
get content() {
|
||||
private _body: ReactNode;
|
||||
get body() {
|
||||
if (this.inited) {
|
||||
return this._content;
|
||||
return this._body;
|
||||
}
|
||||
this.inited = true;
|
||||
const { props } = this.config;
|
||||
|
||||
this._content = createElement(PanelDockView, {
|
||||
this._body = createElement(PanelDockView, {
|
||||
...props,
|
||||
key: this.id,
|
||||
dock: this,
|
||||
});
|
||||
|
||||
return this._content;
|
||||
return this._body;
|
||||
}
|
||||
|
||||
get content(): ReactNode {
|
||||
return createElement(WidgetView, {
|
||||
widget: this,
|
||||
key: this.id,
|
||||
});
|
||||
}
|
||||
|
||||
@obx.ref private _visible: boolean = true;
|
||||
get visible() {
|
||||
return this._visible;
|
||||
}
|
||||
|
||||
@computed get actived(): boolean {
|
||||
@ -52,12 +63,36 @@ export default class PanelDock implements IWidget {
|
||||
props: panelProps || {},
|
||||
contentProps,
|
||||
content,
|
||||
// FIXME! dirty fixed
|
||||
area: panelProps?.area || 'leftFloatArea'
|
||||
}) as Panel;
|
||||
}
|
||||
}
|
||||
|
||||
setVisible(flag: boolean) {
|
||||
if (flag === this._visible) {
|
||||
return;
|
||||
}
|
||||
if (flag) {
|
||||
this._visible = true;
|
||||
} else if (this.inited) {
|
||||
this._visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setVisible(false);
|
||||
}
|
||||
|
||||
show() {
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setVisible(!this._visible);
|
||||
}
|
||||
|
||||
togglePanel() {
|
||||
this.panel?.toggle();
|
||||
}
|
||||
|
||||
@ -69,11 +104,11 @@ export default class PanelDock implements IWidget {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
hide() {
|
||||
hidePanel() {
|
||||
this.panel?.setActive(false);
|
||||
}
|
||||
|
||||
show() {
|
||||
showPanel() {
|
||||
this.panel?.setActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import {createElement, ReactNode } from 'react';
|
||||
import { createElement, ReactNode } from 'react';
|
||||
import { obx, uniqueId, createContent, TitleContent } from '@ali/lowcode-globals';
|
||||
import WidgetContainer from './widget-container';
|
||||
import { PanelConfig, HelpTipConfig } from './types';
|
||||
import { PanelView, TabsPanelView } from './widget-views';
|
||||
import { TitledPanelView, TabsPanelView, PanelView } from './widget-views';
|
||||
import { Skeleton } from './skeleton';
|
||||
import { composeTitle } from './utils';
|
||||
import { IWidget } from './widget';
|
||||
@ -16,32 +16,13 @@ export default class Panel implements IWidget {
|
||||
get actived(): boolean {
|
||||
return this._actived;
|
||||
}
|
||||
|
||||
get visible(): boolean {
|
||||
if (this.parent?.visible) {
|
||||
return this._actived;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
setActive(flag: boolean) {
|
||||
if (flag === this._actived) {
|
||||
// TODO: 如果移动到另外一个 container,会有问题
|
||||
return;
|
||||
}
|
||||
if (flag) {
|
||||
if (!this.inited) {
|
||||
this.initBody();
|
||||
}
|
||||
this._actived = true;
|
||||
this.parent?.active(this);
|
||||
} else if (this.inited) {
|
||||
this._actived = false;
|
||||
this.parent?.unactive(this);
|
||||
}
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setActive(!this._actived);
|
||||
}
|
||||
|
||||
readonly isPanel = true;
|
||||
|
||||
@ -52,7 +33,13 @@ export default class Panel implements IWidget {
|
||||
}
|
||||
|
||||
get content() {
|
||||
return this.plain ? this.body : createElement(PanelView, { panel: this });
|
||||
if (this.plain) {
|
||||
return createElement(PanelView, {
|
||||
panel: this,
|
||||
key: this.id,
|
||||
});
|
||||
}
|
||||
return createElement(TitledPanelView, { panel: this, key: this.id });
|
||||
}
|
||||
|
||||
readonly title: TitleContent;
|
||||
@ -71,13 +58,19 @@ export default class Panel implements IWidget {
|
||||
this.plain = hideTitleBar || !title;
|
||||
this.help = help;
|
||||
if (Array.isArray(content)) {
|
||||
this.container = this.skeleton.createContainer(name, (item) => {
|
||||
if (isPanel(item)) {
|
||||
return item;
|
||||
}
|
||||
return this.skeleton.createPanel(item);
|
||||
}, true, () => this.visible, true);
|
||||
content.forEach(item => this.add(item));
|
||||
this.container = this.skeleton.createContainer(
|
||||
name,
|
||||
(item) => {
|
||||
if (isPanel(item)) {
|
||||
return item;
|
||||
}
|
||||
return this.skeleton.createPanel(item);
|
||||
},
|
||||
true,
|
||||
() => this.visible,
|
||||
true,
|
||||
);
|
||||
content.forEach((item) => this.add(item));
|
||||
}
|
||||
// todo: process shortcut
|
||||
}
|
||||
@ -90,18 +83,18 @@ export default class Panel implements IWidget {
|
||||
if (this.container) {
|
||||
this._body = createElement(TabsPanelView, {
|
||||
container: this.container,
|
||||
key: this.id,
|
||||
});
|
||||
} else {
|
||||
const { content, contentProps } = this.config;
|
||||
this._body = createContent(content, {
|
||||
...contentProps,
|
||||
editor: this.skeleton.editor,
|
||||
config: this.config,
|
||||
panel: this,
|
||||
key: this.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setParent(parent: WidgetContainer) {
|
||||
if (parent === this.parent) {
|
||||
return;
|
||||
@ -136,6 +129,27 @@ export default class Panel implements IWidget {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
setActive(flag: boolean) {
|
||||
if (flag === this._actived) {
|
||||
// TODO: 如果移动到另外一个 container,会有问题
|
||||
return;
|
||||
}
|
||||
if (flag) {
|
||||
if (!this.inited) {
|
||||
this.initBody();
|
||||
}
|
||||
this._actived = true;
|
||||
this.parent?.active(this);
|
||||
} else if (this.inited) {
|
||||
this._actived = false;
|
||||
this.parent?.unactive(this);
|
||||
}
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setActive(!this._actived);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setActive(false);
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { Component, Fragment } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { observer } from '@ali/recore';
|
||||
import { observer } from '@ali/lowcode-globals';
|
||||
import Area from './area';
|
||||
import Panel from './panel';
|
||||
import { PanelWrapper } from './widget-views';
|
||||
|
||||
@observer
|
||||
export default class RightArea extends Component<{ area: Area<any, Panel> }> {
|
||||
@ -29,7 +28,7 @@ class Contents extends Component<{ area: Area<any, Panel> }> {
|
||||
const { area } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
{area.container.items.map((item) => <PanelWrapper key={item.id} panel={item} />)}
|
||||
{area.container.items.map((item) => item.content)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import PanelDock from './panel-dock';
|
||||
import { composeTitle } from './utils';
|
||||
import WidgetContainer from './widget-container';
|
||||
import Panel from './panel';
|
||||
import Widget from './widget';
|
||||
import { IWidget } from './widget';
|
||||
|
||||
export function DockView({ title, icon, description, size, className, onClick }: DockProps) {
|
||||
return (
|
||||
@ -22,6 +22,25 @@ export function DockView({ title, icon, description, size, className, onClick }:
|
||||
|
||||
@observer
|
||||
export class PanelDockView extends Component<DockProps & { dock: PanelDock }> {
|
||||
componentDidMount() {
|
||||
this.checkActived();
|
||||
}
|
||||
componentDidUpdate() {
|
||||
this.checkActived();
|
||||
}
|
||||
private lastActived: boolean = false;
|
||||
checkActived() {
|
||||
const { dock } = this.props;
|
||||
if (dock.actived !== this.lastActived) {
|
||||
this.lastActived = dock.actived;
|
||||
if (this.lastActived) {
|
||||
dock.skeleton.editor.emit('skeleton.panel-dock.active', dock.name, dock);
|
||||
} else {
|
||||
dock.skeleton.editor.emit('skeleton.panel-dock.unactive', dock.name, dock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dock, className, onClick, ...props } = this.props;
|
||||
return DockView({
|
||||
@ -31,7 +50,7 @@ export class PanelDockView extends Component<DockProps & { dock: PanelDock }> {
|
||||
}),
|
||||
onClick: () => {
|
||||
onClick && onClick();
|
||||
dock.toggle();
|
||||
dock.togglePanel();
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -41,16 +60,82 @@ export class DialogDockView extends Component {
|
||||
|
||||
}
|
||||
|
||||
@observer
|
||||
export class TitledPanelView extends Component<{ panel: Panel }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
}
|
||||
componentDidUpdate() {
|
||||
this.checkVisible();
|
||||
}
|
||||
private lastVisible: boolean = false;
|
||||
checkVisible() {
|
||||
const { panel } = this.props;
|
||||
const currentVisible = panel.inited && panel.visible;
|
||||
if (currentVisible !== this.lastVisible) {
|
||||
this.lastVisible = currentVisible;
|
||||
if (this.lastVisible) {
|
||||
panel.skeleton.editor.emit('skeleton.panel.show', panel.name, panel);
|
||||
} else {
|
||||
panel.skeleton.editor.emit('skeleton.panel.hide', panel.name, panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { panel } = this.props;
|
||||
if (!panel.inited) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className={classNames('lc-titled-panel', {
|
||||
hidden: !panel.visible,
|
||||
})}>
|
||||
<PanelTitle panel={panel} />
|
||||
<div className="lc-pane-body">{panel.body}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class PanelView extends Component<{ panel: Panel }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
}
|
||||
componentDidUpdate() {
|
||||
this.checkVisible();
|
||||
}
|
||||
private lastVisible: boolean = false;
|
||||
checkVisible() {
|
||||
const { panel } = this.props;
|
||||
const currentVisible = panel.inited && panel.visible;
|
||||
if (currentVisible !== this.lastVisible) {
|
||||
this.lastVisible = currentVisible;
|
||||
if (this.lastVisible) {
|
||||
panel.skeleton.editor.emit('skeleton.panel.show', panel.name, panel);
|
||||
} else {
|
||||
panel.skeleton.editor.emit('skeleton.panel.hide', panel.name, panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { panel } = this.props;
|
||||
if (!panel.inited) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className="lc-panel">
|
||||
<PanelTitle panel={panel} />
|
||||
<div className="lc-pane-body">{panel.body}</div>
|
||||
<div
|
||||
className={classNames('lc-panel', {
|
||||
hidden: !panel.visible,
|
||||
})}
|
||||
>
|
||||
{panel.body}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -64,7 +149,7 @@ export class TabsPanelView extends Component<{ container: WidgetContainer<Panel>
|
||||
const contents: ReactElement[] = [];
|
||||
container.items.forEach((item: any) => {
|
||||
titles.push(<PanelTitle key={item.id} panel={item} className="lc-tab-title" />);
|
||||
contents.push(<PanelWrapper key={item.id} panel={item} />);
|
||||
contents.push(<PanelView key={item.id} panel={item} />);
|
||||
});
|
||||
|
||||
return (
|
||||
@ -113,26 +198,29 @@ class PanelTitle extends Component<{ panel: Panel; className?: string }> {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class PanelWrapper extends Component<{ panel: Panel }> {
|
||||
render() {
|
||||
const { panel } = this.props;
|
||||
if (!panel.inited) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={classNames('lc-panel-wrapper', {
|
||||
hidden: !panel.actived,
|
||||
})}
|
||||
>
|
||||
{panel.body}
|
||||
</div>
|
||||
);
|
||||
export class WidgetView extends Component<{ widget: IWidget }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
}
|
||||
componentDidUpdate() {
|
||||
this.checkVisible();
|
||||
}
|
||||
private lastVisible: boolean = false;
|
||||
checkVisible() {
|
||||
const { widget } = this.props;
|
||||
const currentVisible = widget.visible;
|
||||
if (currentVisible !== this.lastVisible) {
|
||||
this.lastVisible = currentVisible;
|
||||
if (this.lastVisible) {
|
||||
widget.skeleton.editor.emit('skeleton.widget.show', widget.name, widget);
|
||||
} else {
|
||||
widget.skeleton.editor.emit('skeleton.widget.hide', widget.name, widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class WidgetWrapper extends Component<{ widget: Widget }> {
|
||||
render() {
|
||||
const { widget } = this.props;
|
||||
if (!widget.visible) {
|
||||
|
||||
@ -2,18 +2,22 @@ import { ReactNode, createElement } from 'react';
|
||||
import { createContent, uniqueId, obx } from '@ali/lowcode-globals';
|
||||
import { WidgetConfig } from './types';
|
||||
import { Skeleton } from './skeleton';
|
||||
import { WidgetWrapper } from './widget-views';
|
||||
import { WidgetView } from './widget-views';
|
||||
|
||||
export interface IWidget {
|
||||
readonly name: string;
|
||||
readonly content: any;
|
||||
readonly content: ReactNode;
|
||||
readonly align?: string;
|
||||
readonly isWidget: true;
|
||||
readonly visible: boolean;
|
||||
readonly body: ReactNode;
|
||||
readonly skeleton: Skeleton;
|
||||
|
||||
getName(): string;
|
||||
getContent(): any;
|
||||
show(): void;
|
||||
hide(): void;
|
||||
toggle(): void;
|
||||
}
|
||||
|
||||
export default class Widget implements IWidget {
|
||||
@ -42,8 +46,8 @@ export default class Widget implements IWidget {
|
||||
return this._body;
|
||||
}
|
||||
|
||||
get content() {
|
||||
return createElement(WidgetWrapper, {
|
||||
get content(): ReactNode {
|
||||
return createElement(WidgetView, {
|
||||
widget: this,
|
||||
key: this.id,
|
||||
});
|
||||
|
||||
@ -45,7 +45,7 @@ body {
|
||||
}
|
||||
|
||||
|
||||
.my-pane {
|
||||
.lc-titled-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
@ -104,7 +104,7 @@ body {
|
||||
top: var(--pane-title-height);
|
||||
}
|
||||
}
|
||||
.lc-panel-wrapper {
|
||||
.lc-panel {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
@ -173,8 +173,6 @@ body {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.lc-workbench {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
@ -197,7 +195,8 @@ body {
|
||||
bottom: 0;
|
||||
width: var(--dock-pane-width);
|
||||
left: calc(var(--left-area-width) + 1px);
|
||||
z-index: 20;
|
||||
background-color: var(--color-pane-background);
|
||||
z-index: 820;
|
||||
display: none;
|
||||
&.lc-area-visible {
|
||||
display: block;
|
||||
|
||||
@ -69,3 +69,12 @@ export {
|
||||
Panes,
|
||||
modules,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
console.log(
|
||||
`%cLowcodeEngine %cv${VERSION}`,
|
||||
"color:#000;font-weight:bold;",
|
||||
"color:green;font-weight:bold;"
|
||||
);
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user