diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index 13a5bc9f90..0ec76c1ecb 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -11,7 +11,11 @@ import { Emitter } from '../../events'; import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { fireEvent, queryByTestId } from '@testing-library/dom'; -import { getPanelData } from '../../dnd/dataTransfer'; +import { + getPanelData, + LocalSelectionTransfer, + PanelTransfer, +} from '../../dnd/dataTransfer'; import { GroupDragEvent, TabDragEvent, @@ -4404,6 +4408,175 @@ describe('dockviewComponent', () => { expect(events.length).toBe(5); }); + test('that external dockview drags trigger the top-level edge dnd target', () => { + const container = document.createElement('div'); + + const dockview = new DockviewComponent(container, { + createComponent(options) { + switch (options.name) { + case 'default': + return new PanelContentPartTest( + options.id, + options.name + ); + default: + throw new Error(`unsupported`); + } + }, + }); + + let events: DockviewDndOverlayEvent[] = []; + + dockview.onUnhandledDragOverEvent((e) => { + events.push(e); + e.accept(); + }); + + dockview.layout(1000, 500); + + dockview.addPanel({ + id: 'panel_1', + component: 'default', + }); + dockview.addPanel({ + id: 'panel_2', + component: 'default', + position: { direction: 'right' }, + }); + + Object.defineProperty(dockview.element, 'offsetWidth', { + get: () => 100, + }); + Object.defineProperty(dockview.element, 'offsetHeight', { + get: () => 100, + }); + + jest.spyOn(dockview.element, 'getBoundingClientRect').mockReturnValue({ + left: 0, + top: 0, + width: 100, + height: 100, + } as any); + + LocalSelectionTransfer.getInstance().setData( + [new PanelTransfer('external-view', 'external-group', 'panel_99')], + PanelTransfer.prototype + ); + + try { + const eventLeft = new KeyboardEvent('dragover'); + Object.defineProperty(eventLeft, 'clientX', { + get: () => 0, + }); + Object.defineProperty(eventLeft, 'clientY', { + get: () => 0, + }); + + fireEvent.dragEnter(dockview.element); + fireEvent(dockview.element, eventLeft); + + expect(events).toHaveLength(1); + expect(events[0].nativeEvent).toBe(eventLeft); + expect(events[0].position).toBe('left'); + expect(events[0].target).toBe('edge'); + expect(events[0].getData).toBe(getPanelData); + expect( + dockview.element.getElementsByClassName( + 'dv-drop-target-anchor' + ).length + ).toBe(1); + } finally { + LocalSelectionTransfer.getInstance().clearData( + PanelTransfer.prototype + ); + } + }); + + test('that external dockview drops emit root-level onDidDrop events', () => { + const container = document.createElement('div'); + + const dockview = new DockviewComponent(container, { + createComponent(options) { + switch (options.name) { + case 'default': + return new PanelContentPartTest( + options.id, + options.name + ); + default: + throw new Error(`unsupported`); + } + }, + }); + + let didDropEvent: any = undefined; + + dockview.onUnhandledDragOverEvent((e) => { + e.accept(); + }); + dockview.onDidDrop((event) => { + didDropEvent = event; + }); + + dockview.layout(1000, 500); + + dockview.addPanel({ + id: 'panel_1', + component: 'default', + }); + dockview.addPanel({ + id: 'panel_2', + component: 'default', + position: { direction: 'right' }, + }); + + Object.defineProperty(dockview.element, 'offsetWidth', { + get: () => 100, + }); + Object.defineProperty(dockview.element, 'offsetHeight', { + get: () => 100, + }); + + jest.spyOn(dockview.element, 'getBoundingClientRect').mockReturnValue({ + left: 0, + top: 0, + width: 100, + height: 100, + } as any); + + const moveSpy = jest.spyOn(dockview, 'moveGroupOrPanel'); + + LocalSelectionTransfer.getInstance().setData( + [new PanelTransfer('external-view', 'external-group', 'panel_99')], + PanelTransfer.prototype + ); + + try { + const eventLeft = new KeyboardEvent('dragover'); + Object.defineProperty(eventLeft, 'clientX', { + get: () => 0, + }); + Object.defineProperty(eventLeft, 'clientY', { + get: () => 0, + }); + + fireEvent.dragEnter(dockview.element); + fireEvent(dockview.element, eventLeft); + fireEvent.drop(dockview.element); + + expect(moveSpy).not.toHaveBeenCalled(); + expect(didDropEvent).toBeDefined(); + expect(didDropEvent.position).toBe('left'); + expect(didDropEvent.group).toBeUndefined(); + expect(didDropEvent.panel).toBeUndefined(); + expect(didDropEvent.getData).toBe(getPanelData); + } finally { + LocalSelectionTransfer.getInstance().clearData( + PanelTransfer.prototype + ); + } + }); + test('that dragging a tab triggers onWillDragPanel', () => { const container = document.createElement('div'); diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 370fd9111f..850420fd4d 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -460,11 +460,7 @@ export class DockviewComponent canDisplayOverlay: (event, position) => { const data = getPanelData(); - if (data) { - if (data.viewId !== this.id) { - return false; - } - + if (data?.viewId === this.id) { if (position === 'center') { // center drop target is only allowed if there are no panels in the grid // floating panels are allowed @@ -631,7 +627,7 @@ export class DockviewComponent const data = getPanelData(); - if (data) { + if (data?.viewId === this.id) { this.moveGroupOrPanel({ from: { groupId: data.groupId,