自定义工作台(Workbench)
Molecule 默认的 Workbench UI 是一个 VSCode 的克隆版本。但是我们在实际的开发场景中,往往不能满足我们的需求。
除了内置的一些原子 Components 以外,Molecule 同时提供了基本的 Workbench、SideBar、Editor、ActivityBar、MenuBar、Panel、StatusBar 等核心UI 部件,以便开发者根据自己的需求重新组装自己的 Workbench。
tip
本文内容中的所有代码,都以 Quick Start 中的 molecule-demo 项目为基础演示。
自定义 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
和右侧的 Editor 和 Panel 面板,并没有包含 RightSideBar 面板。
具体改造如下:
<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 类型的组件:
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,以减轻上手成本,并尽可能的提供更多的使用示例。