@opensumi/ide-core-browser 3.2.5 → 3.2.6-next-1724824955.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.
Files changed (76) hide show
  1. package/lib/ai-native/command.d.ts +6 -0
  2. package/lib/ai-native/command.d.ts.map +1 -1
  3. package/lib/ai-native/command.js +7 -1
  4. package/lib/ai-native/command.js.map +1 -1
  5. package/lib/bootstrap/app.d.ts.map +1 -1
  6. package/lib/bootstrap/app.js +4 -1
  7. package/lib/bootstrap/app.js.map +1 -1
  8. package/lib/components/ai-native/enhanceIcon/index.d.ts +4 -0
  9. package/lib/components/ai-native/enhanceIcon/index.d.ts.map +1 -1
  10. package/lib/components/ai-native/enhanceIcon/index.js +1 -1
  11. package/lib/components/ai-native/enhanceIcon/index.js.map +1 -1
  12. package/lib/components/ai-native/interactive-input/index.d.ts.map +1 -1
  13. package/lib/components/ai-native/interactive-input/index.js +1 -1
  14. package/lib/components/ai-native/interactive-input/index.js.map +1 -1
  15. package/lib/components/ai-native/thumbs/index.d.ts.map +1 -1
  16. package/lib/components/ai-native/thumbs/index.js +2 -2
  17. package/lib/components/ai-native/thumbs/index.js.map +1 -1
  18. package/lib/components/layout/default-layout.d.ts +7 -6
  19. package/lib/components/layout/default-layout.d.ts.map +1 -1
  20. package/lib/components/layout/default-layout.js +11 -5
  21. package/lib/components/layout/default-layout.js.map +1 -1
  22. package/lib/components/layout/split-panel.d.ts.map +1 -1
  23. package/lib/components/layout/split-panel.js +3 -1
  24. package/lib/components/layout/split-panel.js.map +1 -1
  25. package/lib/components/layout/split-panel.service.d.ts +4 -0
  26. package/lib/components/layout/split-panel.service.d.ts.map +1 -1
  27. package/lib/components/layout/split-panel.service.js +16 -0
  28. package/lib/components/layout/split-panel.service.js.map +1 -1
  29. package/lib/contextkey/ai-native.d.ts +1 -0
  30. package/lib/contextkey/ai-native.d.ts.map +1 -1
  31. package/lib/contextkey/ai-native.js +2 -1
  32. package/lib/contextkey/ai-native.js.map +1 -1
  33. package/lib/design/rule.d.ts +19 -10
  34. package/lib/design/rule.d.ts.map +1 -1
  35. package/lib/design/rule.js +22 -9
  36. package/lib/design/rule.js.map +1 -1
  37. package/lib/index.d.ts +1 -0
  38. package/lib/index.d.ts.map +1 -1
  39. package/lib/index.js +1 -1
  40. package/lib/index.js.map +1 -1
  41. package/lib/layout/constants.d.ts +11 -7
  42. package/lib/layout/constants.d.ts.map +1 -1
  43. package/lib/layout/constants.js +66 -36
  44. package/lib/layout/constants.js.map +1 -1
  45. package/lib/layout/index.d.ts +1 -0
  46. package/lib/layout/index.d.ts.map +1 -1
  47. package/lib/layout/index.js +1 -0
  48. package/lib/layout/index.js.map +1 -1
  49. package/lib/layout/render.d.ts +4 -0
  50. package/lib/layout/render.d.ts.map +1 -0
  51. package/lib/layout/render.js +10 -0
  52. package/lib/layout/render.js.map +1 -0
  53. package/lib/react-hooks/injectable-hooks.d.ts.map +1 -1
  54. package/lib/react-hooks/injectable-hooks.js +6 -2
  55. package/lib/react-hooks/injectable-hooks.js.map +1 -1
  56. package/lib/react-hooks/memorize-fn.d.ts +2 -0
  57. package/lib/react-hooks/memorize-fn.d.ts.map +1 -0
  58. package/lib/react-hooks/memorize-fn.js +11 -0
  59. package/lib/react-hooks/memorize-fn.js.map +1 -0
  60. package/package.json +5 -8
  61. package/src/ai-native/command.ts +8 -0
  62. package/src/bootstrap/app.ts +4 -0
  63. package/src/components/ai-native/enhanceIcon/index.tsx +8 -0
  64. package/src/components/ai-native/interactive-input/index.tsx +3 -0
  65. package/src/components/ai-native/thumbs/index.tsx +8 -0
  66. package/src/components/layout/default-layout.tsx +22 -4
  67. package/src/components/layout/split-panel.service.ts +16 -0
  68. package/src/components/layout/split-panel.tsx +4 -1
  69. package/src/contextkey/ai-native.ts +1 -0
  70. package/src/design/rule.ts +26 -10
  71. package/src/index.ts +1 -1
  72. package/src/layout/constants.ts +69 -37
  73. package/src/layout/index.ts +1 -0
  74. package/src/layout/render.tsx +14 -0
  75. package/src/react-hooks/injectable-hooks.tsx +7 -2
  76. package/src/react-hooks/memorize-fn.ts +7 -0
