feat : drag intercept examples

This commit is contained in:
mathuo 2023-08-29 20:22:23 +01:00
parent 6c2d511827
commit bfa4f60288
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
3 changed files with 107 additions and 22 deletions

View File

@ -38,6 +38,10 @@ import {
import { Emitter, Event } from '../events'; import { Emitter, Event } from '../events';
import { IDockviewPanel } from '../dockview/dockviewPanel'; import { IDockviewPanel } from '../dockview/dockviewPanel';
import { PaneviewDropEvent } from '../paneview/draggablePaneviewPanel'; import { PaneviewDropEvent } from '../paneview/draggablePaneviewPanel';
import {
GroupDragEvent,
TabDragEvent,
} from '../dockview/components/titlebar/tabsContainer';
export interface CommonApi<T = any> { export interface CommonApi<T = any> {
readonly height: number; readonly height: number;
@ -118,7 +122,9 @@ export class SplitviewApi implements CommonApi<SerializedSplitview> {
return this.component.layout(width, height); return this.component.layout(width, height);
} }
addPanel<T extends object = Parameters>(options: AddSplitviewComponentOptions<T>): ISplitviewPanel { addPanel<T extends object = Parameters>(
options: AddSplitviewComponentOptions<T>
): ISplitviewPanel {
return this.component.addPanel(options); return this.component.addPanel(options);
} }
@ -213,7 +219,9 @@ export class PaneviewApi implements CommonApi<SerializedPaneview> {
this.component.layout(width, height); this.component.layout(width, height);
} }
addPanel<T extends object = Parameters>(options: AddPaneviewComponentOptions<T>): IPaneviewPanel { addPanel<T extends object = Parameters>(
options: AddPaneviewComponentOptions<T>
): IPaneviewPanel {
return this.component.addPanel(options); return this.component.addPanel(options);
} }
@ -297,7 +305,9 @@ export class GridviewApi implements CommonApi<SerializedGridviewComponent> {
this.component.layout(width, height, force); this.component.layout(width, height, force);
} }
addPanel<T extends object = Parameters>(options: AddComponentOptions<T>): IGridviewPanel { addPanel<T extends object = Parameters>(
options: AddComponentOptions<T>
): IGridviewPanel {
return this.component.addPanel(options); return this.component.addPanel(options);
} }
@ -402,6 +412,14 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
return this.component.onDidDrop; return this.component.onDidDrop;
} }
get onWillDragGroup(): Event<GroupDragEvent> {
return this.component.onWillDragGroup;
}
get onWillDragPanel(): Event<TabDragEvent> {
return this.component.onWillDragPanel;
}
get panels(): IDockviewPanel[] { get panels(): IDockviewPanel[] {
return this.component.panels; return this.component.panels;
} }
@ -432,7 +450,9 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
this.component.layout(width, height, force); this.component.layout(width, height, force);
} }
addPanel<T extends object = Parameters>(options: AddPanelOptions<T>): IDockviewPanel { addPanel<T extends object = Parameters>(
options: AddPanelOptions<T>
): IDockviewPanel {
return this.component.addPanel(options); return this.component.addPanel(options);
} }

View File

@ -66,19 +66,23 @@ export abstract class DragHandler extends CompositeDisposable {
if (event.dataTransfer) { if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.effectAllowed = 'move';
/** const hasData = event.dataTransfer.items.length > 0;
* Although this is not used by dockview many third party dnd libraries will check
* dataTransfer.types to determine valid drag events. if (!hasData) {
* /**
* For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled * Although this is not used by dockview many third party dnd libraries will check
* through .preventDefault(). Since this is applied globally to all drag events this would break dockviews * dataTransfer.types to determine valid drag events.
* dnd logic. You can see the code at *
* https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542 * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
*/ * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
event.dataTransfer.setData( * dnd logic. You can see the code at
'text/plain', * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
'__dockview_internal_drag_event__' */
); event.dataTransfer.setData(
'text/plain',
'__dockview_internal_drag_event__'
);
}
} }
}), }),
addDisposableListener(this.el, 'dragend', () => { addDisposableListener(this.el, 'dragend', () => {

View File

@ -1,4 +1,5 @@
import { import {
DockviewApi,
DockviewDndOverlayEvent, DockviewDndOverlayEvent,
DockviewDropEvent, DockviewDropEvent,
DockviewReact, DockviewReact,
@ -42,8 +43,14 @@ const DraggableElement = () => (
); );
const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => { const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
const onReady = (event: DockviewReadyEvent) => { const [api, setApi] = React.useState<DockviewApi>();
event.api.addPanel({
React.useEffect(() => {
if (!api) {
return;
}
api.addPanel({
id: 'panel_1', id: 'panel_1',
component: 'default', component: 'default',
params: { params: {
@ -51,7 +58,7 @@ const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
}, },
}); });
event.api.addPanel({ api.addPanel({
id: 'panel_2', id: 'panel_2',
component: 'default', component: 'default',
params: { params: {
@ -59,7 +66,7 @@ const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
}, },
}); });
event.api.addPanel({ api.addPanel({
id: 'panel_3', id: 'panel_3',
component: 'default', component: 'default',
params: { params: {
@ -67,7 +74,7 @@ const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
}, },
}); });
event.api.addPanel({ api.addPanel({
id: 'panel_4', id: 'panel_4',
component: 'default', component: 'default',
params: { params: {
@ -75,6 +82,45 @@ const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
}, },
position: { referencePanel: 'panel_1', direction: 'right' }, position: { referencePanel: 'panel_1', direction: 'right' },
}); });
const panelDragDisposable = api.onWillDragPanel((event) => {
const dataTransfer = event.nativeEvent.dataTransfer;
if (dataTransfer) {
dataTransfer.setData(
'text/plain',
'Some custom panel data transfer data'
);
dataTransfer.setData(
'text/json',
'{text: "Some custom panel data transfer data"}'
);
}
});
const groupDragDisposable = api.onWillDragGroup((event) => {
const dataTransfer = event.nativeEvent.dataTransfer;
if (dataTransfer) {
dataTransfer.setData(
'text/plain',
'Some custom group data transfer data'
);
dataTransfer.setData(
'text/json',
'{text: "Some custom group data transfer data"}'
);
}
});
return () => {
panelDragDisposable.dispose();
groupDragDisposable.dispose();
};
}, [api]);
const onReady = (event: DockviewReadyEvent) => {
setApi(event.api);
}; };
const onDidDrop = (event: DockviewDropEvent) => { const onDidDrop = (event: DockviewDropEvent) => {
@ -92,6 +138,20 @@ const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
return true; return true;
}; };
const onDrop = (event: React.DragEvent) => {
const dataTransfer = event.dataTransfer;
let text = 'The following dataTransfer data was found:\n';
for (let i = 0; i < dataTransfer.items.length; i++) {
const item = dataTransfer.items[i];
const value = dataTransfer.getData(item.type);
text += `type=${item.type},data=${value}\n`;
}
alert(text);
};
return ( return (
<div <div
style={{ style={{
@ -102,6 +162,7 @@ const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
> >
<div style={{ margin: '2px 0px' }}> <div style={{ margin: '2px 0px' }}>
<DraggableElement /> <DraggableElement />
<div onDrop={onDrop}>Inspect Data Transfer</div>
</div> </div>
<DockviewReact <DockviewReact
components={components} components={components}