Skip to content

Commit 0e3afcf

Browse files
authored
Merge pull request #847 from mathuo/830-cannot-close-tab-with-middle-mouse-button
feat: close tab with middle btn
2 parents 1a85444 + 0e9c648 commit 0e3afcf

File tree

4 files changed

+31
-64
lines changed

4 files changed

+31
-64
lines changed

packages/dockview-core/src/dockview/components/tab/defaultTab.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
2929
this._element.appendChild(this._content);
3030
this._element.appendChild(this.action);
3131

32-
this.addDisposables(
33-
addDisposableListener(this.action, 'pointerdown', (ev) => {
34-
ev.preventDefault();
35-
})
36-
);
37-
3832
this.render();
3933
}
4034

packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ export class TabsContainer
318318
this._onTabDragStart.fire({ nativeEvent: event, panel });
319319
}),
320320
tab.onChanged((event) => {
321+
if (event.defaultPrevented) {
322+
return;
323+
}
324+
321325
const isFloatingGroupsEnabled =
322326
!this.accessor.options.disableFloatingGroups;
323327

@@ -346,14 +350,15 @@ export class TabsContainer
346350
return;
347351
}
348352

349-
const isLeftClick = event.button === 0;
350-
351-
if (!isLeftClick || event.defaultPrevented) {
352-
return;
353-
}
354-
355-
if (this.group.activePanel !== panel) {
356-
this.group.model.openPanel(panel);
353+
switch (event.button) {
354+
case 0: // left click or touch
355+
if (this.group.activePanel !== panel) {
356+
this.group.model.openPanel(panel);
357+
}
358+
break;
359+
case 1: // middle click
360+
panel.api.close();
361+
break;
357362
}
358363
}),
359364
tab.onDrop((event) => {

packages/dockview/src/__tests__/dockview/defaultTab.spec.tsx

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import { Disposable } from 'dockview-core/dist/cjs/lifecycle';
1010
describe('defaultTab', () => {
1111
test('has close button by default', async () => {
1212
const api = fromPartial<DockviewPanelApi>({
13-
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
13+
onDidTitleChange: jest
14+
.fn()
15+
.mockImplementation(() => Disposable.NONE),
1416
});
1517
const containerApi = fromPartial<DockviewApi>({});
1618
const params = {};
@@ -30,7 +32,9 @@ describe('defaultTab', () => {
3032
test('that title is displayed', async () => {
3133
const api = fromPartial<DockviewPanelApi>({
3234
title: 'test_title',
33-
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
35+
onDidTitleChange: jest
36+
.fn()
37+
.mockImplementation(() => Disposable.NONE),
3438
});
3539
const containerApi = fromPartial<DockviewApi>({});
3640
const params = {};
@@ -84,7 +88,9 @@ describe('defaultTab', () => {
8488

8589
test('has no close button when hideClose=true', async () => {
8690
const api = fromPartial<DockviewPanelApi>({
87-
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
91+
onDidTitleChange: jest
92+
.fn()
93+
.mockImplementation(() => Disposable.NONE),
8894
});
8995
const containerApi = fromPartial<DockviewApi>({});
9096
const params = {};
@@ -105,7 +111,9 @@ describe('defaultTab', () => {
105111
test('that settings closeActionOverride skips api.close()', async () => {
106112
const api = fromPartial<DockviewPanelApi>({
107113
close: jest.fn(),
108-
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
114+
onDidTitleChange: jest
115+
.fn()
116+
.mockImplementation(() => Disposable.NONE),
109117
});
110118
const containerApi = fromPartial<DockviewApi>({});
111119
const params = {};
@@ -134,7 +142,9 @@ describe('defaultTab', () => {
134142
test('that clicking close calls api.close()', async () => {
135143
const api = fromPartial<DockviewPanelApi>({
136144
close: jest.fn(),
137-
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
145+
onDidTitleChange: jest
146+
.fn()
147+
.mockImplementation(() => Disposable.NONE),
138148
});
139149
const containerApi = fromPartial<DockviewApi>({});
140150
const params = {};
@@ -158,7 +168,9 @@ describe('defaultTab', () => {
158168

159169
test('has close button when hideClose=false', async () => {
160170
const api = fromPartial<DockviewPanelApi>({
161-
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
171+
onDidTitleChange: jest
172+
.fn()
173+
.mockImplementation(() => Disposable.NONE),
162174
});
163175
const containerApi = fromPartial<DockviewApi>({});
164176
const params = {};
@@ -175,32 +187,4 @@ describe('defaultTab', () => {
175187
const element = await screen.getByTestId('dockview-dv-default-tab');
176188
expect(element.querySelector('.dv-default-tab-action')).toBeTruthy();
177189
});
178-
179-
test('that pointerDown on close button prevents panel becoming active', async () => {
180-
const api = fromPartial<DockviewPanelApi>({
181-
setActive: jest.fn(),
182-
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
183-
});
184-
const containerApi = fromPartial<DockviewApi>({});
185-
const params = {};
186-
187-
render(
188-
<DockviewDefaultTab
189-
api={api}
190-
containerApi={containerApi}
191-
params={params}
192-
/>
193-
);
194-
195-
const element = await screen.getByTestId('dockview-dv-default-tab');
196-
const btn = element.querySelector(
197-
'.dv-default-tab-action'
198-
) as HTMLElement;
199-
200-
fireEvent.pointerDown(btn);
201-
expect(api.setActive).toHaveBeenCalledTimes(0);
202-
203-
fireEvent.click(element);
204-
expect(api.setActive).toHaveBeenCalledTimes(1);
205-
});
206190
});

packages/dockview/src/dockview/defaultTab.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,10 @@ export const DockviewDefaultTab: React.FunctionComponent<
5353
e.preventDefault();
5454
}, []);
5555

56-
const onClick = React.useCallback(
57-
(event: React.MouseEvent<HTMLDivElement>) => {
58-
if (event.defaultPrevented) {
59-
return;
60-
}
61-
62-
api.setActive();
63-
64-
if (rest.onClick) {
65-
rest.onClick(event);
66-
}
67-
},
68-
[api, rest.onClick]
69-
);
70-
7156
return (
7257
<div
7358
data-testid="dockview-dv-default-tab"
7459
{...rest}
75-
onClick={onClick}
7660
className="dv-default-tab"
7761
>
7862
<span className="dv-default-tab-content">{title}</span>

0 commit comments

Comments
 (0)