mirror of
https://github.com/mathuo/dockview
synced 2025-05-03 18:18:25 +00:00
feat: dockview custom dnd events
- remove old flag for external dnd events - add methods onDidDrop and showDndOverlay to allow interaction with custom dnd events
This commit is contained in:
parent
0b05115733
commit
c9eb954de8
@ -410,9 +410,14 @@ export const TestGrid = (props: IGridviewPanelProps) => {
|
|||||||
components={components}
|
components={components}
|
||||||
tabComponents={tabComponents}
|
tabComponents={tabComponents}
|
||||||
debug={false}
|
debug={false}
|
||||||
enableExternalDragEvents={true}
|
|
||||||
onTabContextMenu={onTabContextMenu}
|
onTabContextMenu={onTabContextMenu}
|
||||||
watermarkComponent={Watermark}
|
watermarkComponent={Watermark}
|
||||||
|
showDndOverlay={(ev, target) => {
|
||||||
|
return true;
|
||||||
|
}}
|
||||||
|
onDidDrop={(ev) => {
|
||||||
|
console.log('onDidDrop', ev);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -207,9 +207,7 @@ describe('groupview', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
dockview = <IDockviewComponent>(<any>{
|
dockview = <IDockviewComponent>(<any>{
|
||||||
options: {
|
options: {},
|
||||||
enableExternalDragEvents: false,
|
|
||||||
},
|
|
||||||
createWatermarkComponent: () => new Watermark(),
|
createWatermarkComponent: () => new Watermark(),
|
||||||
doSetGroupActive: jest.fn(),
|
doSetGroupActive: jest.fn(),
|
||||||
id: 'dockview-1',
|
id: 'dockview-1',
|
||||||
|
@ -41,6 +41,7 @@ import {
|
|||||||
GroupChangeKind2,
|
GroupChangeKind2,
|
||||||
GroupOptions,
|
GroupOptions,
|
||||||
GroupPanelViewState,
|
GroupPanelViewState,
|
||||||
|
GroupviewDropEvent,
|
||||||
} from '../groupview/groupview';
|
} from '../groupview/groupview';
|
||||||
import { GroupviewPanel } from '../groupview/groupviewPanel';
|
import { GroupviewPanel } from '../groupview/groupviewPanel';
|
||||||
import { DefaultGroupPanelView } from './defaultGroupPanelView';
|
import { DefaultGroupPanelView } from './defaultGroupPanelView';
|
||||||
@ -71,12 +72,18 @@ export type DockviewComponentUpdateOptions = Pick<
|
|||||||
| 'frameworkComponents'
|
| 'frameworkComponents'
|
||||||
| 'tabComponents'
|
| 'tabComponents'
|
||||||
| 'frameworkTabComponents'
|
| 'frameworkTabComponents'
|
||||||
|
| 'showDndOverlay'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
export interface DockviewDropEvent extends GroupviewDropEvent {
|
||||||
|
api: DockviewApi;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IDockviewComponent extends IBaseGrid<GroupviewPanel> {
|
export interface IDockviewComponent extends IBaseGrid<GroupviewPanel> {
|
||||||
readonly activePanel: IGroupPanel | undefined;
|
readonly activePanel: IGroupPanel | undefined;
|
||||||
readonly totalPanels: number;
|
readonly totalPanels: number;
|
||||||
readonly panels: IGroupPanel[];
|
readonly panels: IGroupPanel[];
|
||||||
|
readonly onDidDrop: Event<DockviewDropEvent>;
|
||||||
tabHeight: number | undefined;
|
tabHeight: number | undefined;
|
||||||
deserializer: IPanelDeserializer | undefined;
|
deserializer: IPanelDeserializer | undefined;
|
||||||
updateOptions(options: DockviewComponentUpdateOptions): void;
|
updateOptions(options: DockviewComponentUpdateOptions): void;
|
||||||
@ -124,9 +131,14 @@ export class DockviewComponent
|
|||||||
private readonly _onTabInteractionEvent = new Emitter<LayoutMouseEvent>();
|
private readonly _onTabInteractionEvent = new Emitter<LayoutMouseEvent>();
|
||||||
readonly onTabInteractionEvent: Event<LayoutMouseEvent> =
|
readonly onTabInteractionEvent: Event<LayoutMouseEvent> =
|
||||||
this._onTabInteractionEvent.event;
|
this._onTabInteractionEvent.event;
|
||||||
|
|
||||||
private readonly _onTabContextMenu = new Emitter<TabContextMenuEvent>();
|
private readonly _onTabContextMenu = new Emitter<TabContextMenuEvent>();
|
||||||
readonly onTabContextMenu: Event<TabContextMenuEvent> =
|
readonly onTabContextMenu: Event<TabContextMenuEvent> =
|
||||||
this._onTabContextMenu.event;
|
this._onTabContextMenu.event;
|
||||||
|
|
||||||
|
private readonly _onDidDrop = new Emitter<DockviewDropEvent>();
|
||||||
|
readonly onDidDrop: Event<DockviewDropEvent> = this._onDidDrop.event;
|
||||||
|
|
||||||
// everything else
|
// everything else
|
||||||
private _deserializer: IPanelDeserializer | undefined;
|
private _deserializer: IPanelDeserializer | undefined;
|
||||||
private panelState: State = {};
|
private panelState: State = {};
|
||||||
@ -668,6 +680,9 @@ export class DockviewComponent
|
|||||||
const { groupId, itemId, target, index } = event;
|
const { groupId, itemId, target, index } = event;
|
||||||
this.moveGroupOrPanel(view, groupId, itemId, target, index);
|
this.moveGroupOrPanel(view, groupId, itemId, target, index);
|
||||||
}),
|
}),
|
||||||
|
view.model.onDidDrop((event) => {
|
||||||
|
this._onDidDrop.fire({ ...event, api: this._api });
|
||||||
|
}),
|
||||||
view.model.onDidGroupChange((event) => {
|
view.model.onDidGroupChange((event) => {
|
||||||
switch (event.kind) {
|
switch (event.kind) {
|
||||||
case GroupChangeKind2.ADD_PANEL:
|
case GroupChangeKind2.ADD_PANEL:
|
||||||
@ -716,6 +731,9 @@ export class DockviewComponent
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
||||||
this._onGridEvent.dispose();
|
this._onGridEvent.dispose();
|
||||||
|
this._onDidDrop.dispose();
|
||||||
|
this._onTabContextMenu.dispose();
|
||||||
|
this._onTabInteractionEvent.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
import { GroupviewPanel } from '../groupview/groupviewPanel';
|
import { GroupviewPanel } from '../groupview/groupviewPanel';
|
||||||
import { ISplitviewStyles, Orientation } from '../splitview/core/splitview';
|
import { ISplitviewStyles, Orientation } from '../splitview/core/splitview';
|
||||||
import { FrameworkFactory } from '../types';
|
import { FrameworkFactory } from '../types';
|
||||||
|
import { DockviewDropTargets } from '../groupview/dnd';
|
||||||
|
|
||||||
export interface GroupPanelFrameworkComponentFactory {
|
export interface GroupPanelFrameworkComponentFactory {
|
||||||
content: FrameworkFactory<IContentRenderer>;
|
content: FrameworkFactory<IContentRenderer>;
|
||||||
@ -54,9 +55,9 @@ export interface DockviewOptions extends DockviewRenderFunctions {
|
|||||||
frameworkComponentFactory?: GroupPanelFrameworkComponentFactory;
|
frameworkComponentFactory?: GroupPanelFrameworkComponentFactory;
|
||||||
tabHeight?: number;
|
tabHeight?: number;
|
||||||
debug?: boolean;
|
debug?: boolean;
|
||||||
enableExternalDragEvents?: boolean;
|
|
||||||
orientation?: Orientation;
|
orientation?: Orientation;
|
||||||
styles?: ISplitviewStyles;
|
styles?: ISplitviewStyles;
|
||||||
|
showDndOverlay?: (event: DragEvent, target: DockviewDropTargets) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PanelOptions {
|
export interface PanelOptions {
|
||||||
|
@ -67,14 +67,21 @@ export interface GroupPanelViewState {
|
|||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GroupviewDropEvent {
|
||||||
|
nativeEvent: DragEvent;
|
||||||
|
position: Position;
|
||||||
|
index?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IGroupview extends IDisposable, IGridPanelView {
|
export interface IGroupview extends IDisposable, IGridPanelView {
|
||||||
readonly isActive: boolean;
|
readonly isActive: boolean;
|
||||||
readonly size: number;
|
readonly size: number;
|
||||||
readonly panels: IGroupPanel[];
|
readonly panels: IGroupPanel[];
|
||||||
readonly tabHeight: number | undefined;
|
readonly tabHeight: number | undefined;
|
||||||
|
readonly activePanel: IGroupPanel | undefined;
|
||||||
|
readonly onDidDrop: Event<GroupviewDropEvent>;
|
||||||
// state
|
// state
|
||||||
isPanelActive: (panel: IGroupPanel) => boolean;
|
isPanelActive: (panel: IGroupPanel) => boolean;
|
||||||
activePanel: IGroupPanel | undefined;
|
|
||||||
indexOf(panel: IGroupPanel): number;
|
indexOf(panel: IGroupPanel): number;
|
||||||
// panel lifecycle
|
// panel lifecycle
|
||||||
openPanel(
|
openPanel(
|
||||||
@ -124,6 +131,9 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
readonly onDidGroupChange: Event<GroupviewChangeEvent> =
|
readonly onDidGroupChange: Event<GroupviewChangeEvent> =
|
||||||
this._onDidGroupChange.event;
|
this._onDidGroupChange.event;
|
||||||
|
|
||||||
|
private readonly _onDidDrop = new Emitter<GroupviewDropEvent>();
|
||||||
|
readonly onDidDrop: Event<GroupviewDropEvent> = this._onDidDrop.event;
|
||||||
|
|
||||||
get element(): HTMLElement {
|
get element(): HTMLElement {
|
||||||
throw new Error('not supported');
|
throw new Error('not supported');
|
||||||
}
|
}
|
||||||
@ -184,7 +194,12 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
|
|
||||||
this.container.classList.add('groupview');
|
this.container.classList.add('groupview');
|
||||||
|
|
||||||
this.addDisposables(this._onMove, this._onDidGroupChange);
|
this.addDisposables(
|
||||||
|
this._onMove,
|
||||||
|
this._onDidGroupChange,
|
||||||
|
this._onDidChange,
|
||||||
|
this._onDidDrop
|
||||||
|
);
|
||||||
|
|
||||||
this.tabsContainer = new TabsContainer(this.accessor, this.parent, {
|
this.tabsContainer = new TabsContainer(this.accessor, this.parent, {
|
||||||
tabHeight: options.tabHeight,
|
tabHeight: options.tabHeight,
|
||||||
@ -619,11 +634,11 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canDisplayOverlay(
|
canDisplayOverlay(event: DragEvent, target: DockviewDropTargets): boolean {
|
||||||
dragOverEvent: DragEvent,
|
|
||||||
target: DockviewDropTargets
|
|
||||||
): boolean {
|
|
||||||
// custom overlay handler
|
// custom overlay handler
|
||||||
|
if (this.accessor.options.showDndOverlay) {
|
||||||
|
return this.accessor.options.showDndOverlay(event, target);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,7 +673,8 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
index,
|
index,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// custom drop handler
|
// TODO: custom drop handler
|
||||||
|
this._onDidDrop.fire({ nativeEvent: event, position, index });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { DockviewComponent } from '../../dockview/dockviewComponent';
|
import {
|
||||||
|
DockviewComponent,
|
||||||
|
DockviewDropEvent,
|
||||||
|
} from '../../dockview/dockviewComponent';
|
||||||
import { ReactPanelContentPart } from './reactContentPart';
|
import { ReactPanelContentPart } from './reactContentPart';
|
||||||
import { ReactPanelHeaderPart } from './reactHeaderPart';
|
import { ReactPanelHeaderPart } from './reactHeaderPart';
|
||||||
import { ReactPanelDeserialzier } from '../deserializer';
|
import { ReactPanelDeserialzier } from '../deserializer';
|
||||||
@ -14,6 +17,7 @@ import { ReactWatermarkPart } from './reactWatermarkPart';
|
|||||||
import { PanelCollection, PanelParameters } from '../types';
|
import { PanelCollection, PanelParameters } from '../types';
|
||||||
import { watchElementResize } from '../../dom';
|
import { watchElementResize } from '../../dom';
|
||||||
import { IContentRenderer, ITabRenderer } from '../../groupview/types';
|
import { IContentRenderer, ITabRenderer } from '../../groupview/types';
|
||||||
|
import { DockviewDropTargets } from '../../groupview/dnd';
|
||||||
|
|
||||||
export interface IGroupPanelBaseProps<T extends {} = Record<string, any>>
|
export interface IGroupPanelBaseProps<T extends {} = Record<string, any>>
|
||||||
extends PanelParameters<T> {
|
extends PanelParameters<T> {
|
||||||
@ -43,8 +47,9 @@ export interface IDockviewReactProps {
|
|||||||
onReady?: (event: DockviewReadyEvent) => void;
|
onReady?: (event: DockviewReadyEvent) => void;
|
||||||
debug?: boolean;
|
debug?: boolean;
|
||||||
tabHeight?: number;
|
tabHeight?: number;
|
||||||
enableExternalDragEvents?: boolean;
|
|
||||||
onTabContextMenu?: (event: TabContextMenuEvent) => void;
|
onTabContextMenu?: (event: TabContextMenuEvent) => void;
|
||||||
|
onDidDrop?: (event: DockviewDropEvent) => void;
|
||||||
|
showDndOverlay?: (event: DragEvent, target: DockviewDropTargets) => boolean;
|
||||||
hideBorders?: boolean;
|
hideBorders?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
disableAutoResizing?: boolean;
|
disableAutoResizing?: boolean;
|
||||||
@ -128,13 +133,18 @@ export const DockviewReact = React.forwardRef(
|
|||||||
frameworkTabComponents: props.tabComponents,
|
frameworkTabComponents: props.tabComponents,
|
||||||
tabHeight: props.tabHeight,
|
tabHeight: props.tabHeight,
|
||||||
debug: props.debug,
|
debug: props.debug,
|
||||||
enableExternalDragEvents: props.enableExternalDragEvents,
|
|
||||||
watermarkFrameworkComponent: props.watermarkComponent,
|
watermarkFrameworkComponent: props.watermarkComponent,
|
||||||
styles: props.hideBorders
|
styles: props.hideBorders
|
||||||
? { separatorBorder: 'transparent' }
|
? { separatorBorder: 'transparent' }
|
||||||
: undefined,
|
: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const disposable = dockview.onDidDrop((event) => {
|
||||||
|
if (props.onDidDrop) {
|
||||||
|
props.onDidDrop(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
domRef.current?.appendChild(dockview.element);
|
domRef.current?.appendChild(dockview.element);
|
||||||
dockview.deserializer = new ReactPanelDeserialzier(dockview);
|
dockview.deserializer = new ReactPanelDeserialzier(dockview);
|
||||||
|
|
||||||
@ -148,6 +158,7 @@ export const DockviewReact = React.forwardRef(
|
|||||||
dockviewRef.current = dockview;
|
dockviewRef.current = dockview;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
disposable.dispose();
|
||||||
dockview.dispose();
|
dockview.dispose();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
@ -161,6 +172,15 @@ export const DockviewReact = React.forwardRef(
|
|||||||
});
|
});
|
||||||
}, [props.components]);
|
}, [props.components]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!dockviewRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dockviewRef.current.updateOptions({
|
||||||
|
showDndOverlay: props.showDndOverlay,
|
||||||
|
});
|
||||||
|
}, [props.showDndOverlay]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!dockviewRef.current) {
|
if (!dockviewRef.current) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user