跳到主要内容
版本:Next

自定义工作台(Workbench)

Molecule 默认的 Workbench UI 是一个 VSCode 的克隆版本。但是我们在实际的开发场景中,往往不能满足我们的需求。

除了内置的一些原子 Components 以外,Molecule 同时提供了基本的 Workbench、SideBar、Editor、ActivityBar、MenuBar、Panel、StatusBar 等核心UI 部件,以便开发者根据自己的需求重新组装自己的 Workbench

tip

本文内容中的所有代码,都以 Quick Start 中的 molecule-demo 项目为基础演示。

自定义 Workbench 示例

Custom Workbench

Molecule 默认的是 VSCode 布局的 Workbench。在上图示例中,我们将 MenuBar 水平置于了顶部的位置,在编辑器的右侧,我们又自定义了一个右边栏(RightSideBar)

info

目前 MenuBar 置顶布局功能已内置,我们会在未来的版本中,将右边栏(RightSideBar)也作为 Molecule 的内置功能。

重组 Workbench

首先我们打开 Molecule 源码仓库,找到 src/workbench 目录,拷贝 workbench.tsx 文件到项目的 views 或其他目录下,将其重命名为 myWorkbench.tsx 文件:

<div id={ID_APP} className={appClassName} tabIndex={0}>
<div className={workbenchFinalClassName}>
<Display visible={isMenuBarHorizontal}>
<MenuBarView mode={MenuBarMode.horizontal} />
</Display>
<div className={mainBenchClassName}>
<div className={compositeBarClassName}>
<Display visible={isMenuBarVertical}>
<MenuBarView mode={MenuBarMode.vertical} />
</Display>
<Display
visible={!activityBar.hidden}
className={displayActivityBarClassName}
>
<ActivityBarView />
</Display>
</div>
<SplitPane
sizes={sidebar.hidden ? [0, '100%'] : splitPanePos}
split="vertical"
allowResize={[false]}
onChange={handleSideBarChanged}
onResizeStrategy={() => ['keep', 'pave']}
>
<Pane minSize={170} maxSize="80%">
<SidebarView />
</Pane>
<SplitPane
sizes={getSizes()}
allowResize={[false]}
split="horizontal"
onChange={handleEditorChanged}
onResizeStrategy={() => ['pave', 'keep']}
>
<Pane minSize="10%" maxSize="80%">
<EditorView />
</Pane>
<PanelView />
</SplitPane>
</SplitPane>
</div>
</div>
<Display visible={!statusBar.hidden}>
<StatusBarView />
</Display>
</div>

代码中,horizontal 模式下和 vertical 模式下的 MenuBarView 分别放在了不同的位置,SplitPane 组件中默认包含了 SidebarView 和右侧的 EditorPanel 面板,并没有包含 RightSideBar 面板。

具体改造如下:

/src/views/myWorkbench.tsx
<div
id={ID_APP}
className={classNames(appClassName, 'myMolecule')}
tabIndex={0}
>
<div className={workbenchFinalClassName}>
<Display visible={isMenuBarHorizontal}>
<MenuBarView mode={MenuBarMode.horizontal} />
</Display>
<div className={mainBenchClassName}>
<div className={compositeBarClassName}>
<Display visible={isMenuBarVertical}>
<MenuBarView mode={MenuBarMode.vertical} />
</Display>
<Display
visible={!activityBar.hidden}
className={displayActivityBarClassName}
>
<ActivityBarView />
</Display>
</div>
<SplitPane
sizes={sidebar.hidden ? [0, '100%'] : splitPanePos}
split="vertical"
allowResize={[false, true]}
onChange={handleSideBarChanged}
onResizeStrategy={() => ['keep', 'pave']}
>
<Pane minSize={170} maxSize="80%">
<SidebarView />
</Pane>
<SplitPane
sizes={getSizes()}
allowResize={[false, true]}
split="horizontal"
onChange={handleEditorChanged}
onResizeStrategy={() => ['pave', 'keep']}
>
<Pane minSize="10%" maxSize="80%">
<EditorView />
</Pane>
<PanelView />
</SplitPane>
</SplitPane>
<div style={{ width: 300 }}>
<Sidebar current={MySidePane.id} panes={[MySidePane]} />
</div>
</div>
</div>
<Display visible={!statusBar.hidden}>
<StatusBarView />
</Display>
</div>
caution

以上代码仅仅是 myWorkbench.tsx 文件的部分代码,完整代码请查看 molecule-demo

我们新增了一个RightSidebar,使用了内置的 Sidebar 组件,并在 Sidebar 中使用了自定义的 MySidePane 组件。

自定义 RightSideBar

我们复用了内置的 Sidebar 组件,这里我们只需要传入 ISidebarPane 类型的组件:

/src/views/mySidePane.tsx
import React from 'react';
import molecule from '@dtinsight/molecule';
import { Header, Content } from '@dtinsight/molecule/esm/workbench/sidebar';
import { IActionBarItemProps } from '@dtinsight/molecule/esm/components';
import { localize } from '@dtinsight/molecule/esm/i18n/localize';
import { ISidebarPane } from '@dtinsight/molecule/esm/model';

const Toolbar = molecule.component.Toolbar;

export function MySidePaneView() {
const renderHeaderToolbar = React.useCallback((): IActionBarItemProps[] => {
return [
{
icon: 'editor-layout',
id: 'tools',
title: 'Layout the right SidePane',
},
];
}, []);

return (
<div className={'mySidePane'}>
<Header
title={localize('demo.rightSidebar.title', 'Tools')}
toolbar={<Toolbar data={renderHeaderToolbar()} />}
/>
<Content>
<p style={{ textAlign: 'center' }}>Right Side Pane</p>
</Content>
</div>
);
}

export const MySidePane: ISidebarPane = {
id: 'mySidePane',
title: 'Tools',
render: () => {
return <MySidePaneView />;
},
};

完成这些操作后,即可在界面中看到如上图所示的布局了。完整示例请参考 molecule-demo

总结

上例中使用了很多 Molecule 内置的 UI 组件来实现自定义,然而使用内置组件是有一定上手成本的,需要开发者对内置的 UI 组件有比较好了解。我们会在后序的版本中,持续优化文档API,以减轻上手成本,并尽可能的提供更多的使用示例