@opensumi/ide-editor 3.2.4 → 3.2.5-next-1724132734.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/editor-scrollbar/index.module.less +106 -0
- package/lib/browser/editor-scrollbar/inedx.d.ts +69 -0
- package/lib/browser/editor-scrollbar/inedx.d.ts.map +1 -0
- package/lib/browser/editor-scrollbar/inedx.js +289 -0
- package/lib/browser/editor-scrollbar/inedx.js.map +1 -0
- package/lib/browser/editor.module.less +3 -3
- package/lib/browser/editor.view.d.ts.map +1 -1
- package/lib/browser/editor.view.js +2 -12
- package/lib/browser/editor.view.js.map +1 -1
- package/lib/browser/grid/grid.service.d.ts +1 -0
- package/lib/browser/grid/grid.service.d.ts.map +1 -1
- package/lib/browser/grid/grid.service.js +6 -4
- package/lib/browser/grid/grid.service.js.map +1 -1
- package/lib/browser/navigation.module.less +3 -2
- package/lib/browser/navigation.view.js +1 -1
- package/lib/browser/navigation.view.js.map +1 -1
- package/lib/browser/tab.view.d.ts.map +1 -1
- package/lib/browser/tab.view.js +12 -3
- package/lib/browser/tab.view.js.map +1 -1
- package/lib/browser/workbench-editor.service.d.ts.map +1 -1
- package/lib/browser/workbench-editor.service.js +3 -2
- package/lib/browser/workbench-editor.service.js.map +1 -1
- package/lib/common/components.d.ts +3 -0
- package/lib/common/components.d.ts.map +1 -0
- package/lib/common/components.js +6 -0
- package/lib/common/components.js.map +1 -0
- package/lib/common/index.d.ts +1 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +1 -0
- package/lib/common/index.js.map +1 -1
- package/package.json +14 -14
- package/src/browser/editor-scrollbar/index.module.less +106 -0
- package/src/browser/editor-scrollbar/inedx.tsx +399 -0
- package/src/browser/editor.module.less +3 -3
- package/src/browser/editor.view.tsx +4 -21
- package/src/browser/grid/grid.service.ts +13 -7
- package/src/browser/navigation.module.less +3 -2
- package/src/browser/navigation.view.tsx +1 -1
- package/src/browser/tab.view.tsx +24 -6
- package/src/browser/workbench-editor.service.ts +7 -4
- package/src/common/components.ts +2 -0
- package/src/common/index.ts +1 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import cls from 'classnames';
|
|
2
|
+
import React, { MouseEvent, UIEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
import styles from './index.module.less';
|
|
5
|
+
|
|
6
|
+
export interface ScrollAreaProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
onScroll?: (position: ScrollPosition) => any;
|
|
9
|
+
atTopClassName?: string;
|
|
10
|
+
style?: any;
|
|
11
|
+
containerStyle?: any;
|
|
12
|
+
delegate?: (delegate: IScrollDelegate) => void;
|
|
13
|
+
|
|
14
|
+
forwardedRef: (ref: HTMLDivElement) => void;
|
|
15
|
+
|
|
16
|
+
children: any;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IScrollDelegate {
|
|
20
|
+
scrollTo(position: ScrollPosition): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ScrollPosition {
|
|
24
|
+
top: number;
|
|
25
|
+
left: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ScrollSizes {
|
|
29
|
+
scrollHeight: number;
|
|
30
|
+
offsetHeight: number;
|
|
31
|
+
offsetWidth: number;
|
|
32
|
+
scrollWidth: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class Scroll extends React.Component<ScrollAreaProps, any> {
|
|
36
|
+
public ref: HTMLDivElement;
|
|
37
|
+
|
|
38
|
+
public container: HTMLDivElement;
|
|
39
|
+
|
|
40
|
+
private thumbV!: HTMLDivElement;
|
|
41
|
+
|
|
42
|
+
private trackV!: HTMLDivElement;
|
|
43
|
+
|
|
44
|
+
private thumbH!: HTMLDivElement;
|
|
45
|
+
|
|
46
|
+
private trackH!: HTMLDivElement;
|
|
47
|
+
|
|
48
|
+
private decorationL: HTMLDivElement;
|
|
49
|
+
private decorationR: HTMLDivElement;
|
|
50
|
+
|
|
51
|
+
private size: ScrollSizes;
|
|
52
|
+
|
|
53
|
+
private position: ScrollPosition = {
|
|
54
|
+
top: 0,
|
|
55
|
+
left: 0,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
private dragging = false;
|
|
59
|
+
|
|
60
|
+
private draggingStart = 0;
|
|
61
|
+
|
|
62
|
+
private draggingStartPos = 0;
|
|
63
|
+
|
|
64
|
+
private requestFrame: any;
|
|
65
|
+
|
|
66
|
+
private shouldHideThumb = true;
|
|
67
|
+
|
|
68
|
+
private isAtTop = true;
|
|
69
|
+
|
|
70
|
+
onScroll(e: UIEvent<HTMLDivElement>) {
|
|
71
|
+
this.position = {
|
|
72
|
+
top: this.ref.scrollTop,
|
|
73
|
+
left: this.ref.scrollLeft,
|
|
74
|
+
};
|
|
75
|
+
if (this.props.onScroll) {
|
|
76
|
+
this.props.onScroll(this.position);
|
|
77
|
+
}
|
|
78
|
+
this.update(() => {
|
|
79
|
+
const contentWidth = this.ref.scrollWidth;
|
|
80
|
+
const width = this.ref.offsetWidth;
|
|
81
|
+
const contentHeight = this.ref.scrollHeight;
|
|
82
|
+
const height = this.ref.offsetHeight;
|
|
83
|
+
this.thumbH.style.left = (this.position.left * width) / contentWidth + 'px';
|
|
84
|
+
this.thumbV.style.top = (this.position.top * height) / contentHeight + 'px';
|
|
85
|
+
});
|
|
86
|
+
if (!this.isAtTop && this.ref.scrollTop === 0) {
|
|
87
|
+
this.isAtTop = true;
|
|
88
|
+
this.setCss();
|
|
89
|
+
} else if (this.isAtTop && this.ref.scrollTop !== 0) {
|
|
90
|
+
this.isAtTop = false;
|
|
91
|
+
this.setCss();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (this.ref.scrollLeft > 0) {
|
|
95
|
+
this.decorationL.style.opacity = String(1);
|
|
96
|
+
this.decorationR.style.opacity = String(1);
|
|
97
|
+
} else {
|
|
98
|
+
this.decorationL.style.opacity = String(0);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
this.ref.scrollWidth === this.ref.offsetWidth ||
|
|
103
|
+
this.ref.scrollLeft === this.ref.scrollWidth - this.ref.offsetWidth
|
|
104
|
+
) {
|
|
105
|
+
this.decorationR.style.opacity = String(0);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
scrollTo(position: ScrollPosition) {
|
|
110
|
+
this.ref.scrollLeft = position.left;
|
|
111
|
+
this.ref.scrollTop = position.top;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
onMouseDownHorizontal(e: MouseEvent<HTMLDivElement>) {
|
|
115
|
+
this.dragging = true;
|
|
116
|
+
if (e.target === this.trackH) {
|
|
117
|
+
this.onMouseDownOnTrack(e);
|
|
118
|
+
}
|
|
119
|
+
this.draggingStart = e.pageX;
|
|
120
|
+
this.draggingStartPos = this.ref.scrollLeft;
|
|
121
|
+
document.addEventListener('mousemove', this.onMouseMoveHorizontal);
|
|
122
|
+
document.addEventListener('mouseup', this.onMouseUpHorizontal);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
onMouseMoveHorizontal = (e) => {
|
|
126
|
+
if (!this.dragging) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const move = e.pageX - this.draggingStart;
|
|
130
|
+
this.ref.scrollLeft = this.draggingStartPos + this.calculateXToLeft(move);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
onMouseUpHorizontal = (e) => {
|
|
134
|
+
this.dragging = false;
|
|
135
|
+
document.removeEventListener('mousemove', this.onMouseMoveHorizontal);
|
|
136
|
+
document.removeEventListener('mouseup', this.onMouseUpHorizontal);
|
|
137
|
+
if (this.shouldHideThumb) {
|
|
138
|
+
this.hideThumb();
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
onMouseDownOnTrack(e: MouseEvent<HTMLDivElement>) {
|
|
143
|
+
const track = e.target as HTMLDivElement;
|
|
144
|
+
const x = e.clientX - track.getBoundingClientRect().left;
|
|
145
|
+
const contentWidth = this.ref.scrollWidth;
|
|
146
|
+
const width = this.ref.offsetWidth;
|
|
147
|
+
const left = (x * contentWidth) / width - 0.5 * width;
|
|
148
|
+
this.scrollTo({
|
|
149
|
+
left,
|
|
150
|
+
top: this.position.top,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
calculateXToLeft(x) {
|
|
155
|
+
const contentWidth = this.ref.scrollWidth;
|
|
156
|
+
const width = this.ref.offsetWidth;
|
|
157
|
+
return (x * contentWidth) / width;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
onMouseDownVertical(e: MouseEvent<HTMLDivElement>) {
|
|
161
|
+
this.dragging = true;
|
|
162
|
+
if (e.target === this.trackV) {
|
|
163
|
+
this.onMouseDownOnTrackVertical(e);
|
|
164
|
+
}
|
|
165
|
+
this.draggingStart = e.pageY;
|
|
166
|
+
this.draggingStartPos = this.ref.scrollTop;
|
|
167
|
+
document.addEventListener('mousemove', this.onMouseMoveVertical);
|
|
168
|
+
document.addEventListener('mouseup', this.onMouseUpVertical);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
onMouseMoveVertical = (e) => {
|
|
172
|
+
if (!this.dragging) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const move = e.pageY - this.draggingStart;
|
|
176
|
+
this.ref.scrollTop = this.draggingStartPos + this.calculateYToTop(move);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
onMouseUpVertical = (e) => {
|
|
180
|
+
this.dragging = false;
|
|
181
|
+
document.removeEventListener('mousemove', this.onMouseMoveVertical);
|
|
182
|
+
document.removeEventListener('mouseup', this.onMouseUpVertical);
|
|
183
|
+
if (this.shouldHideThumb) {
|
|
184
|
+
this.hideThumb();
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
onMouseDownOnTrackVertical(e: MouseEvent<HTMLDivElement>) {
|
|
189
|
+
const track = e.target as HTMLDivElement;
|
|
190
|
+
const x = e.clientY - track.getBoundingClientRect().top;
|
|
191
|
+
const contentHeight = this.ref.scrollHeight;
|
|
192
|
+
const height = this.ref.offsetHeight;
|
|
193
|
+
const top = (x * contentHeight) / height - 0.5 * height;
|
|
194
|
+
this.scrollTo({
|
|
195
|
+
left: this.position.left,
|
|
196
|
+
top,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
onMousewheel = (e: WheelEvent) => {
|
|
201
|
+
// 鼠标滚动滚轮只在有横向滚动条的情况下
|
|
202
|
+
// 页面有缩放的时候,scrollHeight 可能会小于 clientHeight / offsetHeight
|
|
203
|
+
if (this.ref.clientHeight >= this.ref.scrollHeight) {
|
|
204
|
+
if (e.deltaY !== 0) {
|
|
205
|
+
// scrollLeft 内部有边界判断
|
|
206
|
+
this.ref.scrollLeft += e.deltaY;
|
|
207
|
+
}
|
|
208
|
+
if (e.deltaX !== 0) {
|
|
209
|
+
this.ref.scrollLeft += e.deltaX;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
calculateYToTop(y) {
|
|
215
|
+
const contentHeight = this.ref.scrollHeight;
|
|
216
|
+
const height = this.ref.offsetHeight;
|
|
217
|
+
return (y * contentHeight) / height;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
componentDidUpdate() {
|
|
221
|
+
this.update();
|
|
222
|
+
if (this.props.delegate) {
|
|
223
|
+
this.props.delegate({
|
|
224
|
+
scrollTo: this.scrollTo.bind(this),
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
componentDidMount() {
|
|
230
|
+
this.update();
|
|
231
|
+
window.addEventListener('resize', this.handleWindowResize);
|
|
232
|
+
if (this.props.delegate) {
|
|
233
|
+
this.props.delegate({
|
|
234
|
+
scrollTo: this.scrollTo.bind(this),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
if (this.ref) {
|
|
238
|
+
this.ref.addEventListener('mouseenter', this.onMouseEnter);
|
|
239
|
+
this.ref.addEventListener('wheel', this.onMousewheel);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
onMouseEnter = () => {
|
|
244
|
+
this.update();
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
componentWillUnmount() {
|
|
248
|
+
if (this.ref) {
|
|
249
|
+
this.ref.removeEventListener('mouseenter', this.onMouseEnter);
|
|
250
|
+
this.ref.addEventListener('wheel', this.onMousewheel);
|
|
251
|
+
}
|
|
252
|
+
window.removeEventListener('resize', this.handleWindowResize);
|
|
253
|
+
if (this.requestFrame) {
|
|
254
|
+
window.cancelAnimationFrame(this.requestFrame);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
handleWindowResize = () => {
|
|
259
|
+
this.update();
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
sizeEqual(size1: ScrollSizes, size2: ScrollSizes): boolean {
|
|
263
|
+
return (
|
|
264
|
+
size1 &&
|
|
265
|
+
size2 &&
|
|
266
|
+
size1.offsetHeight === size2.offsetHeight &&
|
|
267
|
+
size1.scrollHeight === size2.scrollHeight &&
|
|
268
|
+
size1.offsetWidth === size2.offsetWidth &&
|
|
269
|
+
size1.scrollWidth === size2.scrollWidth
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
update = (callback?) => {
|
|
274
|
+
if (this.requestFrame) {
|
|
275
|
+
window.cancelAnimationFrame(this.requestFrame);
|
|
276
|
+
}
|
|
277
|
+
this.requestFrame = window.requestAnimationFrame(() => {
|
|
278
|
+
this._update();
|
|
279
|
+
if (callback) {
|
|
280
|
+
callback();
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
_update() {
|
|
286
|
+
if (this.ref) {
|
|
287
|
+
if (!this.sizeEqual(this.size, this.ref)) {
|
|
288
|
+
this.size = {
|
|
289
|
+
offsetHeight: this.ref.offsetHeight,
|
|
290
|
+
offsetWidth: this.ref.offsetWidth,
|
|
291
|
+
scrollWidth: this.ref.scrollWidth,
|
|
292
|
+
scrollHeight: this.ref.scrollHeight,
|
|
293
|
+
};
|
|
294
|
+
this.updateScrollBar();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
updateScrollBar() {
|
|
300
|
+
const contentWidth = this.ref.scrollWidth;
|
|
301
|
+
const width = this.ref.offsetWidth;
|
|
302
|
+
if (width < contentWidth) {
|
|
303
|
+
const thumbHWidth = (width * width) / contentWidth;
|
|
304
|
+
this.thumbH.style.width = thumbHWidth + 'px';
|
|
305
|
+
this.trackH.parentElement!.style.display = 'block';
|
|
306
|
+
} else {
|
|
307
|
+
this.trackH.parentElement!.style.display = 'none';
|
|
308
|
+
}
|
|
309
|
+
const contentHeight = this.ref.scrollHeight;
|
|
310
|
+
const height = this.ref.offsetHeight;
|
|
311
|
+
if (height < contentHeight) {
|
|
312
|
+
this.thumbV.style.height = (height * height) / contentHeight + 'px';
|
|
313
|
+
this.trackV.parentElement!.style.display = 'block';
|
|
314
|
+
} else {
|
|
315
|
+
this.trackV.parentElement!.style.display = 'none';
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
hideThumb() {
|
|
320
|
+
this.shouldHideThumb = true;
|
|
321
|
+
if (!this.dragging) {
|
|
322
|
+
this.setCss();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
showThumb() {
|
|
327
|
+
this.shouldHideThumb = false;
|
|
328
|
+
this.setCss();
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
setCss() {
|
|
332
|
+
this.container.className = cls({
|
|
333
|
+
[styles.scroll]: true,
|
|
334
|
+
[styles['hide-thumb']]: this.shouldHideThumb && !this.dragging,
|
|
335
|
+
});
|
|
336
|
+
const clses = {};
|
|
337
|
+
if (this.props.atTopClassName) {
|
|
338
|
+
clses[this.props.atTopClassName] = this.isAtTop;
|
|
339
|
+
}
|
|
340
|
+
if (this.props.className) {
|
|
341
|
+
clses[this.props.className] = true;
|
|
342
|
+
}
|
|
343
|
+
this.ref.className = cls(clses);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
render() {
|
|
347
|
+
return (
|
|
348
|
+
<div
|
|
349
|
+
className={cls(styles.scroll, styles['hide-thumb'])}
|
|
350
|
+
ref={(e) => {
|
|
351
|
+
if (e) {
|
|
352
|
+
this.container = e;
|
|
353
|
+
this.props.forwardedRef(e);
|
|
354
|
+
}
|
|
355
|
+
}}
|
|
356
|
+
onMouseMove={() => this.showThumb()}
|
|
357
|
+
onMouseLeave={() => this.hideThumb()}
|
|
358
|
+
style={this.props.containerStyle}
|
|
359
|
+
>
|
|
360
|
+
<div
|
|
361
|
+
style={this.props.style}
|
|
362
|
+
className={cls(this.props.className)}
|
|
363
|
+
onScroll={this.onScroll.bind(this)}
|
|
364
|
+
ref={(e) => e && (this.ref = e)}
|
|
365
|
+
onMouseDown={() => this.update()}
|
|
366
|
+
onMouseUp={() => this.update()}
|
|
367
|
+
>
|
|
368
|
+
{this.props.children}
|
|
369
|
+
</div>
|
|
370
|
+
<div className={styles['scrollbar-decoration-vertical-l']} ref={(e) => e && (this.decorationL = e)} />
|
|
371
|
+
<div className={styles['scrollbar-decoration-vertical-r']} ref={(e) => e && (this.decorationR = e)} />
|
|
372
|
+
<div className={styles['scroll-horizontal']}>
|
|
373
|
+
<div
|
|
374
|
+
className={styles['track-horizontal']}
|
|
375
|
+
ref={(e) => e && (this.trackH = e)}
|
|
376
|
+
onMouseDown={this.onMouseDownHorizontal.bind(this)}
|
|
377
|
+
/>
|
|
378
|
+
<div
|
|
379
|
+
className={'thumb-horizontal'}
|
|
380
|
+
onMouseDown={this.onMouseDownHorizontal.bind(this)}
|
|
381
|
+
ref={(e) => e && (this.thumbH = e)}
|
|
382
|
+
/>
|
|
383
|
+
</div>
|
|
384
|
+
<div className={styles['scroll-vertical']}>
|
|
385
|
+
<div
|
|
386
|
+
className={styles['track-vertical']}
|
|
387
|
+
ref={(e) => e && (this.trackV = e)}
|
|
388
|
+
onMouseDown={this.onMouseDownVertical.bind(this)}
|
|
389
|
+
/>
|
|
390
|
+
<div
|
|
391
|
+
className={'thumb-vertical'}
|
|
392
|
+
onMouseDown={this.onMouseDownVertical.bind(this)}
|
|
393
|
+
ref={(e) => e && (this.thumbV = e)}
|
|
394
|
+
/>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
@@ -304,7 +304,7 @@
|
|
|
304
304
|
position: relative;
|
|
305
305
|
background: var(--tab-activeBackground);
|
|
306
306
|
color: var(--tab-activeForeground);
|
|
307
|
-
z-index: 11;
|
|
307
|
+
z-index: var(--stacking-level-editor-tabbar-current, 11);
|
|
308
308
|
&::before {
|
|
309
309
|
position: absolute;
|
|
310
310
|
content: '';
|
|
@@ -312,7 +312,7 @@
|
|
|
312
312
|
width: 100%;
|
|
313
313
|
top: -1px;
|
|
314
314
|
left: 0;
|
|
315
|
-
z-index:
|
|
315
|
+
z-index: var(--stacking-level-popover-component, 1000);
|
|
316
316
|
background-color: var(--tab-activeBorderTop);
|
|
317
317
|
}
|
|
318
318
|
.dirty {
|
|
@@ -489,7 +489,7 @@
|
|
|
489
489
|
.overlay-shadow();
|
|
490
490
|
border-radius: 2px;
|
|
491
491
|
padding: 5px 10px;
|
|
492
|
-
z-index:
|
|
492
|
+
z-index: var(--stacking-level-overlay-top, 1000);
|
|
493
493
|
white-space: nowrap;
|
|
494
494
|
.editor_action_tip_close {
|
|
495
495
|
cursor: pointer;
|
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
PreferenceService,
|
|
18
18
|
URI,
|
|
19
19
|
View,
|
|
20
|
+
renderView,
|
|
20
21
|
useDesignStyles,
|
|
21
22
|
useDisposable,
|
|
23
|
+
usePreference,
|
|
22
24
|
} from '@opensumi/ide-core-browser';
|
|
23
25
|
import {
|
|
24
26
|
IResizeHandleDelegate,
|
|
@@ -241,7 +243,6 @@ const EditorEmptyComponent: React.FC<{
|
|
|
241
243
|
export const EditorGroupView = observer(({ group }: { group: EditorGroup }) => {
|
|
242
244
|
const groupWrapperRef = React.useRef<HTMLElement | null>();
|
|
243
245
|
|
|
244
|
-
const preferenceService = useInjectable(PreferenceService) as PreferenceService;
|
|
245
246
|
const [isEmpty, setIsEmpty] = React.useState(group.resources.length === 0);
|
|
246
247
|
const styles_kt_editor_group = useDesignStyles(styles.kt_editor_group, 'kt_editor_group');
|
|
247
248
|
|
|
@@ -263,20 +264,7 @@ export const EditorGroupView = observer(({ group }: { group: EditorGroup }) => {
|
|
|
263
264
|
};
|
|
264
265
|
}, []);
|
|
265
266
|
|
|
266
|
-
const
|
|
267
|
-
() => !!preferenceService.get<boolean>('editor.showActionWhenGroupEmpty'),
|
|
268
|
-
);
|
|
269
|
-
|
|
270
|
-
useDisposable(
|
|
271
|
-
() => [
|
|
272
|
-
preferenceService.onPreferenceChanged((change) => {
|
|
273
|
-
if (change.preferenceName === 'editor.showActionWhenGroupEmpty') {
|
|
274
|
-
setShowActionWhenGroupEmpty(!!change.newValue);
|
|
275
|
-
}
|
|
276
|
-
}),
|
|
277
|
-
],
|
|
278
|
-
[],
|
|
279
|
-
);
|
|
267
|
+
const showActionWhenGroupEmpty = usePreference('editor.showActionWhenGroupEmpty', false);
|
|
280
268
|
|
|
281
269
|
const componentRegistry = useInjectable<ComponentRegistry>(ComponentRegistry);
|
|
282
270
|
|
|
@@ -314,12 +302,7 @@ export const EditorGroupView = observer(({ group }: { group: EditorGroup }) => {
|
|
|
314
302
|
backgroundImage: !EmptyEditorViewConfig && editorBackgroundImage ? `url(${editorBackgroundImage})` : 'none',
|
|
315
303
|
}}
|
|
316
304
|
>
|
|
317
|
-
{
|
|
318
|
-
<ErrorBoundary>
|
|
319
|
-
{EmptyEditorViewConfig.component &&
|
|
320
|
-
React.createElement(EmptyEditorViewConfig.component, EmptyEditorViewConfig.initialProps)}
|
|
321
|
-
</ErrorBoundary>
|
|
322
|
-
) : null}
|
|
305
|
+
{renderView(EmptyEditorViewConfig)}
|
|
323
306
|
</div>
|
|
324
307
|
)}
|
|
325
308
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Emitter, IDisposable, IEventBus, MaybeNull } from '@opensumi/ide-core-browser';
|
|
2
|
-
import { makeRandomHexString } from '@opensumi/ide-core-common';
|
|
2
|
+
import { DisposableStore, makeRandomHexString } from '@opensumi/ide-core-common';
|
|
3
3
|
|
|
4
4
|
import { Direction, IEditorGroup, IEditorGroupState } from '../../common';
|
|
5
5
|
import { GridResizeEvent } from '../types';
|
|
@@ -7,17 +7,19 @@ import { GridResizeEvent } from '../types';
|
|
|
7
7
|
export const editorGridUid = new Set();
|
|
8
8
|
|
|
9
9
|
export class EditorGrid implements IDisposable {
|
|
10
|
+
private _disposables = new DisposableStore();
|
|
11
|
+
|
|
10
12
|
public editorGroup: IGridEditorGroup | null = null;
|
|
11
13
|
|
|
12
14
|
public children: EditorGrid[] = [];
|
|
13
15
|
|
|
14
16
|
public splitDirection: SplitDirection | undefined;
|
|
15
17
|
|
|
16
|
-
protected readonly _onDidGridStateChange = new Emitter<void>();
|
|
18
|
+
protected readonly _onDidGridStateChange = this._disposables.add(new Emitter<void>());
|
|
17
19
|
|
|
18
20
|
public readonly onDidGridStateChange = this._onDidGridStateChange.event;
|
|
19
21
|
|
|
20
|
-
protected readonly _onDidGridAndDesendantStateChange = new Emitter<void>();
|
|
22
|
+
protected readonly _onDidGridAndDesendantStateChange = this._disposables.add(new Emitter<void>());
|
|
21
23
|
|
|
22
24
|
public readonly onDidGridAndDesendantStateChange = this._onDidGridAndDesendantStateChange.event;
|
|
23
25
|
|
|
@@ -30,10 +32,12 @@ export class EditorGrid implements IDisposable {
|
|
|
30
32
|
}
|
|
31
33
|
this.uid = uid;
|
|
32
34
|
editorGridUid.add(uid);
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
this._disposables.add(
|
|
36
|
+
this.onDidGridStateChange(() => {
|
|
37
|
+
this._onDidGridAndDesendantStateChange.fire();
|
|
38
|
+
this.parent?._onDidGridAndDesendantStateChange.fire();
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
setEditorGroup(editorGroup: IGridEditorGroup) {
|
|
@@ -106,6 +110,8 @@ export class EditorGrid implements IDisposable {
|
|
|
106
110
|
} else {
|
|
107
111
|
// 应该不会落入这里
|
|
108
112
|
}
|
|
113
|
+
|
|
114
|
+
this._disposables.dispose();
|
|
109
115
|
}
|
|
110
116
|
|
|
111
117
|
public replaceBy(target: EditorGrid) {
|
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.navigation_icon {
|
|
18
|
-
font-size: 12px;
|
|
18
|
+
font-size: 12px !important;
|
|
19
19
|
color: var(--breadcrumb-foreground);
|
|
20
20
|
}
|
|
21
|
+
|
|
21
22
|
.navigation-part {
|
|
22
23
|
color: var(--breadcrumb-foreground);
|
|
23
|
-
font-size: 12px;
|
|
24
|
+
font-size: 12px !important;
|
|
24
25
|
padding: 0 4px;
|
|
25
26
|
position: relative;
|
|
26
27
|
line-height: 22px;
|
|
@@ -56,7 +56,7 @@ export const NavigationBar = ({ editorGroup }: { editorGroup: EditorGroup }) =>
|
|
|
56
56
|
}
|
|
57
57
|
return parts.length === 0 ? null : (
|
|
58
58
|
<div
|
|
59
|
-
className={styles_navigation_container}
|
|
59
|
+
className={cls('kt-navigation-container', styles_navigation_container)}
|
|
60
60
|
onContextMenu={(event) => {
|
|
61
61
|
event.preventDefault();
|
|
62
62
|
}}
|
package/src/browser/tab.view.tsx
CHANGED
|
@@ -13,8 +13,8 @@ import React, {
|
|
|
13
13
|
useState,
|
|
14
14
|
} from 'react';
|
|
15
15
|
|
|
16
|
-
import { Scrollbars } from '@opensumi/ide-components';
|
|
17
16
|
import {
|
|
17
|
+
ComponentRegistry,
|
|
18
18
|
ConfigContext,
|
|
19
19
|
Disposable,
|
|
20
20
|
DisposableCollection,
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
getExternalIcon,
|
|
30
30
|
getIcon,
|
|
31
31
|
getSlotLocation,
|
|
32
|
+
renderView,
|
|
32
33
|
useDesignStyles,
|
|
33
34
|
} from '@opensumi/ide-core-browser';
|
|
34
35
|
import { InlineMenuBar } from '@opensumi/ide-core-browser/lib/components/actions';
|
|
@@ -37,8 +38,16 @@ import { VIEW_CONTAINERS } from '@opensumi/ide-core-browser/lib/layout/view-id';
|
|
|
37
38
|
import { IMenuRegistry, MenuId } from '@opensumi/ide-core-browser/lib/menu/next';
|
|
38
39
|
import { useInjectable, useUpdateOnEventBusEvent } from '@opensumi/ide-core-browser/lib/react-hooks';
|
|
39
40
|
|
|
40
|
-
import {
|
|
41
|
-
|
|
41
|
+
import {
|
|
42
|
+
IEditorGroup,
|
|
43
|
+
IResource,
|
|
44
|
+
ResourceDidUpdateEvent,
|
|
45
|
+
ResourceService,
|
|
46
|
+
TabbarRightExtraContentId,
|
|
47
|
+
WorkbenchEditorService,
|
|
48
|
+
} from '../common';
|
|
49
|
+
|
|
50
|
+
import { Scroll } from './editor-scrollbar/inedx';
|
|
42
51
|
import styles from './editor.module.less';
|
|
43
52
|
import { TabTitleMenuService } from './menu/title-context.menu';
|
|
44
53
|
import {
|
|
@@ -72,6 +81,7 @@ export const Tabs = ({ group }: ITabsProps) => {
|
|
|
72
81
|
const menuRegistry = useInjectable<IMenuRegistry>(IMenuRegistry);
|
|
73
82
|
const editorTabService = useInjectable<IEditorTabService>(IEditorTabService);
|
|
74
83
|
const layoutViewSize = useInjectable<LayoutViewSizeConfig>(LayoutViewSizeConfig);
|
|
84
|
+
const componentRegistry = useInjectable<ComponentRegistry>(ComponentRegistry);
|
|
75
85
|
|
|
76
86
|
const styles_tab_right = useDesignStyles(styles.tab_right, 'tab_right');
|
|
77
87
|
const styles_close_tab = useDesignStyles(styles.close_tab, 'close_tab');
|
|
@@ -105,6 +115,13 @@ export const Tabs = ({ group }: ITabsProps) => {
|
|
|
105
115
|
|
|
106
116
|
const slotLocation = useMemo(() => getSlotLocation(pkgName, configContext.layoutConfig), []);
|
|
107
117
|
|
|
118
|
+
const RightExtraContentViewConfig = React.useMemo(() => {
|
|
119
|
+
const firstView = componentRegistry.getComponentRegistryInfo(TabbarRightExtraContentId)?.views?.[0];
|
|
120
|
+
if (firstView) {
|
|
121
|
+
return firstView;
|
|
122
|
+
}
|
|
123
|
+
}, []);
|
|
124
|
+
|
|
108
125
|
useUpdateOnGroupTabChange(group);
|
|
109
126
|
useUpdateOnEventBusEvent(
|
|
110
127
|
ResourceDidUpdateEvent,
|
|
@@ -492,18 +509,19 @@ export const Tabs = ({ group }: ITabsProps) => {
|
|
|
492
509
|
onDoubleClick={handleEmptyDBClick}
|
|
493
510
|
>
|
|
494
511
|
{!wrapMode ? (
|
|
495
|
-
<
|
|
496
|
-
tabBarMode
|
|
512
|
+
<Scroll
|
|
497
513
|
forwardedRef={(el) => (el ? (tabContainer.current = el) : null)}
|
|
498
514
|
className={styles.kt_editor_tabs_scroll}
|
|
499
515
|
>
|
|
500
516
|
{renderTabContent()}
|
|
501
|
-
</
|
|
517
|
+
</Scroll>
|
|
502
518
|
) : (
|
|
503
519
|
<div className={styles.kt_editor_wrap_container}>{renderTabContent()}</div>
|
|
504
520
|
)}
|
|
505
521
|
</div>
|
|
506
522
|
{!wrapMode && <EditorActions ref={editorActionRef} group={group} />}
|
|
523
|
+
|
|
524
|
+
{renderView(RightExtraContentViewConfig)}
|
|
507
525
|
</div>
|
|
508
526
|
);
|
|
509
527
|
};
|
|
@@ -491,10 +491,13 @@ export class WorkbenchEditorServiceImpl extends WithEventBus implements Workbenc
|
|
|
491
491
|
state = this.openedResourceState.get<IEditorGridState>('grid', state);
|
|
492
492
|
}
|
|
493
493
|
this.topGrid = new EditorGrid();
|
|
494
|
-
this.topGrid
|
|
495
|
-
|
|
496
|
-
this.
|
|
497
|
-
|
|
494
|
+
this.addDispose(this.topGrid);
|
|
495
|
+
this.addDispose(
|
|
496
|
+
this.topGrid.onDidGridAndDesendantStateChange(() => {
|
|
497
|
+
this._sortedEditorGroups = undefined;
|
|
498
|
+
this._onDidEditorGroupsChanged.fire();
|
|
499
|
+
}),
|
|
500
|
+
);
|
|
498
501
|
const editorRestorePromises = [];
|
|
499
502
|
const promise = this.topGrid
|
|
500
503
|
.deserialize(state, () => this.createEditorGroup(), editorRestorePromises)
|
package/src/common/index.ts
CHANGED