@theia/core 1.37.0 → 1.37.2

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 (57) hide show
  1. package/README.md +6 -6
  2. package/lib/browser/common-frontend-contribution.js +3 -3
  3. package/lib/browser/common-frontend-contribution.js.map +1 -1
  4. package/lib/browser/core-preferences.js +1 -1
  5. package/lib/browser/core-preferences.js.map +1 -1
  6. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts +2 -0
  7. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts.map +1 -1
  8. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js +23 -8
  9. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js.map +1 -1
  10. package/lib/browser/shell/tab-bars.d.ts +33 -24
  11. package/lib/browser/shell/tab-bars.d.ts.map +1 -1
  12. package/lib/browser/shell/tab-bars.js +90 -45
  13. package/lib/browser/shell/tab-bars.js.map +1 -1
  14. package/lib/browser/view-container.d.ts +10 -0
  15. package/lib/browser/view-container.d.ts.map +1 -1
  16. package/lib/browser/view-container.js +15 -1
  17. package/lib/browser/view-container.js.map +1 -1
  18. package/lib/browser/widgets/select-component.d.ts +4 -2
  19. package/lib/browser/widgets/select-component.d.ts.map +1 -1
  20. package/lib/browser/widgets/select-component.js +14 -11
  21. package/lib/browser/widgets/select-component.js.map +1 -1
  22. package/lib/common/command.d.ts +1 -0
  23. package/lib/common/command.d.ts.map +1 -1
  24. package/lib/common/command.js.map +1 -1
  25. package/lib/common/index.d.ts +1 -0
  26. package/lib/common/index.d.ts.map +1 -1
  27. package/lib/common/index.js +1 -0
  28. package/lib/common/index.js.map +1 -1
  29. package/lib/common/objects.d.ts +1 -0
  30. package/lib/common/objects.d.ts.map +1 -1
  31. package/lib/common/objects.js +43 -1
  32. package/lib/common/objects.js.map +1 -1
  33. package/lib/common/severity.js +1 -1
  34. package/lib/common/severity.js.map +1 -1
  35. package/lib/common/telemetry.d.ts +20 -0
  36. package/lib/common/telemetry.d.ts.map +1 -0
  37. package/lib/common/telemetry.js +25 -0
  38. package/lib/common/telemetry.js.map +1 -0
  39. package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +5 -0
  40. package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
  41. package/lib/electron-browser/menu/electron-main-menu-factory.js +4 -3
  42. package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
  43. package/package.json +6 -6
  44. package/src/browser/common-frontend-contribution.ts +3 -3
  45. package/src/browser/core-preferences.ts +1 -1
  46. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.tsx +23 -6
  47. package/src/browser/shell/tab-bars.ts +107 -63
  48. package/src/browser/style/tabs.css +67 -7
  49. package/src/browser/view-container.ts +21 -0
  50. package/src/browser/widgets/select-component.tsx +21 -13
  51. package/src/common/command.ts +1 -0
  52. package/src/common/i18n/nls.metadata.json +16592 -14032
  53. package/src/common/index.ts +1 -0
  54. package/src/common/objects.ts +48 -1
  55. package/src/common/severity.ts +1 -1
  56. package/src/common/telemetry.ts +45 -0
  57. package/src/electron-browser/menu/electron-main-menu-factory.ts +10 -3
@@ -22,8 +22,6 @@
22
22
  }
23
23
 
24
24
  .p-TabBar[data-orientation='horizontal'] {
25
- overflow-x: hidden;
26
- overflow-y: hidden;
27
25
  min-height: var(--theia-horizontal-toolbar-height);
28
26
  }
29
27
 
@@ -38,6 +36,7 @@
38
36
  line-height: var(--theia-private-horizontal-tab-height);
39
37
  padding: 0px 8px;
40
38
  align-items: center;
39
+ overflow: hidden;
41
40
  }
42
41
 