@@ -5,14 +5,26 @@ import { SlotRenderer } from '../../react-providers/slot';
5
5
  import { BoxPanel } from './box-panel';
6
6
  import { SplitPanel } from './split-panel';
7
7
 
8
+ export interface ILayoutConfigCache {
9
+ [key: string]: { size: number; currentId: string };
10
+ }
11
+
8
12
  export const getStorageValue = () => {
9
13
  // 启动时渲染的颜色和尺寸,弱依赖
10
- let savedLayout: { [key: string]: { size: number; currentId: string } } = {};
14
+ let savedLayout: ILayoutConfigCache = {};
11
15
  let savedColors: { [colorKey: string]: string } = {};
12
16
  try {
13
- savedLayout = JSON.parse(localStorage.getItem('layout') || '{}');
14
- savedColors = JSON.parse(localStorage.getItem('theme') || '{}');
17
+ const layoutConfigStr = localStorage.getItem('layout');
18
+ if (layoutConfigStr) {
19
+ savedLayout = JSON.parse(layoutConfigStr);
20
+ }
21
+
22
+ const themeConfigStr = localStorage.getItem('theme');
23
+ if (themeConfigStr) {
24
+ savedColors = JSON.parse(themeConfigStr);
25
+ }
15
26
  } catch (err) {}
27
+
16
28
  return {
17
29
  layout: savedLayout,
18
30
  colors: savedColors,
@@ -42,7 +54,13 @@ export function ToolbarActionBasedLayout(
42
54
  />
43
55
  <SplitPanel id='main-vertical' minResize={300} flexGrow={1} direction='top-to-bottom'>
44
56
  <SlotRenderer flex={2} flexGrow={1} minResize={200} slot='main' />
45
- <SlotRenderer flex={1} defaultSize={layout.bottom?.size} minResize={160} slot='bottom' isTabbar={true} />
57
+ <SlotRenderer
58
+ flex={1}
59
+ defaultSize={layout.bottom?.currentId ? layout.bottom?.size : 24}
60
+ minResize={160}
61
+ slot='bottom'
62
+ isTabbar={true}
63
+ />
46
64
  </SplitPanel>
47
65
  <SlotRenderer
48
66
  slot='right'
@@ -3,6 +3,7 @@ import React from 'react';
3
3
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
4
4
  import { Deferred, Disposable, IDisposable } from '@opensumi/ide-core-common';
5
5
 
6
+ import { AppConfig, SlotRenderer } from '../../react-providers';
6
7
  import { RESIZE_LOCK } from '../resize/resize';
7
8
 
8
9
  import { SplitPanelProps } from './split-panel';
@@ -19,12 +20,16 @@ export interface ISplitPanelService extends IDisposable {
19
20
  props: SplitPanelProps,
20
21
  ): React.ReactElement;
21
22
  interceptProps(props: SplitPanelProps): SplitPanelProps;
23
+ checkChildNoResize(child: React.ReactNode): boolean;
22
24
  setRootNode(node: HTMLElement): void;
23
25
  whenReady: Promise<void>;
24
26
  }
25
27
 
26
28
  @Injectable({ multiple: true })
27
29
  export class SplitPanelService extends Disposable implements ISplitPanelService {
30
+ @Autowired(AppConfig)
31
+ appConfig: AppConfig;
32
+
28
33
  constructor(protected readonly panelId: string) {
29
34
  super();
30
35
  }
@@ -82,6 +87,17 @@ export class SplitPanelService extends Disposable implements ISplitPanelService
82
87
  }
83
88
  }
84
89
 
90
+ checkChildNoResize(child: React.ReactNode) {
91
+ if (child && (child as React.ReactElement).type === SlotRenderer) {
92
+ // slot render must have modules
93
+ const modules = this.appConfig.layoutConfig[(child as React.ReactElement).props?.slot]?.modules;
94
+ if (!modules || modules.length === 0) {
95
+ return true;
96
+ }
97
+ }
98
+ return false;
99
+ }
100
+
85
101
  public renderSplitPanel(component: React.JSX.Element, children: React.ReactNode[], props: SplitPanelProps) {
86
102
  return React.cloneElement(component, { ...props, ...component.props }, children);
87
103
  }
@@ -247,7 +247,10 @@ export const SplitPanel: React.FC<SplitPanelProps> = (props) => {
247
247
  } else if (getProp(childList[index - 1], 'flexGrow')) {
248
248
  flexMode = ResizeFlexMode.Next;
249
249
  }
250
- const noResize = getProp(targetElement, 'noResize') || locks[index - 1];
250
+ const noResize =
251
+ splitPanelService.checkChildNoResize(targetElement) ||
252
+ getProp(targetElement, 'noResize') ||
253
+ locks[index - 1];
251
254
  if (!noResize) {
252
255
  result.push(
253
256
  <ResizeHandle
@@ -5,3 +5,4 @@ export const InlineCompletionIsTrigger = new RawContextKey('ai.native.inlineComp
5
5
  export const InlineHintWidgetIsVisible = new RawContextKey('ai.native.inlineHintWidgetIsVisible', false);
6
6
  export const InlineInputWidgetIsVisible = new RawContextKey('ai.native.inlineInputWidgetIsVisible', false);
7
7
  export const InlineDiffPartialEditsIsVisible = new RawContextKey('ai.native.inlineDiffPartialEditsIsVisible', false);
8
+ export const MultiLineCompletionsIsVisible = new RawContextKey('ai.native.multiLineCompletionsIsVisible', false);
@@ -1,35 +1,51 @@
1
1
  /**
2
2
  * 定义了 zIndex 的层级
3
3
  */
4
- export const StackingLevel = {
4
+ export const StackingLevel = Object.freeze({
5
5
  /**
6
6
  * 基础层级
7
7
  */
8
- Base: 0,
9
8
  Background: 0,
10
9
 
10
+ /**
11
+ * IDE 的主要内容区域,基础控件
12
+ */
11
13
  Workbench: 1,
12
- WorkbenchEditor: 1,
13
14
 
15
+ /**
16
+ * 顶部的工具栏
17
+ */
14
18
  Toolbar: 2,
15
19
 
16
- XtermDecoration: 8, // xterm.css 中 decoration 的 z-index 是 7,所以这里要比它大一点
20
+ /**
21
+ * xterm.css 中 decoration 的 z-index 是 7,所以这里要比它大一点
22
+ */
23
+ XtermDecoration: 8,
17
24
 
25
+ /**
26
+ * 顶部工具栏的下拉菜单
27
+ */
18
28
  ToolbarDropdown: 10,
19
29
 
30
+ EditorTabbarCurrent: 11,
31
+
20
32
  ResizeHandle: 12,
21
33
 
34
+ EditorTabbarOverlay: 15,
35
+
22
36
  EditorFloatingContainer: 20,
23
37
 
24
- /**
25
- * 一级弹窗
26
- */
38
+ // #region 中级弹窗区域
27
39
  Popup: 100,
28
- PopoverComponent: 1000,
29
- PopoverComponentArrow: 1001,
40
+ // #endregion
41
+
42
+ // #region 顶级弹窗区域
30
43
  Overlay: 800,
44
+ PopoverComponent: 999,
45
+ PopoverComponentArrow: 1000,
31
46
  OverlayTop: 1000,
32
- } as const;
47
+ // #endregion
48
+ } as const);
33
49
 
34
50
  export const StackingLevelStr = Object.fromEntries(
35
51
  Object.entries(StackingLevel).map(([key, value]) => [key, value.toString()]),
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- // 输出所有 common 里面会有的内容
2
1
  export * from '@opensumi/ide-core-common';
3
2
 
4
3
  // 输出当前 browser 特有的内容
@@ -45,3 +44,4 @@ export * from './markdown';
45
44
  export * from './extensions';
46
45
 
47
46
  export * from './static-resource';
47
+ export * from './context-key';
@@ -1,7 +1,7 @@
1
1
  import merge from 'lodash/merge';
2
2
 
3
3
  import { Injectable } from '@opensumi/di';
4
- import { IDesignLayoutConfig, isMacintosh } from '@opensumi/ide-core-common';
4
+ import { IDesignLayoutConfig, isDefined, isMacintosh } from '@opensumi/ide-core-common';
5
5
 
6
6
  import { electronEnv } from '../utils/electron';
7
7
 
@@ -25,15 +25,48 @@ export const DEFAULT_LAYOUT_VIEW_SIZE: ILayoutViewSize = {
25
25
  accordionHeaderSizeHeight: 24,
26
26
  };
27
27
 
28
+ export enum ConfigPriority {
29
+ ModuleDefined,
30
+ UserDefined,
31
+ }
32
+
33
+ /**
34
+ * 支持多档优先级配置
35
+ */
36
+ class ConfigAtom<T> {
37
+ /**
38
+ * index 越高,优先级越高
39
+ */
40
+ protected _value: (T | undefined)[] = [];
41
+ constructor(public defaultValue: T) {}
42
+
43
+ setValue(value: T | undefined, priority: number) {
44
+ this._value[priority] = value;
45
+ }
46
+
47
+ getValue(): T {
48
+ let value = this.defaultValue;
49
+
50
+ for (let i = this._value.length - 1; i >= 0; i--) {
51
+ if (isDefined(this._value[i])) {
52
+ value = this._value[i]!;
53
+ break;
54
+ }
55
+ }
56
+
57
+ return value;
58
+ }
59
+ }
60
+
28
61
  @Injectable()
29
62
  export class LayoutViewSizeConfig implements ILayoutViewSize {
30
- #menubarHeight: number;
31
- #editorTabsHeight: number;
32
- #bigSurTitleBarHeight: number;
33
- #titleBarHeight: number;
34
- #panelTitleBarHeight: number;
35
- #statusBarHeight: number;
36
- #accordionHeaderSizeHeight: number;
63
+ #menubarHeight = new ConfigAtom(DEFAULT_LAYOUT_VIEW_SIZE.menubarHeight);
64
+ #editorTabsHeight = new ConfigAtom(DEFAULT_LAYOUT_VIEW_SIZE.editorTabsHeight);
65
+ #bigSurTitleBarHeight = new ConfigAtom(DEFAULT_LAYOUT_VIEW_SIZE.bigSurTitleBarHeight);
66
+ #titleBarHeight = new ConfigAtom(DEFAULT_LAYOUT_VIEW_SIZE.titleBarHeight);
67
+ #panelTitleBarHeight = new ConfigAtom(DEFAULT_LAYOUT_VIEW_SIZE.panelTitleBarHeight);
68
+ #statusBarHeight = new ConfigAtom(DEFAULT_LAYOUT_VIEW_SIZE.statusBarHeight);
69
+ #accordionHeaderSizeHeight = new ConfigAtom(DEFAULT_LAYOUT_VIEW_SIZE.accordionHeaderSizeHeight);
37
70
 
38
71
  private inited = false;
39
72
  init(layoutViewSize: Partial<ILayoutViewSize> = {}) {
@@ -42,63 +75,62 @@ export class LayoutViewSizeConfig implements ILayoutViewSize {
42
75
  }
43
76
  this.inited = true;
44
77
 
45
- this.#menubarHeight = layoutViewSize.menubarHeight || DEFAULT_LAYOUT_VIEW_SIZE.menubarHeight;
46
- this.#editorTabsHeight = layoutViewSize.editorTabsHeight || DEFAULT_LAYOUT_VIEW_SIZE.editorTabsHeight;
47
- this.#bigSurTitleBarHeight = layoutViewSize.bigSurTitleBarHeight || DEFAULT_LAYOUT_VIEW_SIZE.bigSurTitleBarHeight;
48
- this.#titleBarHeight = layoutViewSize.titleBarHeight || DEFAULT_LAYOUT_VIEW_SIZE.titleBarHeight;
49
- this.#panelTitleBarHeight = layoutViewSize.panelTitleBarHeight || DEFAULT_LAYOUT_VIEW_SIZE.panelTitleBarHeight;
50
- this.#statusBarHeight = layoutViewSize.statusBarHeight || DEFAULT_LAYOUT_VIEW_SIZE.statusBarHeight;
51
- this.#accordionHeaderSizeHeight =
52
- layoutViewSize.accordionHeaderSizeHeight || DEFAULT_LAYOUT_VIEW_SIZE.accordionHeaderSizeHeight;
78
+ this.#menubarHeight.setValue(layoutViewSize.menubarHeight, ConfigPriority.UserDefined);
79
+ this.#editorTabsHeight.setValue(layoutViewSize.editorTabsHeight, ConfigPriority.UserDefined);
80
+ this.#bigSurTitleBarHeight.setValue(layoutViewSize.bigSurTitleBarHeight, ConfigPriority.UserDefined);
81
+ this.#titleBarHeight.setValue(layoutViewSize.titleBarHeight, ConfigPriority.UserDefined);
82
+ this.#panelTitleBarHeight.setValue(layoutViewSize.panelTitleBarHeight, ConfigPriority.UserDefined);
83
+ this.#statusBarHeight.setValue(layoutViewSize.statusBarHeight, ConfigPriority.UserDefined);
84
+ this.#accordionHeaderSizeHeight.setValue(layoutViewSize.accordionHeaderSizeHeight, ConfigPriority.UserDefined);
53
85
  }
54
86
 
55
87
  get menubarHeight(): number {
56
- return this.#menubarHeight;
88
+ return this.#menubarHeight.getValue();
57
89
  }
58
- setMenubarHeight(value: number) {
59
- this.#menubarHeight = value;
90
+ setMenubarHeight(value: number, priority?: number) {
91
+ this.#menubarHeight.setValue(value, priority ?? ConfigPriority.ModuleDefined);
60
92
  }
61
93
 
62
94
  get editorTabsHeight(): number {
63
- return this.#editorTabsHeight;
95
+ return this.#editorTabsHeight.getValue();
64
96
  }
65
- setEditorTabsHeight(value: number) {
66
- this.#editorTabsHeight = value;
97
+ setEditorTabsHeight(value: number, priority?: number) {
98
+ this.#editorTabsHeight.setValue(value, priority ?? ConfigPriority.ModuleDefined);
67
99
  }
68
100
 
69
101
  get bigSurTitleBarHeight(): number {
70
- return this.#bigSurTitleBarHeight;
102
+ return this.#bigSurTitleBarHeight.getValue();
71
103
  }
72
- setBigSurTitleBarHeight(value: number) {
73
- this.#bigSurTitleBarHeight = value;
104
+ setBigSurTitleBarHeight(value: number, priority?: number) {
105
+ this.#bigSurTitleBarHeight.setValue(value, priority ?? ConfigPriority.ModuleDefined);
74
106
  }
75
107
 
76
108
  get titleBarHeight(): number {
77
- return this.#titleBarHeight;
109
+ return this.#titleBarHeight.getValue();
78
110
  }
79
- setTitleBarHeight(value: number) {
80
- this.#titleBarHeight = value;
111
+ setTitleBarHeight(value: number, priority?: number) {
112
+ this.#titleBarHeight.setValue(value, priority ?? ConfigPriority.ModuleDefined);
81
113
  }
82
114
 
83
115
  get panelTitleBarHeight(): number {
84
- return this.#panelTitleBarHeight;
116
+ return this.#panelTitleBarHeight.getValue();
85
117
  }
86
- setPanelTitleBarHeight(value: number) {
87
- this.#panelTitleBarHeight = value;
118
+ setPanelTitleBarHeight(value: number, priority?: number) {
119
+ this.#panelTitleBarHeight.setValue(value, priority ?? ConfigPriority.ModuleDefined);
88
120
  }
89
121
 
90
122
  get statusBarHeight(): number {
91
- return this.#statusBarHeight;
123
+ return this.#statusBarHeight.getValue();
92
124
  }
93
- setStatusBarHeight(value: number) {
94
- this.#statusBarHeight = value;
125
+ setStatusBarHeight(value: number, priority?: number) {
126
+ this.#statusBarHeight.setValue(value, priority ?? ConfigPriority.ModuleDefined);
95
127
  }
96
128
 
97
129
  get accordionHeaderSizeHeight(): number {
98
- return this.#accordionHeaderSizeHeight;
130
+ return this.#accordionHeaderSizeHeight.getValue();
99
131
  }
100
- setAccordionHeaderSizeHeight(value: number) {
101
- this.#accordionHeaderSizeHeight = value;
132
+ setAccordionHeaderSizeHeight(value: number, priority?: number) {
133
+ this.#accordionHeaderSizeHeight.setValue(value, priority ?? ConfigPriority.ModuleDefined);
102
134
  }
103
135
 
104
136
  protected supportNewMacHeaderBar = electronEnv.osRelease ? parseFloat(electronEnv.osRelease) >= 20 : false;
@@ -3,3 +3,4 @@ export * from './layout-hooks';
3
3
  export * from './layout.interface';
4
4
  export * from './accordion/view-context-key.registry';
5
5
  export * from './accordion/tab-bar-toolbar';
6
+ export * from './render';
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import ReactIs from 'react-is';
3
+
4
+ import { ErrorBoundary } from '../react-providers';
5
+
6
+ import { View } from './layout.interface';
7
+
8
+ export const renderView = (view?: View) => (
9
+ <>
10
+ {view && ReactIs.isValidElementType(view.component) ? (
11
+ <ErrorBoundary>{view.component && React.createElement(view.component, view.initialProps)}</ErrorBoundary>
12
+ ) : null}
13
+ </>
14
+ );
@@ -5,6 +5,8 @@ import { Disposable } from '@opensumi/ide-core-common';
5
5
 
6
6
  import { ConfigContext } from '../react-providers/config-provider';
7
7
 
8
+ import { useMemorizeFn } from './memorize-fn';
9
+
8
10
  import type { EventEmitter } from '@opensumi/events';
9
11
 
10
12
  function isDisposable(target: any): target is Disposable {
@@ -43,12 +45,15 @@ export function useEventDrivenState<T, Events extends EventEmitter<any>, Event e
43
45
  eventName: Event,
44
46
  factory: (emitter: any) => T,
45
47
  ) {
46
- const [state, setState] = useState(factory(emitter));
48
+ const memorizeFactory = useMemorizeFn(factory);
49
+ const [state, setState] = useState(memorizeFactory(emitter));
47
50
 
48
51
  useEffect(() => {
49
52
  const listener = (...args: any[]) => {
50
- setState(factory(emitter));
53
+ setState(() => memorizeFactory(emitter));
51
54
  };
55
+ // 绑定事件前先取下值,避免期间事件已 emit
56
+ listener();
52
57
  emitter.on(eventName, listener);
53
58
  return () => emitter.off(eventName, listener);
54
59
  }, [emitter]);
@@ -0,0 +1,7 @@
1
+ import { useCallback, useMemo, useRef } from 'react';
2
+
3
+ export function useMemorizeFn<T extends (...args: any[]) => any>(fn: T) {
4
+ const fnRef = useRef<T>(fn);
5
+ fnRef.current = useMemo(() => fn, [fn]);
6
+ return useCallback((...args: any) => fnRef.current(...args), []) as T;
7
+ }