Skip to content

Commit

Permalink
feat: add serviceTab logic
Browse files Browse the repository at this point in the history
  • Loading branch information
mumiao committed Dec 17, 2020
1 parent 6141663 commit bbc1973
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 46 deletions.
3 changes: 2 additions & 1 deletion src/components/tabs/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { classNames, getBEMElement, getBEMModifier, prefixClaName } from 'mo/com

export const tabClassName = prefixClaName('tab')
export const tabItemClassName = getBEMElement(tabClassName, 'item')
export const tabItemCloseClassName = getBEMElement(tabItemClassName, 'close')

export const Tab = (props) => {
const { index, propsKey, activeTab, children, onMoveTab, onTabChange } = props;
Expand Down Expand Up @@ -65,7 +66,7 @@ export const Tab = (props) => {
<div
ref={ref}
className={classNames(tabItemClassName, { [getBEMModifier(tabItemClassName, 'active')]: activeTab === propsKey })}
onClick={(event: React.MouseEvent) => onTabChange(event, propsKey)}
onClick={(event: React.MouseEvent) => onTabChange(propsKey)}
>
{children}
</div>
Expand Down
27 changes: 15 additions & 12 deletions src/components/tabs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { useCallback, useState } from 'react';
import { useCallback } from 'react';
import { DndProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import update from 'immutability-helper';
Expand Down Expand Up @@ -29,7 +29,7 @@ export interface ITabsProps {
type?: 'line' | 'editable-card';
onCloseTab?: (key?: string) => void ;
onMoveTab?: (tabs: ITab[]) => void;
onSelectTab?: (event: React.MouseEvent, key?: string) => void;
onSelectTab?: (key?: string) => void;
}

export const tabsClassName = prefixClaName('tabs')
Expand All @@ -55,22 +55,25 @@ const Tabs = (props: ITabsProps) => {
[data]
);

const onTabClick = (event: React.MouseEvent, key?: string) => {
onSelectTab?.(event, key);
const onTabClick = (key?: string) => {
onSelectTab?.(key);
};

const onTabClose = (item: ITab) => {
onCloseTab?.(item.key)
};

const renderTabBar = (tab) => (
<TabButton
key={tab.key}
name={tab.name}
modified={tab.modified}
active={activeTab === tab.key}
onClose={() => onCloseTab?.(tab.key)}
/>)
const renderTabBar = (tab) => {
return (
<TabButton
key={tab.key}
name={tab.name}
modified={tab.modified}
active={activeTab === tab.key}
onClose={() => onCloseTab?.(tab.key)}
/>
)
}
return (
<DndProvider backend={HTML5Backend}>
<div className={classNames(tabsClassName, getBEMModifier(tabsClassName, `${type}`))}>
Expand Down
7 changes: 2 additions & 5 deletions src/components/tabs/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,23 @@
padding: 0 14px;
position: relative;
user-select: none;
width: 150px;

&__name {
font-size: 16px;
margin-left: 10px;
}

&__op {
align-items: center;
display: inline-flex;
line-height: 1;
margin-left: 10px;
width: 20px;
}

&__dot {
display: block;
height: 18px;
position: relative;
width: 18px;

&::after {
border-radius: 50%;
content: '';
Expand Down
7 changes: 5 additions & 2 deletions src/extensions/search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ function init() {
editorService.onMoveTab((data) => {
console.log(data);
});
editorService.onSelectTab((tab) => {
console.log(`selected tabKey${tab}`);
editorService.onSelectTab((tabKey?: string) => {
console.log(`selected tabKey ${tabKey}`);
});
editorService.onCloseTab((tabKey?: string) => {
console.log(`closed tabkey ${tabKey}`)
})
}

export const ExtendSearch: IExtension = {
Expand Down
4 changes: 2 additions & 2 deletions src/extensions/search/searchPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ export default class SearchPane extends React.Component<
const tabData = {
key: `${key}`,
name: `editor.js`,
modified: true,
value: `hello javascript${key}`,
modified: false,
value: `hello javascript ${key}`,
path: 'desktop/molecule/editor1'
};
console.log('open editor:', tabData);
Expand Down
14 changes: 8 additions & 6 deletions src/model/workbench/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ITab } from 'mo/components/tabs';
import { container, inject, injectable } from 'tsyringe';

export enum EditorEvent {
CloseTab = 'editor.close',
OnCloseTab = 'editor.closeTab',
OnMoveTab = 'editor.moveTab',
OpenTab = 'editor.openTab',
OnSelectTab = 'editor.selectTab',
Expand All @@ -14,10 +14,10 @@ export interface IEditor {
current: IEditorGroup | undefined;
groups: IEditorGroup[];
closeAll?: () => void;
onClose?: () => void;
onCloseTab?: (tabKey?: string, group?: number) => void;
render?: () => React.ReactNode;
onMoveTab?: (tabs: ITab[], group?: number) => void;
onSelectTab?: (tabKey: string) => void;
onSelectTab?: (tabKey: string, group?: number) => void;
}

export interface IEditorGroup<E = any> {
Expand Down Expand Up @@ -72,16 +72,18 @@ export class EditorModel implements IEditor {
this.groups = groups;
}
closeAll?: (() => void) | undefined;
onClose?: (() => void) | undefined;

public render!: () => React.ReactNode;

public readonly onselectTab = (tabKey: number) => {
EventBus.emit(EditorEvent.OnSelectTab, tabKey);
public readonly onSelectTab = (tabKey: string, groupId?: number) => {
EventBus.emit(EditorEvent.OnSelectTab, tabKey, groupId);
};
public readonly onMoveTab = (updateTabs: ITab[], groupId?: number) => {
EventBus.emit(EditorEvent.OnMoveTab, updateTabs, groupId);
};
public readonly onCloseTab = (tabKey?: string, groupId?: number) => {
EventBus.emit(EditorEvent.OnCloseTab, tabKey, groupId);
};
}

container.register('CurrentEditorGroup', { useValue: '' });
Expand Down
46 changes: 40 additions & 6 deletions src/services/workbench/editorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface IEditorService extends Component<IEditor> {
* @param groupId group ID
*/
open<T = any>(tab: ITab, groupId?: number): void;
close(index: string, callback: () => void): void;
onCloseTab(callback: (tabKey?: string) => void);
onMoveTab(callback: (tabs: ITab[]) => void);
onSelectTab(callback: (tabKey: string) => void);
}
Expand All @@ -32,9 +32,18 @@ export class EditorService
super();
this.state = container.resolve(EditorModel);
}

@emit(EditorEvent.OnSelectTab)
onSelectTab(callback: (tabKey: string) => void) {
this.subscribe(EditorEvent.OnSelectTab, (args) => {
callback?.(args?.[0]);
let group;
let { groups } = this.state;
const groupId = args?.[1];
const targetKey = args?.[0];
if (!groupId) return;
group = groups?.find((group: IEditorGroup) => group.id === groupId);
group.activeTab = { ...group.activeTab, key: targetKey};
callback?.(targetKey);
});
}

Expand Down Expand Up @@ -67,8 +76,33 @@ export class EditorService
}
public closeAll() {}

@emit(EditorEvent.CloseTab)
public onClose() {}

public close(index: string, callback: () => void) {}
@emit(EditorEvent.OnCloseTab)
public onCloseTab(callback: (data) => void) {
this.subscribe(EditorEvent.OnCloseTab, (args) => {
let group,lastIndex;
let { groups } = this.state;
const groupId = args?.[1];
const targetKey = args?.[0];
if (!groupId) return;
group = groups?.find((group: IEditorGroup) => group.id === groupId);
let newActiveKey = group?.activeTab?.key;
const groupTabs = group.tabs;
groupTabs.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const newPanes = groupTabs.filter(pane => pane.key !== targetKey);
if (newPanes.length && newActiveKey === targetKey) {
if (lastIndex >= 0) {
newActiveKey = newPanes[lastIndex].key
} else {
newActiveKey = newPanes[0].key
}
}
group.tabs = newPanes
group.activeTab ={ ...group.activeTab, key: newActiveKey}
callback?.(targetKey)
});
}
}
9 changes: 6 additions & 3 deletions src/style/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -170,23 +170,26 @@
}

&--editable-card {
#{$tabs}__header {
border-bottom: 1px solid transparent;
}
#{$tab}__item {
&--active {

border-bottom: 1px solid transparent;
}
}
}
}

#{$tab} {
&__item {
background: inherit;
background: #232323;
color: #888;

&--active {
background: #1e1e1e;
border-bottom: 1px solid #e7e7e7;
color: #e7e7e7;
color: #fff;
}

&--close {
Expand Down
22 changes: 13 additions & 9 deletions src/workbench/editor/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import { IEditor, IEditorGroup } from 'mo/model';
const defaultEditorClassName = prefixClaName('editor');
const groupClassName = getBEMElement(defaultEditorClassName, 'group');

function renderEditorGroup(group: IEditorGroup, onMoveTab, onSelectTab) {
function renderEditorGroup(group: IEditorGroup, onMoveTab, onCloseTab, onSelectTab) {
const editor = group.activeTab;

const tabs = group.tabs.map((item, index) => {
const tabs = group.tabs?.map((item, index) => {
return Object.assign({}, item, {
key: item.key,
tip: item.path,
Expand All @@ -40,15 +39,15 @@ function renderEditorGroup(group: IEditorGroup, onMoveTab, onSelectTab) {
onMoveTab={onMoveTab}
onSelectTab={onSelectTab}
activeTab={editor.key}
onCloseTab={(tabKey) => console.log(tabKey)}
onCloseTab={onCloseTab}
/>
</div>
);
}

export function renderGroups(groups: IEditorGroup[], onMoveTab, onSelectTab) {
export function renderGroups(groups: IEditorGroup[], onCloseTab, onMoveTab, onSelectTab) {
if (groups.length === 1) {
return renderEditorGroup(groups[0], onMoveTab, onSelectTab);
return renderEditorGroup(groups[0], onMoveTab, onCloseTab, onSelectTab);
} else if (groups.length > 1) {
const averageNum = Math.round(100 / groups.length);
return (
Expand All @@ -59,7 +58,7 @@ export function renderGroups(groups: IEditorGroup[], onMoveTab, onSelectTab) {
allowResize={true}
>
{groups.map((g: IEditorGroup) =>
renderEditorGroup(g, onMoveTab, onSelectTab)
renderEditorGroup(g, onMoveTab, onCloseTab, onSelectTab)
)}
</SplitPane>
);
Expand All @@ -68,12 +67,17 @@ export function renderGroups(groups: IEditorGroup[], onMoveTab, onSelectTab) {
}

export function Editor(props: IEditor) {
const { groups, render, current, onMoveTab, onSelectTab } = props;
const { groups, render, current, onCloseTab, onMoveTab, onSelectTab } = props;

const setMoveTab = tabs => onMoveTab?.(tabs, 1)
const setCloseTab = tabKey => onCloseTab?.(tabKey, 1)
const setSelectTab = tabKey => onSelectTab?.(tabKey, 1)

let content: React.ReactNode = <Welcome />;
if (current) {
content = render
? render()
: renderGroups(groups, (tabs) => onMoveTab?.(tabs, 1), onSelectTab);
: renderGroups(groups, setCloseTab, setMoveTab, setSelectTab );
}

return <div className={defaultEditorClassName}>{content}</div>;
Expand Down

0 comments on commit bbc1973

Please sign in to comment.