43
42
  .p-TabBar[data-orientation='vertical'] .p-TabBar-tab {
@@ -215,7 +214,19 @@
215
214
  -ms-user-select: none;
216
215
  }
217
216
 
218
- .p-TabBar.theia-app-centers .p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon:hover {
217
+ .p-TabBar.theia-app-centers.dynamic-tabs .p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon,
218
+ .p-TabBar.theia-app-centers.dynamic-tabs .p-TabBar-tab.theia-mod-pinned > .p-TabBar-tabCloseIcon {
219
+ /* hide close icon for dynamic tabs strategy*/
220
+ display: none;
221
+ }
222
+
223
+ .p-TabBar.theia-app-centers .p-TabBar-tab.p-mod-current > .p-TabBar-tabCloseIcon,
224
+ .p-TabBar.theia-app-centers .p-TabBar-tab:hover.p-mod-closable > .p-TabBar-tabCloseIcon,
225
+ .p-TabBar.theia-app-centers .p-TabBar-tab:hover.theia-mod-pinned > .p-TabBar-tabCloseIcon {
226
+ display: inline-block;
227
+ }
228
+
229
+ .p-TabBar.theia-app-centers .p-TabBar-tab:hover.p-mod-closable > .p-TabBar-tabCloseIcon {
219
230
  border-radius: 5px;
220
231
  background-color: rgba(50%, 50%, 50%, 0.2);
221
232
  }
@@ -303,6 +314,15 @@
303
314
  bottom: calc((var(--theia-private-horizontal-tab-scrollbar-rail-height) - var(--theia-private-horizontal-tab-scrollbar-height)) / 2);
304
315
  }
305
316
 
317
+ .p-TabBar[data-orientation='vertical'] .p-TabBar-content-container > .ps__rail-y {
318
+ width: var(--theia-private-horizontal-tab-scrollbar-rail-height);
319
+ z-index: 1000;
320
+ }
321
+
322
+ .p-TabBar[data-orientation='vertical'] .p-TabBar-content-container > .ps__rail-y > .ps__thumb-y {
323
+ width: var(--theia-private-horizontal-tab-scrollbar-height) !important;
324
+ right: calc((var(--theia-private-horizontal-tab-scrollbar-rail-height) - var(--theia-private-horizontal-tab-scrollbar-height)) / 2);
325
+ }
306
326
 
307
327
  /*-----------------------------------------------------------------------------
308
328
  | Dragged tabs
@@ -405,18 +425,36 @@
405
425
  flex-direction: column;
406
426
  }
407
427
 
408
- .theia-tabBar-tab-row {
428
+ .p-TabBar[data-orientation='horizontal'] .theia-tabBar-tab-row {
409
429
  display: flex;
410
430
  flex-flow: row nowrap;
411
431
  min-width: 100%;
412
432
  }
413
433
 
414
- .p-TabBar-tab .theia-tab-icon-label {
434
+ .p-TabBar[data-orientation='vertical'] .theia-tabBar-tab-row {
435
+ display: flex;
436
+ flex-flow: column nowrap;
437
+ height: 100%;
438
+ }
439
+
440
+ .p-TabBar[data-orientation='horizontal'] .p-TabBar-content {
441
+ flex-direction: row;
442
+ }
443
+
444
+ .p-TabBar[data-orientation='vertical'] .p-TabBar-content {
445
+ flex-direction: column;
446
+ }
447
+
448
+ .p-TabBar.theia-app-centers[data-orientation='horizontal'].dynamic-tabs .p-TabBar-tabLabel {
449
+ /* fade out text with dynamic tabs strategy */
450
+ mask-image: linear-gradient(to left, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 1) 15px);
451
+ -webkit-mask-image: linear-gradient(to left, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 1) 15px);
415
452
  flex: 1;
416
453
  }
417
454
 
