|
17 | 17 | import PerfectScrollbar from 'perfect-scrollbar';
|
18 | 18 | import { TabBar, Title, Widget } from '@phosphor/widgets';
|
19 | 19 | import { VirtualElement, h, VirtualDOM, ElementInlineStyle } from '@phosphor/virtualdom';
|
20 |
| -import { Disposable, DisposableCollection, MenuPath, notEmpty, SelectionService, CommandService, nls } from '../../common'; |
| 20 | +import { Disposable, DisposableCollection, MenuPath, notEmpty, SelectionService, CommandService, nls, ArrayUtils } from '../../common'; |
21 | 21 | import { ContextMenuRenderer } from '../context-menu-renderer';
|
22 | 22 | import { Signal, Slot } from '@phosphor/signaling';
|
23 | 23 | import { Message, MessageLoop } from '@phosphor/messaging';
|
@@ -188,6 +188,7 @@ export class TabBarRenderer extends TabBar.Renderer {
|
188 | 188 | { className: 'theia-tab-icon-label' },
|
189 | 189 | this.renderIcon(data, isInSidePanel),
|
190 | 190 | this.renderLabel(data, isInSidePanel),
|
| 191 | + this.renderTailDecorations(data, isInSidePanel), |
191 | 192 | this.renderBadge(data, isInSidePanel),
|
192 | 193 | this.renderLock(data, isInSidePanel)
|
193 | 194 | ),
|
@@ -289,6 +290,37 @@ export class TabBarRenderer extends TabBar.Renderer {
|
289 | 290 | return h.div({ className: 'p-TabBar-tabLabel', style }, data.title.label);
|
290 | 291 | }
|
291 | 292 |
|
| 293 | + protected renderTailDecorations(renderData: SideBarRenderData, isInSidePanel?: boolean): VirtualElement[] { |
| 294 | + if (!this.corePreferences?.get('workbench.editor.decorations.badges')) { |
| 295 | + return []; |
| 296 | + } |
| 297 | + const tailDecorations = ArrayUtils.coalesce(this.getDecorationData(renderData.title, 'tailDecorations')).flat(); |
| 298 | + if (tailDecorations === undefined || tailDecorations.length === 0) { |
| 299 | + return []; |
| 300 | + } |
| 301 | + let dotDecoration: WidgetDecoration.TailDecoration.AnyPartial | undefined; |
| 302 | + const otherDecorations: WidgetDecoration.TailDecoration.AnyPartial[] = []; |
| 303 | + tailDecorations.reverse().forEach(decoration => { |
| 304 | + const partial = decoration as WidgetDecoration.TailDecoration.AnyPartial; |
| 305 | + if (WidgetDecoration.TailDecoration.isDotDecoration(partial)) { |
| 306 | + dotDecoration ||= partial; |
| 307 | + } else if (partial.data || partial.icon || partial.iconClass) { |
| 308 | + otherDecorations.push(partial); |
| 309 | + } |
| 310 | + }); |
| 311 | + const decorationsToRender = dotDecoration ? [dotDecoration, ...otherDecorations] : otherDecorations; |
| 312 | + return decorationsToRender.map((decoration, index) => { |
| 313 | + const { tooltip, data, fontData, color, icon, iconClass } = decoration; |
| 314 | + const iconToRender = icon ?? iconClass; |
| 315 | + const className = ['p-TabBar-tail', 'flex'].join(' '); |
| 316 | + const style = fontData ? fontData : color ? { color } : undefined; |
| 317 | + const content = (data ? data : iconToRender |
| 318 | + ? h.span({ className: this.getIconClass(iconToRender, iconToRender === 'circle' ? [WidgetDecoration.Styles.DECORATOR_SIZE_CLASS] : []) }) |
| 319 | + : '') + (index !== decorationsToRender.length - 1 ? ',' : ''); |
| 320 | + return h.span({ key: ('tailDecoration_' + index), className, style, title: tooltip ?? content }, content); |
| 321 | + }); |
| 322 | + } |
| 323 | + |
292 | 324 | renderBadge(data: SideBarRenderData, isInSidePanel?: boolean): VirtualElement {
|
293 | 325 | const totalBadge = this.getDecorationData(data.title, 'badge').reduce((sum, badge) => sum! + badge!, 0);
|
294 | 326 | if (!totalBadge) {
|
|
0 commit comments