feat: scrollbars

This commit is contained in:
mathuo 2025-03-03 20:53:59 +00:00
parent 5fb13dd8a2
commit 96d6947aa6
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
11 changed files with 78 additions and 46 deletions

View File

@ -10,6 +10,7 @@ describe('groupPanelApi', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const panelMock = jest.fn<DockviewPanel, []>(() => {
@ -50,6 +51,7 @@ describe('groupPanelApi', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupViewPanel = new DockviewGroupPanel(
@ -82,6 +84,7 @@ describe('groupPanelApi', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupViewPanel = new DockviewGroupPanel(

View File

@ -18,6 +18,7 @@ describe('tabsContainer', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -71,6 +72,7 @@ describe('tabsContainer', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const dropTargetContainer = document.createElement('div');
@ -140,6 +142,7 @@ describe('tabsContainer', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -203,6 +206,7 @@ describe('tabsContainer', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -266,6 +270,7 @@ describe('tabsContainer', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -334,6 +339,7 @@ describe('tabsContainer', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -398,6 +404,7 @@ describe('tabsContainer', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -464,6 +471,7 @@ describe('tabsContainer', () => {
element: document.createElement('div'),
addFloatingGroup: jest.fn(),
doSetGroupActive: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -520,6 +528,7 @@ describe('tabsContainer', () => {
element: document.createElement('div'),
addFloatingGroup: jest.fn(),
doSetGroupActive: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -571,6 +580,7 @@ describe('tabsContainer', () => {
element: document.createElement('div'),
addFloatingGroup: jest.fn(),
getGroupPanel: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -627,6 +637,7 @@ describe('tabsContainer', () => {
element: document.createElement('div'),
addFloatingGroup: jest.fn(),
getGroupPanel: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -694,6 +705,7 @@ describe('tabsContainer', () => {
element: document.createElement('div'),
addFloatingGroup: jest.fn(),
getGroupPanel: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -761,6 +773,7 @@ describe('tabsContainer', () => {
element: document.createElement('div'),
addFloatingGroup: jest.fn(),
getGroupPanel: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -824,6 +837,7 @@ describe('tabsContainer', () => {
const cut = new TabsContainer(
fromPartial<DockviewComponent>({
options: {},
onDidOptionsChange: jest.fn(),
}),
fromPartial<DockviewGroupPanel>({})
);

View File

@ -16,6 +16,7 @@ describe('dockviewGroupPanel', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
});
const options = fromPartial<GroupOptions>({});
const cut = new DockviewGroupPanel(accessor, 'test_id', options);
@ -39,6 +40,7 @@ describe('dockviewGroupPanel', () => {
detatch: jest.fn(),
},
doSetGroupActive: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const options = fromPartial<GroupOptions>({});
@ -81,6 +83,7 @@ describe('dockviewGroupPanel', () => {
detatch: jest.fn(),
}),
options: {},
onDidOptionsChange: jest.fn(),
});
const options = fromPartial<GroupOptions>({});
const cut = new DockviewGroupPanel(accessor, 'test_id', options);

View File

@ -270,6 +270,7 @@ describe('dockviewGroupPanelModel', () => {
document.createElement('div'),
fromPartial<DockviewComponent>({})
),
onDidOptionsChange: () => ({ dispose: jest.fn() }),
});
groupview = new DockviewGroupPanel(dockview, 'groupview-1', options);
@ -651,6 +652,7 @@ describe('dockviewGroupPanelModel', () => {
getPanel: jest.fn(),
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -713,6 +715,7 @@ describe('dockviewGroupPanelModel', () => {
getPanel: jest.fn(),
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -809,6 +812,7 @@ describe('dockviewGroupPanelModel', () => {
document.createElement('div'),
fromPartial<DockviewComponent>({})
),
onDidOptionsChange: jest.fn(),
});
const groupView = fromPartial<DockviewGroupPanelModel>({
@ -875,6 +879,7 @@ describe('dockviewGroupPanelModel', () => {
document.createElement('div'),
fromPartial<DockviewComponent>({})
),
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
@ -948,6 +953,7 @@ describe('dockviewGroupPanelModel', () => {
document.createElement('div'),
fromPartial<DockviewComponent>({})
),
onDidOptionsChange: jest.fn(),
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(

View File

@ -8,6 +8,7 @@ describe('gridviewPanel', () => {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
onDidOptionsChange: jest.fn(),
} as any;
});

View File

@ -8,7 +8,7 @@ import {
export class PopupService extends CompositeDisposable {
private readonly _element: HTMLElement;
private _active: HTMLElement | null = null;
private _activeDisposable = new MutableDisposable();
private readonly _activeDisposable = new MutableDisposable();
constructor(private readonly root: HTMLElement) {
super();

View File

@ -1,5 +1,9 @@
.dv-tabs-container {
display: flex;
height: 100%;
overflow: hidden;
scrollbar-width: thin; // firefox
&.dv-horizontal {
.dv-tabs-container {
.dv-tab {
@ -26,11 +30,6 @@
}
}
display: flex;
height: 100%;
overflow: hidden;
scrollbar-width: thin; // firefox
&::-webkit-scrollbar {
height: 3px;
}
@ -57,7 +56,6 @@
}
}
.dv-tabs-overflow-container {
flex-direction: column;
height: unset;

View File

@ -140,11 +140,7 @@ export class TabsContainer
this.preActionsContainer.className = 'dv-pre-actions-container';
this.tabs = new Tabs(group, accessor, {
showTabsOverflowControl: false,
});
this.tabs.onOverflowTabsChange((event) => {
this.toggleDropdown(event);
showTabsOverflowControl: !accessor.options.disableTabsOverflowList,
});
this.voidContainer = new VoidContainer(this.accessor, this.group);
@ -156,6 +152,13 @@ export class TabsContainer
this._element.appendChild(this.rightActionsContainer);
this.addDisposables(
accessor.onDidOptionsChange(() => {
this.tabs.showTabsOverflowControl =
!accessor.options.disableTabsOverflowList;
}),
this.tabs.onOverflowTabsChange((event) => {
this.toggleDropdown(event);
}),
this.tabs,
this._onWillShowOverlay,
this._onDrop,
@ -348,42 +351,40 @@ export class TabsContainer
el.style.overflow = 'auto';
el.className = 'dv-tabs-overflow-container';
this.tabs.tabs
.filter((tab) => this._overflowTabs.includes(tab.panel.id))
.map((tab) => {
const panelObject = this.group.panels.find(
(panel) => panel === tab.panel
)!;
for (const tab of this.tabs.tabs.filter((tab) =>
this._overflowTabs.includes(tab.panel.id)
)) {
const panelObject = this.group.panels.find(
(panel) => panel === tab.panel
)!;
const tabComponent =
panelObject.view.createTabRenderer(
'headerOverflow'
);
const tabComponent =
panelObject.view.createTabRenderer('headerOverflow');
const child = tabComponent.element;
const child = tabComponent.element;
const wrapper = document.createElement('div');
toggleClass(wrapper, 'dv-tab', true);
toggleClass(
wrapper,
'dv-active-tab',
panelObject.api.isActive
);
toggleClass(
wrapper,
'dv-inactive-tab',
!panelObject.api.isActive
);
const wrapper = document.createElement('div');
toggleClass(wrapper, 'dv-tab', true);
toggleClass(
wrapper,
'dv-active-tab',
panelObject.api.isActive
);
toggleClass(
wrapper,
'dv-inactive-tab',
!panelObject.api.isActive
);
wrapper.addEventListener('mousedown', () => {
this.accessor.popupService.close();
tab.element.scrollIntoView();
tab.panel.api.setActive();
});
wrapper.appendChild(child);
el.appendChild(wrapper);
wrapper.addEventListener('mousedown', () => {
this.accessor.popupService.close();
tab.element.scrollIntoView();
tab.panel.api.setActive();
});
wrapper.appendChild(child);
el.appendChild(wrapper);
}
this.accessor.popupService.openPopover(el, {
x: event.clientX,

View File

@ -330,6 +330,9 @@ export class DockviewComponent
readonly onDidAddGroup: Event<DockviewGroupPanel> =
this._onDidAddGroup.event;
private readonly _onDidOptionsChange = new Emitter<void>();
readonly onDidOptionsChange: Event<void> = this._onDidOptionsChange.event;
private readonly _onDidActiveGroupChange = new Emitter<
DockviewGroupPanel | undefined
>();
@ -434,6 +437,7 @@ export class DockviewComponent
this._onDidActiveGroupChange,
this._onUnhandledDragOverEvent,
this._onDidMaximizedGroupChange,
this._onDidOptionsChange,
this.onDidViewVisibilityChangeMicroTaskQueue(() => {
this.updateWatermark();
}),

View File

@ -72,6 +72,7 @@ export interface DockviewOptions {
*/
noPanelsOverlay?: 'emptyGroup' | 'watermark';
theme?: DockviewTheme;
disableTabsOverflowList?: boolean;
}
export interface DockviewDndOverlayEvent extends IAcceptableEvent {
@ -119,6 +120,7 @@ export const PROPERTY_KEYS_DOCKVIEW: (keyof DockviewOptions)[] = (() => {
dndEdges: undefined,
theme: undefined,
gap: undefined,
disableTabsOverflowList: undefined,
};
return Object.keys(properties) as (keyof DockviewOptions)[];

View File

@ -4,11 +4,11 @@ import { CompositeDisposable } from './lifecycle';
import { clamp } from './math';
export class Scrollbar extends CompositeDisposable {
private _element: HTMLElement;
private _horizontalScrollbar: HTMLElement;
private readonly _element: HTMLElement;
private readonly _horizontalScrollbar: HTMLElement;
private _scrollLeft: number = 0;
private _animationTimer: any;
static MouseWheelSpeed = 1;
public static MouseWheelSpeed = 1;
get element(): HTMLElement {
return this._element;