418
- .p-TabBar[data-orientation='horizontal'] .p-TabBar-tab.p-mod-closable:hover .theia-tab-icon-label,
419
- .p-TabBar[data-orientation='horizontal'] .p-TabBar-tab.p-mod-current .theia-tab-icon-label {
455
+
456
+ .p-TabBar[data-orientation='horizontal'] .p-TabBar-tab .theia-tab-icon-label {
457
+ flex: 1;
420
458
  overflow: hidden;
421
459
  }
422
460
 
@@ -435,3 +473,25 @@
435
473
  margin: 0px 0px;
436
474
  margin-top: 4px;
437
475
  }
476
+
477
+ /*-----------------------------------------------------------------------------
478
+ | Open tabs dropdown
479
+ |----------------------------------------------------------------------------*/
480
+ .theia-tabBar-open-tabs>.theia-select-component .theia-select-component-label {
481
+ display: none;
482
+ }
483
+
484
+ .theia-tabBar-open-tabs>.theia-select-component {
485
+ min-width: auto;
486
+ height: 100%;
487
+ }
488
+
489
+ .theia-tabBar-open-tabs {
490
+ flex: 0 0 auto;
491
+ display: flex;
492
+ align-items: center;
493
+ }
494
+
495
+ .theia-tabBar-open-tabs.p-mod-hidden {
496
+ display: none
497
+ }
@@ -76,6 +76,20 @@ export namespace BadgeWidget {
76
76
  }
77
77
  }
78
78
 
