diff --git a/packages/plugin-designer/src/index.tsx b/packages/plugin-designer/src/index.tsx index c1513ff08..216a42e46 100644 --- a/packages/plugin-designer/src/index.tsx +++ b/packages/plugin-designer/src/index.tsx @@ -82,6 +82,7 @@ export default class DesignerPlugin extends PureComponent { + editor.on('skeleton.panel.show', (key: string) => { + console.info('show', key); if (key === at) { setup(); if (this.master) { diff --git a/packages/plugin-outline-pane/src/views/pane.tsx b/packages/plugin-outline-pane/src/views/pane.tsx index 36f141c95..d18e1cfef 100644 --- a/packages/plugin-outline-pane/src/views/pane.tsx +++ b/packages/plugin-outline-pane/src/views/pane.tsx @@ -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) { diff --git a/packages/plugin-settings-pane/src/index.tsx b/packages/plugin-settings-pane/src/index.tsx index 2ade7e562..93e435ae3 100644 --- a/packages/plugin-settings-pane/src/index.tsx +++ b/packages/plugin-settings-pane/src/index.tsx @@ -138,7 +138,9 @@ class OutlinePaneEntry extends PureComponent<{ main: SettingsMain }> { if (!this.state.outlineInited) { return null; } - return ; + return ; } } diff --git a/packages/vision-polyfill/src/bundle/bundle.ts b/packages/vision-polyfill/src/bundle/bundle.ts index fd2db6332..df8c0c291 100644 --- a/packages/vision-polyfill/src/bundle/bundle.ts +++ b/packages/vision-polyfill/src/bundle/bundle.ts @@ -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) { diff --git a/packages/vision-polyfill/src/bak/trunk.ts b/packages/vision-polyfill/src/bundle/trunk.ts similarity index 98% rename from packages/vision-polyfill/src/bak/trunk.ts rename to packages/vision-polyfill/src/bundle/trunk.ts index 8771e21c2..ae8f669d7 100644 --- a/packages/vision-polyfill/src/bak/trunk.ts +++ b/packages/vision-polyfill/src/bundle/trunk.ts @@ -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 { diff --git a/packages/vision-polyfill/src/bundle/upgrade-metadata.ts b/packages/vision-polyfill/src/bundle/upgrade-metadata.ts new file mode 100644 index 000000000..4828f31b3 --- /dev/null +++ b/packages/vision-polyfill/src/bundle/upgrade-metadata.ts @@ -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; + 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; +} diff --git a/packages/vision-polyfill/src/editor.ts b/packages/vision-polyfill/src/editor.ts index 46dccc510..06e3ab17e 100644 --- a/packages/vision-polyfill/src/editor.ts +++ b/packages/vision-polyfill/src/editor.ts @@ -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' } }); diff --git a/packages/vision-polyfill/src/exchange.ts b/packages/vision-polyfill/src/exchange.ts index 812bf38a6..1800f1239 100644 --- a/packages/vision-polyfill/src/exchange.ts +++ b/packages/vision-polyfill/src/exchange.ts @@ -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); }, diff --git a/packages/vision-polyfill/src/panes.ts b/packages/vision-polyfill/src/panes.ts index 6ccadccf8..268bc2d75 100644 --- a/packages/vision-polyfill/src/panes.ts +++ b/packages/vision-polyfill/src/panes.ts @@ -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* */ diff --git a/packages/vision-polyfill/src/skeleton/area.ts b/packages/vision-polyfill/src/skeleton/area.ts index bf68b9fa8..e40aaf9a6 100644 --- a/packages/vision-polyfill/src/skeleton/area.ts +++ b/packages/vision-polyfill/src/skeleton/area.ts @@ -45,4 +45,8 @@ export default class Area }> { @@ -31,7 +30,7 @@ class Contents extends Component<{ area: Area }> { const { area } = this.props; return ( - {area.container.items.map((item) => )} + {area.container.items.map((item) => item.content)} ); } diff --git a/packages/vision-polyfill/src/skeleton/dock.ts b/packages/vision-polyfill/src/skeleton/dock.ts index 20952c766..9a2de3ca1 100644 --- a/packages/vision-polyfill/src/skeleton/dock.ts +++ b/packages/vision-polyfill/src/skeleton/dock.ts @@ -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); + } } diff --git a/packages/vision-polyfill/src/skeleton/left-fixed-pane.tsx b/packages/vision-polyfill/src/skeleton/left-fixed-pane.tsx index cf2579f8b..4a5727ec1 100644 --- a/packages/vision-polyfill/src/skeleton/left-fixed-pane.tsx +++ b/packages/vision-polyfill/src/skeleton/left-fixed-pane.tsx @@ -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 }> { @@ -41,9 +40,7 @@ class Contents extends Component<{ area: Area }> { const { area } = this.props; return ( - {area.container.items.map((panel) => ( - - ))} + {area.container.items.map((panel) => panel.content)} ); } diff --git a/packages/vision-polyfill/src/skeleton/left-float-pane.tsx b/packages/vision-polyfill/src/skeleton/left-float-pane.tsx index 4b551b143..3a51d6ac9 100644 --- a/packages/vision-polyfill/src/skeleton/left-float-pane.tsx +++ b/packages/vision-polyfill/src/skeleton/left-float-pane.tsx @@ -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 }> { @@ -42,9 +41,7 @@ class Contents extends Component<{ area: Area }> { const { area } = this.props; return ( - {area.container.items.map((panel) => ( - - ))} + {area.container.items.map((panel) => panel.content)} ); } diff --git a/packages/vision-polyfill/src/skeleton/main-area.tsx b/packages/vision-polyfill/src/skeleton/main-area.tsx index 58eee2842..45242805e 100644 --- a/packages/vision-polyfill/src/skeleton/main-area.tsx +++ b/packages/vision-polyfill/src/skeleton/main-area.tsx @@ -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 - {area.container.items.map((item) => { - // todo? - if (isPanel(item)) { - return ; - } - return item.content; - })} + {area.container.items.map((item) => item.content)} ); } diff --git a/packages/vision-polyfill/src/skeleton/panel-dock.ts b/packages/vision-polyfill/src/skeleton/panel-dock.ts index 5877c864f..f7d786ec3 100644 --- a/packages/vision-polyfill/src/skeleton/panel-dock.ts +++ b/packages/vision-polyfill/src/skeleton/panel-dock.ts @@ -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); } } diff --git a/packages/vision-polyfill/src/skeleton/panel.ts b/packages/vision-polyfill/src/skeleton/panel.ts index bf34b2e45..caa5100fe 100644 --- a/packages/vision-polyfill/src/skeleton/panel.ts +++ b/packages/vision-polyfill/src/skeleton/panel.ts @@ -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); } diff --git a/packages/vision-polyfill/src/skeleton/right-area.tsx b/packages/vision-polyfill/src/skeleton/right-area.tsx index b756b2868..89daa1ea2 100644 --- a/packages/vision-polyfill/src/skeleton/right-area.tsx +++ b/packages/vision-polyfill/src/skeleton/right-area.tsx @@ -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 }> { @@ -29,7 +28,7 @@ class Contents extends Component<{ area: Area }> { const { area } = this.props; return ( - {area.container.items.map((item) => )} + {area.container.items.map((item) => item.content)} ); } diff --git a/packages/vision-polyfill/src/skeleton/widget-views.tsx b/packages/vision-polyfill/src/skeleton/widget-views.tsx index af5d2364c..e896e2a1a 100644 --- a/packages/vision-polyfill/src/skeleton/widget-views.tsx +++ b/packages/vision-polyfill/src/skeleton/widget-views.tsx @@ -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 { + 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 { }), 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 ( +
+ +
{panel.body}
+
+ ); + } +} + +@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 ( -
- -
{panel.body}
+
+ {panel.body}
); } @@ -64,7 +149,7 @@ export class TabsPanelView extends Component<{ container: WidgetContainer const contents: ReactElement[] = []; container.items.forEach((item: any) => { titles.push(); - contents.push(); + contents.push(); }); 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 ( -
- {panel.body} -
- ); +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) { diff --git a/packages/vision-polyfill/src/skeleton/widget.ts b/packages/vision-polyfill/src/skeleton/widget.ts index f28aba2d9..e15a0872b 100644 --- a/packages/vision-polyfill/src/skeleton/widget.ts +++ b/packages/vision-polyfill/src/skeleton/widget.ts @@ -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, }); diff --git a/packages/vision-polyfill/src/skeleton/workbench.less b/packages/vision-polyfill/src/skeleton/workbench.less index 3ac20e84f..9fc2d4da1 100644 --- a/packages/vision-polyfill/src/skeleton/workbench.less +++ b/packages/vision-polyfill/src/skeleton/workbench.less @@ -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; diff --git a/packages/vision-polyfill/src/vision.ts b/packages/vision-polyfill/src/vision.ts index 2eeea6cb0..9bc6e408b 100644 --- a/packages/vision-polyfill/src/vision.ts +++ b/packages/vision-polyfill/src/vision.ts @@ -69,3 +69,12 @@ export { Panes, modules, }; + + +/* +console.log( + `%cLowcodeEngine %cv${VERSION}`, + "color:#000;font-weight:bold;", + "color:green;font-weight:bold;" +); +*/