@opensumi/ide-menu-bar 2.21.13 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/menu-bar.contribution.js.map +1 -1
- package/lib/browser/menu-bar.store.js.map +1 -1
- package/lib/browser/menu-bar.view.d.ts +1 -1
- package/lib/browser/menu-bar.view.d.ts.map +1 -1
- package/package.json +9 -8
- package/src/browser/index.ts +17 -0
- package/src/browser/menu-bar.contribution.ts +41 -0
- package/src/browser/menu-bar.module.less +48 -0
- package/src/browser/menu-bar.store.ts +64 -0
- package/src/browser/menu-bar.view.tsx +128 -0
- package/src/browser/toolbar-action.module.less +25 -0
- package/src/browser/toolbar-action.view.tsx +45 -0
- package/src/index.ts +1 -0
package/lib/browser/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";;;;AAAA,0BAA0B;AAC1B,qCAAoD;AACpD,iEAA2D;AAE3D,mEAA8D;AAC9D,qDAAsE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";;;;AAAA,0BAA0B;AAC1B,qCAAoD;AACpD,iEAA2D;AAE3D,mEAA8D;AAC9D,qDAAsE;AAG/D,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,gCAAa;IAAzC;;QACL,cAAS,GAAe;YACtB,2CAAmB;YACnB;gBACE,KAAK,EAAE,qCAAoB;gBAC3B,QAAQ,EAAE,6BAAY;aACvB;SACF,CAAC;IACJ,CAAC;CAAA,CAAA;AARY,aAAa;IADzB,IAAA,eAAU,GAAE;GACA,aAAa,CAQzB;AARY,sCAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-bar.contribution.js","sourceRoot":"","sources":["../../src/browser/menu-bar.contribution.ts"],"names":[],"mappings":";;;;AAAA,qCAAyC;AACzC,iEAAoG;AACpG,kEAAiG;AACjG,uEAAiE;AAEjE,mDAA0D;AAC1D,+DAAsD;
|
|
1
|
+
{"version":3,"file":"menu-bar.contribution.js","sourceRoot":"","sources":["../../src/browser/menu-bar.contribution.ts"],"names":[],"mappings":";;;;AAAA,qCAAyC;AACzC,iEAAoG;AACpG,kEAAiG;AACjG,uEAAiE;AAEjE,mDAA0D;AAC1D,+DAAsD;AAI/C,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAI9B,iBAAiB,CAAC,QAA2B;QAC3C,QAAQ,CAAC,QAAQ,CACf,wBAAwB,EACxB;YACE,EAAE,EAAE,cAAc;YAClB,SAAS,EAAE,uCAAuB;SACnC,EACD;YACE,IAAI,EAAE,EAAE;SACT,CACF,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;YACtC,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,EAAE;gBAChD,EAAE,EAAE,oBAAoB;gBACxB,SAAS,EAAE,mCAAa;aACzB,CAAC,CAAC;SACJ;IACH,CAAC;IAED,sBAAsB,CAAC,QAA0B;QAC/C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;YACtC,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YACnC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;SACnC;IACH,CAAC;CACF,CAAA;AA7BC;IAAC,IAAA,cAAS,EAAC,4BAAS,CAAC;;sDACiB;AAF3B,mBAAmB;IAD/B,IAAA,kBAAM,EAAC,8BAAqB,EAAE,4CAAyB,CAAC;GAC5C,mBAAmB,CA8B/B;AA9BY,kDAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-bar.store.js","sourceRoot":"","sources":["../../src/browser/menu-bar.store.ts"],"names":[],"mappings":";;;;AAAA,uEAAuC;AACvC,+BAA0C;AAE1C,qCAAqD;AACrD,iEAAwD;AACxD,mEAA0G;AAE1G,MAAsB,oBAAqB,SAAQ,6BAAU;CAG5D;AAHD,oDAGC;
|
|
1
|
+
{"version":3,"file":"menu-bar.store.js","sourceRoot":"","sources":["../../src/browser/menu-bar.store.ts"],"names":[],"mappings":";;;;AAAA,uEAAuC;AACvC,+BAA0C;AAE1C,qCAAqD;AACrD,iEAAwD;AACxD,mEAA0G;AAE1G,MAAsB,oBAAqB,SAAQ,6BAAU;CAG5D;AAHD,oDAGC;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,6BAAU;IAU1C;QACE,KAAK,EAAE,CAAC;QANH,iBAAY,GAAG,iBAAU,CAAC,KAAK,CAAe,EAAE,CAAC,CAAC;QAGlD,cAAS,GAAG,iBAAU,CAAC,GAAG,EAAsB,CAAC;QAmCjD,uBAAkB,GAA6B,IAAA,kBAAQ,EAC5D,CAAC,MAAc,EAAE,EAAE;YACjB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,EACD,GAAG,EACH,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAClC,CAAC;QApCA,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAChH,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC5G,CAAC;IAGO,eAAe,CAAC,MAAc;QACpC,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACjE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;IAEO,KAAK;QACX,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;QAC3D,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC;QACvE,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;YACtC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,iBAAiB,CAAC,MAAc;QACtC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAEO,oBAAoB;QAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;QAC3D,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;CAUF,CAAA;AAjDC;IAAC,IAAA,cAAS,EAAC,6BAAsB,CAAC;sCACD,6BAAsB;oDAAC;AAExD;IAAC,iBAAU;;kDAC8C;AAEzD;IAAC,iBAAU;;+CAC6C;AAUxD;IAAC,aAAM,CAAC,KAAK;;;;mDAKZ;AAmBD;IAAC,aAAM,CAAC,KAAK;;wDAOX;AAjDS,YAAY;IADxB,IAAA,eAAU,GAAE;;GACA,YAAY,CAkDxB;AAlDY,oCAAY"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export declare const MenuBar: React.FunctionComponent<object>;
|
|
3
|
-
|
|
3
|
+
type MenuBarMixToolbarActionProps = Pick<React.HTMLProps<HTMLElement>, 'className'>;
|
|
4
4
|
export declare const MenuBarMixToolbarAction: React.FC<MenuBarMixToolbarActionProps>;
|
|
5
5
|
export declare const MenuBarActionWrapper: (props: MenuBarMixToolbarActionProps) => React.FunctionComponentElement<MenuBarMixToolbarActionProps>;
|
|
6
6
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-bar.view.d.ts","sourceRoot":"","sources":["../../src/browser/menu-bar.view.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AA8E1B,eAAO,MAAM,OAAO,iCAgClB,CAAC;AAIH,
|
|
1
|
+
{"version":3,"file":"menu-bar.view.d.ts","sourceRoot":"","sources":["../../src/browser/menu-bar.view.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AA8E1B,eAAO,MAAM,OAAO,iCAgClB,CAAC;AAIH,KAAK,4BAA4B,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC;AAEpF,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CAK1E,CAAC;AAIF,eAAO,MAAM,oBAAoB,uGAA8E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opensumi/ide-menu-bar",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"description": "@opensumi/ide-menu-bar",
|
|
5
5
|
"files": [
|
|
6
|
-
"lib"
|
|
6
|
+
"lib",
|
|
7
|
+
"src"
|
|
7
8
|
],
|
|
8
9
|
"license": "MIT",
|
|
9
10
|
"main": "lib/index.js",
|
|
10
11
|
"typings": "lib/index.d.ts",
|
|
11
12
|
"scripts": {
|
|
12
|
-
"prepublishOnly": "
|
|
13
|
+
"prepublishOnly": "yarn run build",
|
|
13
14
|
"build": "tsc --build ../../configs/ts/references/tsconfig.menu-bar.json"
|
|
14
15
|
},
|
|
15
16
|
"repository": {
|
|
@@ -17,12 +18,12 @@
|
|
|
17
18
|
"url": "git@github.com:opensumi/core.git"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
|
-
"@opensumi/ide-core-common": "2.
|
|
21
|
+
"@opensumi/ide-core-common": "2.22.0"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
|
-
"@opensumi/ide-components": "2.
|
|
24
|
-
"@opensumi/ide-core-browser": "2.
|
|
25
|
-
"@opensumi/ide-dev-tool": "
|
|
24
|
+
"@opensumi/ide-components": "2.22.0",
|
|
25
|
+
"@opensumi/ide-core-browser": "2.22.0",
|
|
26
|
+
"@opensumi/ide-dev-tool": "1.3.1"
|
|
26
27
|
},
|
|
27
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "927717e1c60f9cf5f01622fd51085b318a175eeb"
|
|
28
29
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* istanbul ignore file */
|
|
2
|
+
import { Provider, Injectable } from '@opensumi/di';
|
|
3
|
+
import { BrowserModule } from '@opensumi/ide-core-browser';
|
|
4
|
+
|
|
5
|
+
import { MenuBarContribution } from './menu-bar.contribution';
|
|
6
|
+
import { AbstractMenubarStore, MenubarStore } from './menu-bar.store';
|
|
7
|
+
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class MenuBarModule extends BrowserModule {
|
|
10
|
+
providers: Provider[] = [
|
|
11
|
+
MenuBarContribution,
|
|
12
|
+
{
|
|
13
|
+
token: AbstractMenubarStore,
|
|
14
|
+
useClass: MenubarStore,
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Autowired } from '@opensumi/di';
|
|
2
|
+
import { ToolBarActionContribution, AppConfig, IToolbarRegistry } from '@opensumi/ide-core-browser';
|
|
3
|
+
import { ComponentContribution, ComponentRegistry } from '@opensumi/ide-core-browser/lib/layout';
|
|
4
|
+
import { Domain } from '@opensumi/ide-core-common/lib/di-helper';
|
|
5
|
+
|
|
6
|
+
import { MenuBarMixToolbarAction } from './menu-bar.view';
|
|
7
|
+
import { ToolbarAction } from './toolbar-action.view';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@Domain(ComponentContribution, ToolBarActionContribution)
|
|
11
|
+
export class MenuBarContribution implements ComponentContribution, ToolBarActionContribution {
|
|
12
|
+
@Autowired(AppConfig)
|
|
13
|
+
private readonly appConfig: AppConfig;
|
|
14
|
+
|
|
15
|
+
registerComponent(registry: ComponentRegistry) {
|
|
16
|
+
registry.register(
|
|
17
|
+
'@opensumi/ide-menu-bar',
|
|
18
|
+
{
|
|
19
|
+
id: 'ide-menu-bar',
|
|
20
|
+
component: MenuBarMixToolbarAction,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
size: 27,
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (!this.appConfig.isElectronRenderer) {
|
|
28
|
+
registry.register('@opensumi/ide-toolbar-action', {
|
|
29
|
+
id: 'ide-toolbar-action',
|
|
30
|
+
component: ToolbarAction,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
registerToolbarActions(registry: IToolbarRegistry) {
|
|
36
|
+
if (!this.appConfig.isElectronRenderer) {
|
|
37
|
+
registry.addLocation('menu-right');
|
|
38
|
+
registry.addLocation('menu-left');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@import '~@opensumi/ide-core-browser/lib/style/variable.less';
|
|
2
|
+
|
|
3
|
+
.menubarWrapper {
|
|
4
|
+
display: flex;
|
|
5
|
+
background-color: var(--kt-menubar-background);
|
|
6
|
+
z-index: 1;
|
|
7
|
+
position: relative;
|
|
8
|
+
user-select: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.logoIconEmpty {
|
|
12
|
+
padding-left: 10px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.menubars {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
font-size: 14px;
|
|
19
|
+
flex-grow: 1;
|
|
20
|
+
flex-shrink: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.menubar {
|
|
24
|
+
height: 100%;
|
|
25
|
+
display: flex;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
align-items: center;
|
|
28
|
+
padding: 0 12px;
|
|
29
|
+
color: var(--kt-menubar-foreground);
|
|
30
|
+
user-select: none;
|
|
31
|
+
|
|
32
|
+
// 目前尚未开启使用 kt.menubar.separatorBackground
|
|
33
|
+
|
|
34
|
+
&.menu-open,
|
|
35
|
+
&:hover {
|
|
36
|
+
color: var(--menubar-selectionForeground);
|
|
37
|
+
background-color: var(--menubar-selectionBackground);
|
|
38
|
+
border-left: 1px solid var(--menubar-selectionBorder);
|
|
39
|
+
border-right: 1px solid var(--menubar-selectionBorder);
|
|
40
|
+
cursor: default;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&-drop {
|
|
44
|
+
position: absolute;
|
|
45
|
+
left: 0;
|
|
46
|
+
top: 100%;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import debounce from 'lodash/debounce';
|
|
2
|
+
import { observable, action } from 'mobx';
|
|
3
|
+
|
|
4
|
+
import { Injectable, Autowired } from '@opensumi/di';
|
|
5
|
+
import { Disposable } from '@opensumi/ide-core-browser';
|
|
6
|
+
import { AbstractMenubarService, IMenubarItem, MenuNode } from '@opensumi/ide-core-browser/lib/menu/next';
|
|
7
|
+
|
|
8
|
+
export abstract class AbstractMenubarStore extends Disposable {
|
|
9
|
+
menubarItems: IMenubarItem[];
|
|
10
|
+
abstract handleMenubarClick(menuId: string): void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@Injectable()
|
|
14
|
+
export class MenubarStore extends Disposable implements AbstractMenubarStore {
|
|
15
|
+
@Autowired(AbstractMenubarService)
|
|
16
|
+
private readonly menubarService: AbstractMenubarService;
|
|
17
|
+
|
|
18
|
+
@observable
|
|
19
|
+
public menubarItems = observable.array<IMenubarItem>([]);
|
|
20
|
+
|
|
21
|
+
@observable
|
|
22
|
+
public menuItems = observable.map<string, MenuNode[]>();
|
|
23
|
+
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
|
|
27
|
+
this.build();
|
|
28
|
+
this.registerDispose(this.menubarService.onDidMenubarChange(this.handleMenubarChanged, this, this.disposables));
|
|
29
|
+
this.registerDispose(this.menubarService.onDidMenuChange(this.handleMenuChanged, this, this.disposables));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@action.bound
|
|
33
|
+
private updateMenuNodes(menuId: string) {
|
|
34
|
+
this.menubarService.rebuildMenuNodes(menuId);
|
|
35
|
+
const menuItems = this.menubarService.getMenuNodes(menuId) || [];
|
|
36
|
+
this.menuItems.set(menuId, menuItems);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private build() {
|
|
40
|
+
const menubarItems = this.menubarService.getMenubarItems();
|
|
41
|
+
this.menubarItems.splice(0, this.menubarItems.length, ...menubarItems);
|
|
42
|
+
menubarItems.forEach(({ id: menuId }) => {
|
|
43
|
+
this.updateMenuNodes(menuId);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private handleMenuChanged(menuId: string) {
|
|
48
|
+
this.updateMenuNodes(menuId);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private handleMenubarChanged() {
|
|
52
|
+
const menubarItems = this.menubarService.getMenubarItems();
|
|
53
|
+
this.menubarItems.replace(menubarItems);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@action.bound
|
|
57
|
+
public handleMenubarClick: (menuId: string) => void = debounce(
|
|
58
|
+
(menuId: string) => {
|
|
59
|
+
this.updateMenuNodes(menuId);
|
|
60
|
+
},
|
|
61
|
+
500,
|
|
62
|
+
{ leading: true, trailing: true },
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import clx from 'classnames';
|
|
2
|
+
import { observer } from 'mobx-react-lite';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import { ClickOutside } from '@opensumi/ide-components';
|
|
6
|
+
import { Dropdown } from '@opensumi/ide-components/lib/dropdown';
|
|
7
|
+
import { Deprecated } from '@opensumi/ide-components/lib/utils/deprecated';
|
|
8
|
+
import { useInjectable, SlotRenderer, ComponentRegistry } from '@opensumi/ide-core-browser';
|
|
9
|
+
import { MenuActionList } from '@opensumi/ide-core-browser/lib/components/actions';
|
|
10
|
+
import { LAYOUT_VIEW_SIZE } from '@opensumi/ide-core-browser/lib/layout/constants';
|
|
11
|
+
import { IMenubarItem } from '@opensumi/ide-core-browser/lib/menu/next';
|
|
12
|
+
|
|
13
|
+
import styles from './menu-bar.module.less';
|
|
14
|
+
import { MenubarStore } from './menu-bar.store';
|
|
15
|
+
|
|
16
|
+
const MenubarItem = observer<
|
|
17
|
+
IMenubarItem & {
|
|
18
|
+
focusMode: boolean;
|
|
19
|
+
afterMenuClick: () => void;
|
|
20
|
+
afterMenubarClick: () => void;
|
|
21
|
+
}
|
|
22
|
+
>(({ id, label, focusMode, afterMenubarClick, afterMenuClick }) => {
|
|
23
|
+
const menubarStore = useInjectable<MenubarStore>(MenubarStore);
|
|
24
|
+
const [menuOpen, setMenuOpen] = React.useState<boolean>(false);
|
|
25
|
+
|
|
26
|
+
const handleMenubarItemClick = React.useCallback(() => {
|
|
27
|
+
menubarStore.handleMenubarClick(id);
|
|
28
|
+
if (focusMode) {
|
|
29
|
+
setMenuOpen(true);
|
|
30
|
+
} else {
|
|
31
|
+
setMenuOpen((r) => !r);
|
|
32
|
+
}
|
|
33
|
+
afterMenubarClick();
|
|
34
|
+
}, [id]);
|
|
35
|
+
|
|
36
|
+
const handleMenuItemClick = () => {
|
|
37
|
+
setMenuOpen(false);
|
|
38
|
+
afterMenuClick();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleMouseOver = React.useCallback(() => {
|
|
42
|
+
// 只有 focus mode 下才会 hover 时重新生成数据
|
|
43
|
+
if (focusMode) {
|
|
44
|
+
menubarStore.handleMenubarClick(id);
|
|
45
|
+
}
|
|
46
|
+
}, [id, focusMode]);
|
|
47
|
+
|
|
48
|
+
const triggerMenuVisibleChange = (visible: boolean) => {
|
|
49
|
+
setMenuOpen(visible);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const data = menubarStore.menuItems.get(id) || [];
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Dropdown
|
|
56
|
+
className={'kt-menu'}
|
|
57
|
+
transitionName=''
|
|
58
|
+
align={{
|
|
59
|
+
offset: [0, 0],
|
|
60
|
+
}}
|
|
61
|
+
visible={menuOpen}
|
|
62
|
+
onVisibleChange={triggerMenuVisibleChange}
|
|
63
|
+
overlay={<MenuActionList data={data} afterClick={handleMenuItemClick} />}
|
|
64
|
+
trigger={focusMode ? ['click', 'hover'] : ['click']}
|
|
65
|
+
>
|
|
66
|
+
<div
|
|
67
|
+
className={clx(styles.menubar, { [styles['menu-open']]: menuOpen })}
|
|
68
|
+
onMouseOver={handleMouseOver}
|
|
69
|
+
onClick={handleMenubarItemClick}
|
|
70
|
+
>
|
|
71
|
+
{label}
|
|
72
|
+
</div>
|
|
73
|
+
</Dropdown>
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// 点击一次后开启 focus mode, 此时 hover 也能出现子菜单
|
|
78
|
+
// outside click/contextmenu 之后解除 focus mode
|
|
79
|
+
// 点击 MenubarItem 也会解除 focus mode
|
|
80
|
+
// 点击 MenuItem 也会解除 focus mode
|
|
81
|
+
export const MenuBar = observer(() => {
|
|
82
|
+
const menubarStore = useInjectable<MenubarStore>(MenubarStore);
|
|
83
|
+
const componentRegistry: ComponentRegistry = useInjectable(ComponentRegistry);
|
|
84
|
+
const [focusMode, setFocusMode] = React.useState(false);
|
|
85
|
+
|
|
86
|
+
const handleMouseLeave = React.useCallback(() => {
|
|
87
|
+
// 只有 focus 为 true 的时候, mouse leave 才会将其置为 false
|
|
88
|
+
setFocusMode(false);
|
|
89
|
+
}, [focusMode]);
|
|
90
|
+
|
|
91
|
+
const LogoIcon = componentRegistry.getComponentRegistryInfo('@opensumi/ide-menu-bar-logo')?.views[0].component;
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<ClickOutside
|
|
95
|
+
className={styles.menubars}
|
|
96
|
+
style={{ height: LAYOUT_VIEW_SIZE.MENUBAR_HEIGHT }}
|
|
97
|
+
mouseEvents={['click', 'contextmenu']}
|
|
98
|
+
onOutsideClick={handleMouseLeave}
|
|
99
|
+
>
|
|
100
|
+
{LogoIcon ? <LogoIcon /> : <div className={styles.logoIconEmpty}></div>}
|
|
101
|
+
{menubarStore.menubarItems.map(({ id, label }) => (
|
|
102
|
+
<MenubarItem
|
|
103
|
+
key={id}
|
|
104
|
+
id={id}
|
|
105
|
+
label={label}
|
|
106
|
+
focusMode={focusMode}
|
|
107
|
+
afterMenuClick={() => setFocusMode(false)}
|
|
108
|
+
afterMenubarClick={() => setFocusMode((r) => !r)}
|
|
109
|
+
/>
|
|
110
|
+
))}
|
|
111
|
+
</ClickOutside>
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
MenuBar.displayName = 'MenuBar';
|
|
116
|
+
|
|
117
|
+
type MenuBarMixToolbarActionProps = Pick<React.HTMLProps<HTMLElement>, 'className'>;
|
|
118
|
+
|
|
119
|
+
export const MenuBarMixToolbarAction: React.FC<MenuBarMixToolbarActionProps> = (props) => (
|
|
120
|
+
<div className={clx(styles.menubarWrapper, props.className)}>
|
|
121
|
+
<MenuBar />
|
|
122
|
+
<SlotRenderer slot='action' flex={1} overflow={'initial'} />
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
MenuBarMixToolbarAction.displayName = 'MenuBarMixToolbarAction';
|
|
127
|
+
|
|
128
|
+
export const MenuBarActionWrapper = Deprecated(MenuBarMixToolbarAction, 'please use `MenuBarMixToolbarAction`');
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/*
|
|
2
|
+
@deprecated
|
|
3
|
+
*/
|
|
4
|
+
.toolbarActionsWrapper {
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
.toolbarActions {
|
|
8
|
+
&.toolbarActionsLeft {
|
|
9
|
+
flex-shrink: 0;
|
|
10
|
+
}
|
|
11
|
+
&.toolbarActionsRight {
|
|
12
|
+
flex-grow: 1;
|
|
13
|
+
}
|
|
14
|
+
padding: 0 10px;
|
|
15
|
+
height: 27px;
|
|
16
|
+
background-color: var(--kt-menubar-background);
|
|
17
|
+
|
|
18
|
+
:global(.kt-toolbar-location-visible) {
|
|
19
|
+
display: flex;
|
|
20
|
+
justify-content: flex-end;
|
|
21
|
+
align-items: center;
|
|
22
|
+
height: 100%;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import classnames from 'classnames';
|
|
2
|
+
import { observer } from 'mobx-react-lite';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import { ToolbarLocation } from '@opensumi/ide-core-browser';
|
|
6
|
+
|
|
7
|
+
import styles from './toolbar-action.module.less';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// const ActionGroup = observer(({ group, id }: { group: IToolbarActionGroup; id: string }) => {
|
|
11
|
+
// return (<div className={styles.actionGroup} key={id}>
|
|
12
|
+
// {group.map((action) => {
|
|
13
|
+
// switch (action.type) {
|
|
14
|
+
// case 'action':
|
|
15
|
+
// return (
|
|
16
|
+
// <Tooltip title={action.title}>
|
|
17
|
+
// <Button key={`${id}-${action.title}`} onClick={action.click} className={styles.action} type='icon' iconClass={action.iconClass} />
|
|
18
|
+
// </Tooltip>);
|
|
19
|
+
// case 'enum':
|
|
20
|
+
// return (<Select
|
|
21
|
+
// key={`${id}-${action.title}`}
|
|
22
|
+
// onChange={action.select}
|
|
23
|
+
// className={styles.action}
|
|
24
|
+
// size='small'
|
|
25
|
+
// style={{ width: 110 }}
|
|
26
|
+
// value={action.defaultValue || action.title}
|
|
27
|
+
// options={action.enum.map((option) => <Option key={option} label={option} value={option}>{option}</Option>)}
|
|
28
|
+
// />);
|
|
29
|
+
// default:
|
|
30
|
+
// console.warn(`Unknow Action type called: ${id}`);
|
|
31
|
+
// }
|
|
32
|
+
// })}
|
|
33
|
+
// </div>);
|
|
34
|
+
// });
|
|
35
|
+
|
|
36
|
+
export const ToolbarAction = observer(() => (
|
|
37
|
+
<div className={styles.toolbarActionsWrapper}>
|
|
38
|
+
<ToolbarLocation
|
|
39
|
+
location='menu-left'
|
|
40
|
+
preferences={{ noDropDown: true }}
|
|
41
|
+
className={classnames(styles.toolbarActions, styles.toolbarActionsLeft)}
|
|
42
|
+
/>
|
|
43
|
+
<ToolbarLocation location='menu-right' className={classnames(styles.toolbarActions, styles.toolbarActionsRight)} />
|
|
44
|
+
</div>
|
|
45
|
+
));
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './browser';
|