79
+ /**
80
+ * A widget that may change it's internal structure dynamically. Current use is for
81
+ * updating the toolbar when a contributed view is contructed "lazily"
82
+ */
83
+ export interface DynamicToolbarWidget {
84
+ onDidChangeToolbarItems: CommonEvent<void>;
85
+ }
86
+
87
+ export namespace DynamicToolbarWidget {
88
+ export function is(arg: unknown): arg is DynamicToolbarWidget {
89
+ return isObject(arg) && 'onDidChangeToolbarItems' in arg;
90
+ }
91
+ }
92
+
79
93
  /**
80
94
  * A view container holds an arbitrary number of widgets inside a split panel.
81
95
  * Each widget is wrapped in a _part_ that displays the widget title and toolbar
@@ -970,6 +984,13 @@ export class ViewContainerPart extends BaseWidget {
970
984
  this.wrapped.onDidChangeBadgeTooltip(() => this.onDidChangeBadgeTooltipEmitter.fire(), undefined, this.toDispose);
971
985
  }
972
986
 
987
+ if (DynamicToolbarWidget.is(this.wrapped)) {
988
+ this.wrapped.onDidChangeToolbarItems(() => {
989
+ this.toolbar.updateTarget(this.wrapped);
990
+ this.viewContainer?.update();
991
+ });
992
+ }
993
+
973
994
  const { header, body, disposable } = this.createContent();
974
995
  this.header = header;
975
996
  this.body = body;
@@ -34,11 +34,12 @@ export interface SelectOption {
34
34
  }
35
35
 
36
36
  export interface SelectComponentProps {
37
- options: SelectOption[]
37
+ options: readonly SelectOption[]
38
38
  defaultValue?: string | number
39
39
  onChange?: (option: SelectOption, index: number) => void,
40
40
  onBlur?: () => void,
41
- onFocus?: () => void
41
+ onFocus?: () => void,
42
+ alignment?: 'left' | 'right';
42
43
  }
43
44
 
44
45
  export interface SelectComponentState {
@@ -81,7 +82,7 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
81
82
  this.dropdownElement = list;
82
83
  }
83
84
 
84
- get options(): SelectOption[] {
85
+ get options(): readonly SelectOption[] {
85
86
  return this.props.options;
86
87
  }
87
88
 
@@ -105,6 +106,10 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
105
106
  }
106
107
  }
107
108
 
109
+ protected get alignLeft(): boolean {
110
+ return this.props.alignment !== 'right';
111
+ }
112
+
108
113
  protected getOptimalWidth(): number {
109
114
  const textWidth = measureTextWidth(this.props.options.map(e => e.label || e.value || '' + (e.detail || '')));
110
115
  return Math.ceil(textWidth + 16);
@@ -168,7 +173,7 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
168
173
  if (options[selected]?.separator) {
169
174
  selected = this.nextNotSeparator('forwards');
170
175
  }
171
- const selectedItemLabel = options[selected].label ?? options[selected].value;
176
+ const selectedItemLabel = options[selected]?.label ?? options[selected]?.value;
172
177
  return <>
173
178
  <div
174
179
  key="select-component"
@@ -279,6 +284,9 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
279
284
  if (!this.state.dimensions) {
280
285
  return;
281
286
  }
287
+
288
+ const shellArea = document.getElementById('theia-app-shell')!.getBoundingClientRect();
289
+ const maxWidth = this.alignLeft ? shellArea.width - this.state.dimensions.left : this.state.dimensions.right;
282
290
  if (this.mountedListeners.size === 0) {
283
291
  // Only attach our listeners once we render our dropdown menu
284
292
  this.attachListeners();
@@ -286,11 +294,11 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
286
294
  this.optimalWidth = this.getOptimalWidth();
287
295
  this.optimalHeight = this.getOptimalHeight(Math.max(this.state.dimensions.width, this.optimalWidth));
288
296
  }
289
- const clientRect = document.getElementById('theia-app-shell')!.getBoundingClientRect();
290
- const availableTop = this.state.dimensions.top - clientRect.top;
291
- const availableBottom = clientRect.top + clientRect.height - this.state.dimensions.bottom;
297
+ const availableTop = this.state.dimensions.top - shellArea.top;
298
+ const availableBottom = shellArea.top + shellArea.height - this.state.dimensions.bottom;
292
299
  // prefer rendering to the bottom unless there is not enough space and more content can be shown to the top
293
300
  const invert = availableBottom < this.optimalHeight && (availableBottom - this.optimalHeight) < (availableTop - this.optimalHeight);
301
+
294
302
  const { options } = this.props;
295
303
  const { hover } = this.state;
296
304
  const description = options[hover].description;
@@ -313,14 +321,14 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
313
321
  items.push(descriptionNode);
314
322
  }
315
323
  }
316
- const calculatedWidth = Math.max(this.state.dimensions.width, this.optimalWidth);
317
- const maxWidth = clientRect.width - this.state.dimensions.left;
324
+
318
325
  return <div key="dropdown" className="theia-select-component-dropdown" style={{
319
326
  top: invert ? 'none' : this.state.dimensions.bottom,
320
- bottom: invert ? clientRect.top + clientRect.height - this.state.dimensions.top : 'none',
321
- left: this.state.dimensions.left,
322
- width: Math.min(calculatedWidth, maxWidth),
323
- maxHeight: clientRect.height - (invert ? clientRect.height - this.state.dimensions.bottom : this.state.dimensions.top) - this.state.dimensions.height,
327
+ bottom: invert ? shellArea.top + shellArea.height - this.state.dimensions.top : 'none',
328
+ left: this.alignLeft ? this.state.dimensions.left : 'none',
329
+ right: this.alignLeft ? 'none' : shellArea.width - this.state.dimensions.right,
330
+ width: Math.min(Math.max(this.state.dimensions.width, this.optimalWidth), maxWidth),
331
+ maxHeight: shellArea.height - (invert ? shellArea.height - this.state.dimensions.bottom : this.state.dimensions.top) - this.state.dimensions.height,
324
332
  position: 'absolute'
325
333
  }} ref={this.dropdownRef}>
326
334
  {items}
@@ -122,6 +122,7 @@ export interface CommandHandler {
122
122
  */
123
123
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
124
  isEnabled?(...args: any[]): boolean;
125
+ onDidChangeEnabled?: Event<void>;
125
126
  /**
126
127
  * Test whether menu items for this handler should be visible.
127
128
  */