refactor: simplify dnd control

This commit is contained in:
mathuo 2023-02-14 22:19:29 +07:00
parent 321f78ec0e
commit 3052857dfc
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
15 changed files with 157 additions and 142 deletions

View File

@ -3,9 +3,7 @@ import {
calculateQuadrantAsPixels,
directionToPosition,
Droptarget,
DropTargetDirections,
Position,
Quadrant,
} from '../../dnd/droptarget';
import { fireEvent } from '@testing-library/dom';
@ -36,11 +34,11 @@ describe('droptarget', () => {
});
test('directionToPosition', () => {
expect(directionToPosition('above')).toBe(Position.Top);
expect(directionToPosition('below')).toBe(Position.Bottom);
expect(directionToPosition('left')).toBe(Position.Left);
expect(directionToPosition('right')).toBe(Position.Right);
expect(directionToPosition('within')).toBe(Position.Center);
expect(directionToPosition('above')).toBe('top');
expect(directionToPosition('below')).toBe('bottom');
expect(directionToPosition('left')).toBe('left');
expect(directionToPosition('right')).toBe('right');
expect(directionToPosition('within')).toBe('center');
expect(() => directionToPosition('bad_input' as any)).toThrow(
"invalid direction 'bad_input'"
);
@ -65,7 +63,7 @@ describe('droptarget', () => {
'.drop-target-dropzone'
) as HTMLElement;
fireEvent.drop(target);
expect(position).toBe(Position.Center);
expect(position).toBe('center');
});
test('drop', () => {
@ -100,7 +98,7 @@ describe('droptarget', () => {
expect(position).toBeUndefined();
fireEvent.drop(target);
expect(position).toBe(Position.Left);
expect(position).toBe('left');
});
test('default', () => {
@ -135,7 +133,7 @@ describe('droptarget', () => {
'.drop-target > .drop-target-dropzone > .drop-target-selection'
);
expect(viewQuery.length).toBe(1);
expect(droptarget.state).toBe(Position.Left);
expect(droptarget.state).toBe('left');
expect(
(
element
@ -153,7 +151,7 @@ describe('droptarget', () => {
'.drop-target > .drop-target-dropzone > .drop-target-selection'
);
expect(viewQuery.length).toBe(1);
expect(droptarget.state).toBe(Position.Top);
expect(droptarget.state).toBe('top');
expect(
(
element
@ -171,7 +169,7 @@ describe('droptarget', () => {
'.drop-target > .drop-target-dropzone > .drop-target-selection'
);
expect(viewQuery.length).toBe(1);
expect(droptarget.state).toBe(Position.Bottom);
expect(droptarget.state).toBe('bottom');
expect(
(
element
@ -189,7 +187,7 @@ describe('droptarget', () => {
'.drop-target > .drop-target-dropzone > .drop-target-selection'
);
expect(viewQuery.length).toBe(1);
expect(droptarget.state).toBe(Position.Right);
expect(droptarget.state).toBe('right');
expect(
(
element
@ -202,7 +200,7 @@ describe('droptarget', () => {
target,
createOffsetDragOverEvent({ clientX: 100, clientY: 50 })
);
expect(droptarget.state).toBe(Position.Center);
expect(droptarget.state).toBe('center');
expect(
(
element
@ -212,7 +210,7 @@ describe('droptarget', () => {
).toBe('');
fireEvent.dragLeave(target);
expect(droptarget.state).toBe(Position.Center);
expect(droptarget.state).toBe('center');
viewQuery = element.querySelectorAll('.drop-target');
expect(viewQuery.length).toBe(0);
});
@ -220,10 +218,10 @@ describe('droptarget', () => {
describe('calculateQuadrantAsPercentage', () => {
test('variety of cases', () => {
const inputs: Array<{
directions: DropTargetDirections[];
directions: Position[];
x: number;
y: number;
result: Quadrant | null | undefined;
result: Position | null;
}> = [
{ directions: ['left', 'right'], x: 19, y: 50, result: 'left' },
{
@ -248,13 +246,13 @@ describe('droptarget', () => {
directions: ['left', 'right', 'top', 'bottom', 'center'],
x: 50,
y: 50,
result: null,
result: 'center',
},
{
directions: ['left', 'right', 'top', 'bottom'],
x: 50,
y: 50,
result: undefined,
result: null,
},
];
@ -276,10 +274,10 @@ describe('droptarget', () => {
describe('calculateQuadrantAsPixels', () => {
test('variety of cases', () => {
const inputs: Array<{
directions: DropTargetDirections[];
directions: Position[];
x: number;
y: number;
result: Quadrant | null | undefined;
result: Position | null;
}> = [
{ directions: ['left', 'right'], x: 19, y: 50, result: 'left' },
{
@ -304,13 +302,13 @@ describe('droptarget', () => {
directions: ['left', 'right', 'top', 'bottom', 'center'],
x: 50,
y: 50,
result: null,
result: 'center',
},
{
directions: ['left', 'right', 'top', 'bottom'],
x: 50,
y: 50,
result: undefined,
result: null,
},
];

View File

@ -253,9 +253,9 @@ describe('dockviewComponent', () => {
const panel4 = dockview.getGroupPanel('panel4');
const group1 = panel1!.group;
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', Position.Right);
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
const group2 = panel1!.group;
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup!.model.activePanel).toBe(panel3);
@ -305,9 +305,9 @@ describe('dockviewComponent', () => {
const panel1 = dockview.getGroupPanel('panel1')!;
const panel2 = dockview.getGroupPanel('panel2')!;
const group1 = panel1.group;
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', Position.Right);
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
const group2 = panel1.group;
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
expect(dockview.size).toBe(2);
expect(dockview.totalPanels).toBe(4);
@ -370,9 +370,9 @@ describe('dockviewComponent', () => {
expect(panel4.api.isActive).toBeFalsy();
const group1 = panel1.group;
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', Position.Right);
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
const group2 = panel1.group;
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
expect(dockview.size).toBe(2);
expect(panel1.group).toBe(panel3.group);
@ -439,7 +439,7 @@ describe('dockviewComponent', () => {
expect(group.model.indexOf(panel1)).toBe(0);
expect(group.model.indexOf(panel2)).toBe(1);
dockview.moveGroupOrPanel(group, group.id, 'panel1', Position.Right);
dockview.moveGroupOrPanel(group, group.id, 'panel1', 'right');
expect(dockview.size).toBe(2);
expect(dockview.totalPanels).toBe(2);
@ -489,7 +489,7 @@ describe('dockviewComponent', () => {
expect(viewQuery.length).toBe(1);
const group = dockview.getGroupPanel('panel1')!.group;
dockview.moveGroupOrPanel(group, group.id, 'panel1', Position.Right);
dockview.moveGroupOrPanel(group, group.id, 'panel1', 'right');
viewQuery = container.querySelectorAll(
'.branch-node > .split-view-container > .view-container > .view'
@ -974,7 +974,7 @@ describe('dockviewComponent', () => {
panel2.group!,
panel5.group!.id,
panel5.id,
Position.Center
'center'
);
expect(events).toEqual([
{ type: 'REMOVE_PANEL', panel: panel5 },
@ -993,7 +993,7 @@ describe('dockviewComponent', () => {
panel2.group!,
panel4.group!.id,
panel4.id,
Position.Center
'center'
);
expect(events).toEqual([
@ -1313,7 +1313,7 @@ describe('dockviewComponent', () => {
panel1.group,
panel2.group.id,
'panel2',
Position.Left
'left'
);
expect(panel1Spy).not.toHaveBeenCalled();
@ -1354,7 +1354,7 @@ describe('dockviewComponent', () => {
panel1.group,
panel2.group.id,
'panel2',
Position.Center
'center'
);
expect(panel1Spy).not.toHaveBeenCalled();
@ -1393,7 +1393,7 @@ describe('dockviewComponent', () => {
panel1.group,
panel1.group.id,
'panel1',
Position.Center,
'center',
0
);
@ -1554,7 +1554,7 @@ describe('dockviewComponent', () => {
panel3.group,
panel1.group.id,
undefined,
Position.Center
'center'
);
expect(dockview.groups.length).toBe(1);

View File

@ -730,7 +730,7 @@ describe('groupview', () => {
).toBe(0);
});
test('that should allow drop when not dropping on self for same component id', () => {
test('that should not allow drop when dropping on self for same component id', () => {
const accessorMock = jest.fn<Partial<DockviewComponent>, []>(() => {
return {
id: 'testcomponentid',
@ -792,7 +792,7 @@ describe('groupview', () => {
expect(
element.getElementsByClassName('drop-target-dropzone').length
).toBe(1);
).toBe(0);
});
test('that should not allow drop when not dropping for different component id', () => {

View File

@ -9,44 +9,29 @@ function numberOrFallback(maybeNumber: any, fallback: number): number {
return typeof maybeNumber === 'number' ? maybeNumber : fallback;
}
export enum Position {
Top = 'Top',
Left = 'Left',
Bottom = 'Bottom',
Right = 'Right',
Center = 'Center',
}
export function directionToPosition(direction: Direction): Position {
switch (direction) {
case 'above':
return Position.Top;
return 'top';
case 'below':
return Position.Bottom;
return 'bottom';
case 'left':
return Position.Left;
return 'left';
case 'right':
return Position.Right;
return 'right';
case 'within':
return Position.Center;
return 'center';
default:
throw new Error(`invalid direction '${direction}'`);
}
}
export type Quadrant = 'top' | 'bottom' | 'left' | 'right';
export interface DroptargetEvent {
readonly position: Position;
readonly nativeEvent: DragEvent;
}
export type DropTargetDirections =
| 'top'
| 'bottom'
| 'left'
| 'right'
| 'center';
export type Position = 'top' | 'bottom' | 'left' | 'right' | 'center';
function isBooleanValue(
canDisplayOverlay: CanDisplayOverlay
@ -56,7 +41,7 @@ function isBooleanValue(
export type CanDisplayOverlay =
| boolean
| ((dragEvent: DragEvent, state: Quadrant | null) => boolean);
| ((dragEvent: DragEvent, state: Position) => boolean);
export class Droptarget extends CompositeDisposable {
private target: HTMLElement | undefined;
@ -74,7 +59,7 @@ export class Droptarget extends CompositeDisposable {
private readonly element: HTMLElement,
private readonly options: {
canDisplayOverlay: CanDisplayOverlay;
acceptedTargetZones: DropTargetDirections[];
acceptedTargetZones: Position[];
overlayModel?: {
size?: { value: number; type: 'pixels' | 'percentage' };
activationSize?: {
@ -117,7 +102,7 @@ export class Droptarget extends CompositeDisposable {
height
);
if (quadrant === undefined) {
if (quadrant === null) {
this.removeDropTarget();
return;
}
@ -135,7 +120,7 @@ export class Droptarget extends CompositeDisposable {
this.target.className = 'drop-target-dropzone';
this.overlay = document.createElement('div');
this.overlay.className = 'drop-target-selection';
this._state = Position.Center;
this._state = 'center';
this.target.appendChild(this.overlay);
this.element.classList.add('drop-target');
@ -181,7 +166,7 @@ export class Droptarget extends CompositeDisposable {
}
private toggleClasses(
quadrant: Quadrant | null,
quadrant: Position,
width: number,
height: number
): void {
@ -246,33 +231,33 @@ export class Droptarget extends CompositeDisposable {
toggleClass(this.overlay, 'small-bottom', isSmallY && isBottom);
}
private setState(quadrant: Quadrant | null): void {
private setState(quadrant: Position): void {
switch (quadrant) {
case 'top':
this._state = Position.Top;
this._state = 'top';
break;
case 'left':
this._state = Position.Left;
this._state = 'left';
break;
case 'bottom':
this._state = Position.Bottom;
this._state = 'bottom';
break;
case 'right':
this._state = Position.Right;
this._state = 'right';
break;
default:
this._state = Position.Center;
case 'center':
this._state = 'center';
break;
}
}
private calculateQuadrant(
overlayType: Set<DropTargetDirections>,
overlayType: Set<Position>,
x: number,
y: number,
width: number,
height: number
): Quadrant | null | undefined {
): Position | null {
const isPercentage =
this.options.overlayModel?.activationSize === undefined ||
this.options.overlayModel?.activationSize?.type === 'percentage';
@ -315,13 +300,13 @@ export class Droptarget extends CompositeDisposable {
}
export function calculateQuadrantAsPercentage(
overlayType: Set<DropTargetDirections>,
overlayType: Set<Position>,
x: number,
y: number,
width: number,
height: number,
threshold: number
): Quadrant | null | undefined {
): Position | null {
const xp = (100 * x) / width;
const yp = (100 * y) / height;
@ -339,20 +324,20 @@ export function calculateQuadrantAsPercentage(
}
if (!overlayType.has('center')) {
return undefined;
return null;
}
return null;
return 'center';
}
export function calculateQuadrantAsPixels(
overlayType: Set<DropTargetDirections>,
overlayType: Set<Position>,
x: number,
y: number,
width: number,
height: number,
threshold: number
): Quadrant | null | undefined {
): Position | null {
if (overlayType.has('left') && x < threshold) {
return 'left';
}
@ -367,8 +352,8 @@ export function calculateQuadrantAsPixels(
}
if (!overlayType.has('center')) {
return undefined;
return null;
}
return null;
return 'center';
}

View File

@ -46,6 +46,7 @@ import {
import { GroupPanel, IGroupviewPanel } from '../groupview/groupviewPanel';
import { DefaultGroupPanelView } from './defaultGroupPanelView';
import { getPanelData } from '../dnd/dataTransfer';
import { DockviewDropTargets } from '../groupview/dnd';
export interface PanelReference {
update: (event: { params: { [key: string]: any } }) => void;
@ -235,8 +236,26 @@ export class DockviewComponent
}
const dropTarget = new Droptarget(this.element, {
canDisplayOverlay: () => {
return true;
canDisplayOverlay: (event, position) => {
const data = getPanelData();
if (data) {
if (data.viewId !== this.id) {
return false;
}
return true;
}
if (this.options.showDndOverlay) {
return this.options.showDndOverlay({
nativeEvent: event,
position: position,
target: DockviewDropTargets.Edge,
getData: getPanelData,
});
}
return false;
},
acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
overlayModel: {
@ -250,16 +269,14 @@ export class DockviewComponent
dropTarget.onDrop((event) => {
const data = getPanelData();
if (!data) {
return;
if (data) {
this.moveGroupOrPanel(
this.orthogonalize(event.position),
data.groupId,
data.panelId || undefined,
'center'
);
}
this.moveGroupOrPanel(
this.orthogonalize(event.position),
data.groupId,
data.panelId || undefined,
Position.Center
);
})
);
@ -268,16 +285,16 @@ export class DockviewComponent
private orthogonalize(position: Position): GroupPanel {
switch (position) {
case Position.Top:
case Position.Bottom:
case 'top':
case 'bottom':
if (this.gridview.orientation === Orientation.HORIZONTAL) {
// we need to add to a vertical splitview but the current root is a horizontal splitview.
// insert a vertical splitview at the root level and add the existing view as a child
this.gridview.insertOrthogonalSplitviewAtRoot();
}
break;
case Position.Left:
case Position.Right:
case 'left':
case 'right':
if (this.gridview.orientation === Orientation.VERTICAL) {
// we need to add to a horizontal splitview but the current root is a vertical splitview.
// insert a horiziontal splitview at the root level and add the existing view as a child
@ -289,11 +306,11 @@ export class DockviewComponent
}
switch (position) {
case Position.Top:
case Position.Left:
case 'top':
case 'left':
return this.createGroupAtLocation([0]); // insert into first position
case Position.Bottom:
case Position.Right:
case 'bottom':
case 'right':
return this.createGroupAtLocation([this.gridview.length]); // insert into last position
default:
throw new Error(`unsupported position ${position}`);
@ -543,7 +560,7 @@ export class DockviewComponent
const target = toTarget(
<Direction>options.position?.direction || 'within'
);
if (target === Position.Center) {
if (target === 'center') {
panel = this.createPanel(options, referenceGroup);
referenceGroup.model.openPanel(panel);
} else {
@ -703,7 +720,7 @@ export class DockviewComponent
return;
}
if (!target || target === Position.Center) {
if (!target || target === 'center') {
const groupItem: IDockviewPanel | undefined =
sourceGroup?.model.removePanel(itemId) ||
this.panels.find((panel) => panel.id === itemId);
@ -782,7 +799,7 @@ export class DockviewComponent
target: Position
): void {
if (sourceGroup) {
if (!target || target === Position.Center) {
if (!target || target === 'center') {
const activePanel = sourceGroup.activePanel;
const panels = [...sourceGroup.panels].map((p) =>
sourceGroup.model.removePanel(p.id)

View File

@ -14,6 +14,7 @@ import { FrameworkFactory } from '../types';
import { DockviewDropTargets } from '../groupview/dnd';
import { PanelTransfer } from '../dnd/dataTransfer';
import { IGroupControlRenderer } from '../react/dockview/groupControlsRenderer';
import { Position } from '../dnd/droptarget';
export interface GroupPanelFrameworkComponentFactory {
content: FrameworkFactory<IContentRenderer>;
@ -54,7 +55,8 @@ export interface ViewFactoryData {
export interface DockviewDndOverlayEvent {
nativeEvent: DragEvent;
target: DockviewDropTargets;
group: GroupPanel;
position: Position;
group?: GroupPanel;
getData: () => PanelTransfer | undefined;
}

View File

@ -15,19 +15,19 @@ const nextLayoutId = sequentialNumberGenerator();
export type Direction = 'left' | 'right' | 'above' | 'below' | 'within';
export function toTarget(direction: Direction) {
export function toTarget(direction: Direction): Position {
switch (direction) {
case 'left':
return Position.Left;
return 'left';
case 'right':
return Position.Right;
return 'right';
case 'above':
return Position.Top;
return 'top';
case 'below':
return Position.Bottom;
return 'bottom';
case 'within':
default:
return Position.Center;
return 'center';
}
}

View File

@ -9,13 +9,13 @@ import {
Orientation,
Sizing,
} from '../splitview/core/splitview';
import { Position } from '../dnd/droptarget';
import { tail } from '../array';
import { LeafNode } from './leafNode';
import { BranchNode } from './branchNode';
import { Node } from './types';
import { Emitter, Event } from '../events';
import { IDisposable, MutableDisposable } from '../lifecycle';
import { Position } from '../dnd/droptarget';
function findLeaf(candiateNode: Node, last: boolean): LeafNode {
if (candiateNode instanceof LeafNode) {
@ -132,22 +132,19 @@ export function getRelativeLocation(
const [rest, _index] = tail(location);
let index = _index;
if (direction === Position.Right || direction === Position.Bottom) {
if (direction === 'right' || direction === 'bottom') {
index += 1;
}
return [...rest, index];
} else {
const index =
direction === Position.Right || direction === Position.Bottom
? 1
: 0;
const index = direction === 'right' || direction === 'bottom' ? 1 : 0;
return [...location, index];
}
}
export function getDirectionOrientation(direction: Position): Orientation {
return direction === Position.Top || direction === Position.Bottom
return direction === 'top' || direction === 'bottom'
? Orientation.VERTICAL
: Orientation.HORIZONTAL;
}

View File

@ -3,7 +3,6 @@ import {
SerializedGridObject,
getGridLocation,
} from './gridview';
import { Position } from '../dnd/droptarget';
import { tail, sequenceEquals } from '../array';
import { CompositeDisposable } from '../lifecycle';
import { IPanelDeserializer } from '../dockview/deserializer';
@ -25,6 +24,7 @@ import { BaseComponentOptions } from '../panel/types';
import { Orientation, Sizing } from '../splitview/core/splitview';
import { createComponent } from '../panel/componentFactory';
import { Emitter, Event } from '../events';
import { Position } from '../dnd/droptarget';
export interface SerializedGridview {
grid: {
@ -265,7 +265,7 @@ export class GridviewComponent
}
const target = toTarget(options.direction);
if (target === Position.Center) {
if (target === 'center') {
throw new Error(`${target} not supported as an option`);
} else {
const location = getGridLocation(referenceGroup.element);
@ -294,7 +294,7 @@ export class GridviewComponent
}
const target = toTarget(options.position.direction);
if (target === Position.Center) {
if (target === 'center') {
throw new Error(`${target} not supported as an option`);
} else {
const location = getGridLocation(referenceGroup.element);

View File

@ -2,4 +2,5 @@ export enum DockviewDropTargets {
Tab,
Panel,
TabContainer,
Edge,
}

View File

@ -110,7 +110,11 @@ export interface IGroupview extends IDisposable, IGridPanelView {
panel?: IDockviewPanel;
suppressRoll?: boolean;
}): void;
canDisplayOverlay(event: DragEvent, target: DockviewDropTargets): boolean;
canDisplayOverlay(
event: DragEvent,
position: Position,
target: DockviewDropTargets
): boolean;
}
export class Groupview extends CompositeDisposable implements IGroupview {
@ -240,17 +244,23 @@ export class Groupview extends CompositeDisposable implements IGroupview {
this.dropTarget = new Droptarget(this.contentContainer.element, {
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
canDisplayOverlay: (event, quadrant) => {
if (this.locked && !quadrant) {
canDisplayOverlay: (event, position) => {
if (this.locked && position === 'center') {
return false;
}
const data = getPanelData();
if (data && data.viewId === this.accessor.id) {
if (data.panelId === null && data.groupId === this.id) {
// don't allow group move to drop on self
return false;
if (data.groupId === this.id) {
if (position === 'center') {
// don't allow to drop on self for center position
return false;
}
if (data.panelId === null) {
// don't allow group move to drop anywhere on self
return false;
}
}
const groupHasOnePanelAndIsActiveDragElement =
@ -259,7 +269,11 @@ export class Groupview extends CompositeDisposable implements IGroupview {
return !groupHasOnePanelAndIsActiveDragElement;
}
return this.canDisplayOverlay(event, DockviewDropTargets.Panel);
return this.canDisplayOverlay(
event,
position,
DockviewDropTargets.Panel
);
},
});
@ -279,7 +293,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
this._onDidRemovePanel,
this._onDidActivePanelChange,
this.tabsContainer.onDrop((event) => {
this.handleDropEvent(event.event, Position.Center, event.index);
this.handleDropEvent(event.event, 'center', event.index);
}),
this.contentContainer.onDidFocus(() => {
this.accessor.doSetGroupActive(this.groupPanel, true);
@ -673,13 +687,18 @@ export class Groupview extends CompositeDisposable implements IGroupview {
}
}
canDisplayOverlay(event: DragEvent, target: DockviewDropTargets): boolean {
canDisplayOverlay(
event: DragEvent,
position: Position,
target: DockviewDropTargets
): boolean {
// custom overlay handler
if (this.accessor.options.showDndOverlay) {
return this.accessor.options.showDndOverlay({
nativeEvent: event,
target,
group: this.accessor.getPanel(this.id)!,
position,
getData: getPanelData,
});
}

View File

@ -98,7 +98,7 @@ export class Tab extends CompositeDisposable implements ITab {
this.droptarget = new Droptarget(this._element, {
acceptedTargetZones: ['center'],
canDisplayOverlay: (event) => {
canDisplayOverlay: (event, position) => {
if (this.group.locked) {
return false;
}
@ -119,6 +119,7 @@ export class Tab extends CompositeDisposable implements ITab {
return this.group.model.canDisplayOverlay(
event,
position,
DockviewDropTargets.Tab
);
},

View File

@ -42,7 +42,7 @@ export class VoidContainer extends CompositeDisposable {
this.voidDropTarget = new Droptarget(this._element, {
acceptedTargetZones: ['center'],
canDisplayOverlay: (event) => {
canDisplayOverlay: (event, position) => {
const data = getPanelData();
if (data && this.accessor.id === data.viewId) {
@ -60,6 +60,7 @@ export class VoidContainer extends CompositeDisposable {
return group.model.canDisplayOverlay(
event,
position,
DockviewDropTargets.Panel
);
},

View File

@ -27,7 +27,7 @@ export * from './react'; // TODO: should be conditional on whether user wants th
export { Event } from './events';
export { IDisposable } from './lifecycle';
export { Position } from './dnd/droptarget';
export { Position as DropTargetDirections } from './dnd/droptarget';
export {
FocusEvent,
PanelDimensionChangeEvent,

View File

@ -4,7 +4,7 @@ import {
LocalSelectionTransfer,
PaneTransfer,
} from '../dnd/dataTransfer';
import { Droptarget, DroptargetEvent, Position } from '../dnd/droptarget';
import { Droptarget, DroptargetEvent } from '../dnd/droptarget';
import { Emitter } from '../events';
import { IDisposable } from '../lifecycle';
import { Orientation } from '../splitview/core/splitview';
@ -142,16 +142,10 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
const fromIndex = allPanels.indexOf(existingPanel);
let toIndex = containerApi.panels.indexOf(this);
if (
event.position === Position.Left ||
event.position === Position.Top
) {
if (event.position === 'left' || event.position === 'top') {
toIndex = Math.max(0, toIndex - 1);
}
if (
event.position === Position.Right ||
event.position === Position.Bottom
) {
if (event.position === 'right' || event.position === 'bottom') {
if (fromIndex > toIndex) {
toIndex++;
}