mirror of
https://github.com/mathuo/dockview
synced 2025-05-07 12:08:26 +00:00
feat: scrollbars
This commit is contained in:
parent
5fb13dd8a2
commit
96d6947aa6
@ -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(
|
||||
|
@ -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>({})
|
||||
);
|
||||
|
@ -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);
|
||||
|
@ -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>, []>(
|
||||
|
@ -8,6 +8,7 @@ describe('gridviewPanel', () => {
|
||||
onDidAddPanel: jest.fn(),
|
||||
onDidRemovePanel: jest.fn(),
|
||||
options: {},
|
||||
onDidOptionsChange: jest.fn(),
|
||||
} as any;
|
||||
});
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}),
|
||||
|
@ -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)[];
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user