diff --git a/packages/dockview-core/src/api/component.api.ts b/packages/dockview-core/src/api/component.api.ts index 01bff2a8c..9073ce096 100644 --- a/packages/dockview-core/src/api/component.api.ts +++ b/packages/dockview-core/src/api/component.api.ts @@ -40,7 +40,7 @@ import { } from '../dockview/dockviewGroupPanel'; import { Emitter, Event } from '../events'; import { IDockviewPanel } from '../dockview/dockviewPanel'; -import { PaneviewDropEvent } from '../paneview/draggablePaneviewPanel'; +import { PaneviewDidDropEvent } from '../paneview/draggablePaneviewPanel'; import { GroupDragEvent, TabDragEvent, @@ -51,7 +51,10 @@ import { DockviewWillDropEvent, WillShowOverlayLocationEvent, } from '../dockview/dockviewGroupPanelModel'; -import { PaneviewComponentOptions } from '../paneview/options'; +import { + PaneviewComponentOptions, + PaneviewDndOverlayEvent, +} from '../paneview/options'; import { SplitviewComponentOptions } from '../splitview/options'; import { GridviewComponentOptions } from '../gridview/options'; @@ -294,19 +297,12 @@ export class PaneviewApi implements CommonApi { /** * Invoked when a Drag'n'Drop event occurs that the component was unable to handle. Exposed for custom Drag'n'Drop functionality. */ - get onDidDrop(): Event { - const emitter = new Emitter(); - - const disposable = this.component.onDidDrop((e) => { - emitter.fire({ ...e, api: this }); - }); - - emitter.dispose = () => { - disposable.dispose(); - emitter.dispose(); - }; + get onDidDrop(): Event { + return this.component.onDidDrop; + } - return emitter.event; + get onUnhandledDragOverEvent(): Event { + return this.component.onUnhandledDragOverEvent; } constructor(private readonly component: IPaneviewComponent) {} diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index 05175190a..3f7b94367 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -16,6 +16,7 @@ import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer'; import { IGroupHeaderProps } from './framework'; import { FloatingGroupOptions } from './dockviewComponent'; import { Contraints } from '../gridview/gridviewPanel'; +import { AcceptableEvent, IAcceptableEvent } from '../events'; export interface IHeaderActionsRenderer extends IDisposable { readonly element: HTMLElement; @@ -65,34 +66,26 @@ export interface DockviewOptions { noPanelsOverlay?: 'emptyGroup' | 'watermark'; } -export interface DockviewDndOverlayEvent { +export interface DockviewDndOverlayEvent extends IAcceptableEvent { nativeEvent: DragEvent; target: DockviewGroupDropLocation; position: Position; group?: DockviewGroupPanel; getData: () => PanelTransfer | undefined; - // - isAccepted: boolean; - accept(): void; } -export class DockviewUnhandledDragOverEvent implements DockviewDndOverlayEvent { - private _isAccepted = false; - - get isAccepted(): boolean { - return this._isAccepted; - } - +export class DockviewUnhandledDragOverEvent + extends AcceptableEvent + implements DockviewDndOverlayEvent +{ constructor( readonly nativeEvent: DragEvent, readonly target: DockviewGroupDropLocation, readonly position: Position, readonly getData: () => PanelTransfer | undefined, readonly group?: DockviewGroupPanel - ) {} - - accept(): void { - this._isAccepted = true; + ) { + super(); } } diff --git a/packages/dockview-core/src/events.ts b/packages/dockview-core/src/events.ts index 5c7d0d260..d9cbf32d6 100644 --- a/packages/dockview-core/src/events.ts +++ b/packages/dockview-core/src/events.ts @@ -41,6 +41,23 @@ export class DockviewEvent implements IDockviewEvent { } } +export interface IAcceptableEvent { + readonly isAccepted: boolean; + accept(): void; +} + +export class AcceptableEvent implements IAcceptableEvent { + private _isAccepted = false; + + get isAccepted(): boolean { + return this._isAccepted; + } + + accept(): void { + this._isAccepted = true; + } +} + class LeakageMonitor { readonly events = new Map, Stacktrace>(); diff --git a/packages/dockview-core/src/index.ts b/packages/dockview-core/src/index.ts index dfaec589f..9764f658a 100644 --- a/packages/dockview-core/src/index.ts +++ b/packages/dockview-core/src/index.ts @@ -41,7 +41,7 @@ export * from './gridview/baseComponentGridview'; export { DraggablePaneviewPanel, - PaneviewDropEvent, + PaneviewDidDropEvent as PaneviewDropEvent, } from './paneview/draggablePaneviewPanel'; export * from './dockview/components/panel/content'; @@ -80,6 +80,8 @@ export { PaneviewOptions, PaneviewFrameworkOptions, PROPERTY_KEYS_PANEVIEW, + PaneviewUnhandledDragOverEvent, + PaneviewDndOverlayEvent, } from './paneview/options'; export * from './gridview/gridviewPanel'; diff --git a/packages/dockview-core/src/paneview/draggablePaneviewPanel.ts b/packages/dockview-core/src/paneview/draggablePaneviewPanel.ts index b86c06d33..7227ea46a 100644 --- a/packages/dockview-core/src/paneview/draggablePaneviewPanel.ts +++ b/packages/dockview-core/src/paneview/draggablePaneviewPanel.ts @@ -6,9 +6,13 @@ import { PaneTransfer, } from '../dnd/dataTransfer'; import { Droptarget, DroptargetEvent } from '../dnd/droptarget'; -import { Emitter } from '../events'; +import { Emitter, Event } from '../events'; import { IDisposable } from '../lifecycle'; import { Orientation } from '../splitview/splitview'; +import { + PaneviewDndOverlayEvent, + PaneviewUnhandledDragOverEvent, +} from './options'; import { IPaneviewComponent } from './paneviewComponent'; import { IPaneviewPanel, @@ -16,7 +20,7 @@ import { PaneviewPanel, } from './paneviewPanel'; -export interface PaneviewDropEvent extends DroptargetEvent { +export interface PaneviewDidDropEvent extends DroptargetEvent { panel: IPaneviewPanel; getData: () => PaneTransfer | undefined; api: PaneviewApi; @@ -26,9 +30,14 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel { private handler: DragHandler | undefined; private target: Droptarget | undefined; - private readonly _onDidDrop = new Emitter(); + private readonly _onDidDrop = new Emitter(); readonly onDidDrop = this._onDidDrop.event; + private readonly _onUnhandledDragOverEvent = + new Emitter(); + readonly onUnhandledDragOverEvent: Event = + this._onUnhandledDragOverEvent.event; + constructor( private readonly accessor: IPaneviewComponent, id: string, @@ -40,6 +49,8 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel { ) { super(id, component, headerComponent, orientation, isExpanded, true); + this.addDisposables(this._onDidDrop, this._onUnhandledDragOverEvent); + if (!disableDnd) { this.initDragFeatures(); } @@ -76,7 +87,7 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel { overlayModel: { activationSize: { type: 'percentage', value: 50 }, }, - canDisplayOverlay: (event) => { + canDisplayOverlay: (event, position) => { const data = getPaneData(); if (data) { @@ -88,15 +99,16 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel { } } - if (this.accessor.options.showDndOverlay) { - return this.accessor.options.showDndOverlay({ - nativeEvent: event, - getData: getPaneData, - panel: this, - }); - } + const firedEvent = new PaneviewUnhandledDragOverEvent( + event, + position, + getPaneData, + this + ); + + this._onUnhandledDragOverEvent.fire(firedEvent); - return false; + return firedEvent.isAccepted; }, }); diff --git a/packages/dockview-core/src/paneview/options.ts b/packages/dockview-core/src/paneview/options.ts index f7702638a..f51e28dce 100644 --- a/packages/dockview-core/src/paneview/options.ts +++ b/packages/dockview-core/src/paneview/options.ts @@ -1,11 +1,12 @@ +import { PaneTransfer } from '../dnd/dataTransfer'; +import { Position } from '../dnd/droptarget'; import { CreateComponentOptions } from '../dockview/options'; -import { PaneviewDndOverlayEvent } from './paneviewComponent'; -import { IPanePart } from './paneviewPanel'; +import { AcceptableEvent, IAcceptableEvent } from '../events'; +import { IPanePart, IPaneviewPanel } from './paneviewPanel'; export interface PaneviewOptions { disableAutoResizing?: boolean; disableDnd?: boolean; - showDndOverlay?: (event: PaneviewDndOverlayEvent) => boolean; className?: string; } @@ -27,9 +28,29 @@ export const PROPERTY_KEYS_PANEVIEW: (keyof PaneviewOptions)[] = (() => { const properties: Record = { disableAutoResizing: undefined, disableDnd: undefined, - showDndOverlay: undefined, className: undefined, }; return Object.keys(properties) as (keyof PaneviewOptions)[]; })(); + +export interface PaneviewDndOverlayEvent extends IAcceptableEvent { + nativeEvent: DragEvent; + position: Position; + panel: IPaneviewPanel; + getData: () => PaneTransfer | undefined; +} + +export class PaneviewUnhandledDragOverEvent + extends AcceptableEvent + implements PaneviewDndOverlayEvent +{ + constructor( + readonly nativeEvent: DragEvent, + readonly position: Position, + readonly getData: () => PaneTransfer | undefined, + readonly panel: IPaneviewPanel + ) { + super(); + } +} diff --git a/packages/dockview-core/src/paneview/paneviewComponent.ts b/packages/dockview-core/src/paneview/paneviewComponent.ts index 651f5f406..2ee9d5820 100644 --- a/packages/dockview-core/src/paneview/paneviewComponent.ts +++ b/packages/dockview-core/src/paneview/paneviewComponent.ts @@ -6,12 +6,12 @@ import { MutableDisposable, } from '../lifecycle'; import { LayoutPriority, Orientation, Sizing } from '../splitview/splitview'; -import { PaneviewComponentOptions } from './options'; +import { PaneviewComponentOptions, PaneviewDndOverlayEvent } from './options'; import { Paneview } from './paneview'; import { IPanePart, PaneviewPanel, IPaneviewPanel } from './paneviewPanel'; import { DraggablePaneviewPanel, - PaneviewDropEvent, + PaneviewDidDropEvent, } from './draggablePaneviewPanel'; import { DefaultHeader } from './defaultPaneviewHeader'; import { sequentialNumberGenerator } from '../math'; @@ -22,12 +22,6 @@ import { Classnames } from '../dom'; const nextLayoutId = sequentialNumberGenerator(); -export interface PaneviewDndOverlayEvent { - nativeEvent: DragEvent; - panel: IPaneviewPanel; - getData: () => PaneTransfer | undefined; -} - export interface SerializedPaneviewPanel { snap?: boolean; priority?: LayoutPriority; @@ -106,9 +100,10 @@ export interface IPaneviewComponent extends IDisposable { readonly options: PaneviewComponentOptions; readonly onDidAddView: Event; readonly onDidRemoveView: Event; - readonly onDidDrop: Event; + readonly onDidDrop: Event; readonly onDidLayoutChange: Event; readonly onDidLayoutFromJSON: Event; + readonly onUnhandledDragOverEvent: Event; addPanel( options: AddPaneviewComponentOptions ): IPaneviewPanel; @@ -137,8 +132,8 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent { private readonly _onDidLayoutChange = new Emitter(); readonly onDidLayoutChange: Event = this._onDidLayoutChange.event; - private readonly _onDidDrop = new Emitter(); - readonly onDidDrop: Event = this._onDidDrop.event; + private readonly _onDidDrop = new Emitter(); + readonly onDidDrop: Event = this._onDidDrop.event; private readonly _onDidAddView = new Emitter(); readonly onDidAddView = this._onDidAddView.event; @@ -146,6 +141,11 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent { private readonly _onDidRemoveView = new Emitter(); readonly onDidRemoveView = this._onDidRemoveView.event; + private readonly _onUnhandledDragOverEvent = + new Emitter(); + readonly onUnhandledDragOverEvent: Event = + this._onUnhandledDragOverEvent.event; + private readonly _classNames: Classnames; get id(): string { @@ -204,7 +204,8 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent { this._onDidLayoutfromJSON, this._onDidDrop, this._onDidAddView, - this._onDidRemoveView + this._onDidRemoveView, + this._onUnhandledDragOverEvent ); this._classNames = new Classnames(this.element); @@ -442,9 +443,14 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent { } private doAddPanel(panel: PaneFramework): void { - const disposable = panel.onDidDrop((event) => { - this._onDidDrop.fire(event); - }); + const disposable = new CompositeDisposable( + panel.onDidDrop((event) => { + this._onDidDrop.fire(event); + }), + panel.onUnhandledDragOverEvent((event) => { + this._onUnhandledDragOverEvent.fire(event); + }) + ); this._viewDisposables.set(panel.id, disposable); } diff --git a/packages/dockview/src/paneview/paneview.tsx b/packages/dockview/src/paneview/paneview.tsx index 2dc623638..34ab300b9 100644 --- a/packages/dockview/src/paneview/paneview.tsx +++ b/packages/dockview/src/paneview/paneview.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { PaneviewPanelApi, - PaneviewDndOverlayEvent, PaneviewApi, PaneviewDropEvent, createPaneview, @@ -32,7 +31,6 @@ export interface IPaneviewReactProps extends PaneviewOptions { string, React.FunctionComponent >; - showDndOverlay?: (event: PaneviewDndOverlayEvent) => boolean; onDidDrop?(event: PaneviewDropEvent): void; } @@ -177,15 +175,6 @@ export const PaneviewReact = React.forwardRef( }; }, [props.onDidDrop]); - React.useEffect(() => { - if (!paneviewRef.current) { - return; - } - paneviewRef.current.updateOptions({ - showDndOverlay: props.showDndOverlay, - }); - }, [props.showDndOverlay]); - return (
", + "kind": "property", + "type": { + "type": "reference", + "value": "Event", + "source": "dockview-core", + "typeArguments": [ + { + "type": "reference", + "value": "PaneviewDndOverlayEvent", + "source": "dockview-core" + } + ] + }, + "flags": { + "isReadonly": true + } + }, { "name": "part", "code": "IFrameworkPart", @@ -15115,6 +15137,26 @@ "isReadonly": true } }, + { + "name": "onUnhandledDragOverEvent", + "code": "Event", + "kind": "property", + "type": { + "type": "reference", + "value": "Event", + "source": "dockview-core", + "typeArguments": [ + { + "type": "reference", + "value": "PaneviewDndOverlayEvent", + "source": "dockview-core" + } + ] + }, + "flags": { + "isReadonly": true + } + }, { "name": "part", "code": "IFrameworkPart", @@ -16584,6 +16626,28 @@ ] } }, + { + "name": "onUnhandledDragOverEvent", + "code": "Event", + "kind": "accessor", + "value": { + "name": "onUnhandledDragOverEvent", + "code": "Event", + "kind": "getSignature", + "returnType": { + "type": "reference", + "value": "Event", + "source": "dockview-core", + "typeArguments": [ + { + "type": "reference", + "value": "PaneviewDndOverlayEvent", + "source": "dockview-core" + } + ] + } + } + }, { "name": "panels", "code": "IPaneviewPanel[]", @@ -17292,6 +17356,26 @@ "isReadonly": true } }, + { + "name": "onUnhandledDragOverEvent", + "code": "Event", + "kind": "property", + "type": { + "type": "reference", + "value": "Event", + "source": "dockview-core", + "typeArguments": [ + { + "type": "reference", + "value": "PaneviewDndOverlayEvent", + "source": "dockview-core" + } + ] + }, + "flags": { + "isReadonly": true + } + }, { "name": "disableResizing", "code": "boolean", @@ -19487,7 +19571,7 @@ "summary": [ { "kind": "text", - "text": "Invoked whenever any aspect of the layout changes.\r\nIf listening to this event it may be worth debouncing ouputs." + "text": "Invoked whenever any aspect of the layout changes.\nIf listening to this event it may be worth debouncing ouputs." } ] }, @@ -19509,7 +19593,7 @@ "summary": [ { "kind": "text", - "text": "Invoked whenever any aspect of the layout changes.\r\nIf listening to this event it may be worth debouncing ouputs." + "text": "Invoked whenever any aspect of the layout changes.\nIf listening to this event it may be worth debouncing ouputs." } ] } @@ -20105,7 +20189,7 @@ }, { "kind": "text", - "text": " method\r\nfor the subsequent resize." + "text": " method\nfor the subsequent resize." } ] }, @@ -20167,7 +20251,7 @@ }, { "kind": "text", - "text": " method\r\nfor the subsequent resize." + "text": " method\nfor the subsequent resize." } ] } @@ -23092,7 +23176,9 @@ "type": "intrinsic", "value": "boolean" }, - "flags": {} + "flags": { + "isReadonly": true + } }, { "name": "nativeEvent", @@ -23146,7 +23232,9 @@ ] } ], - "extends": [] + "extends": [ + "IAcceptableEvent" + ] }, "DockviewFrameworkOptions": { "kind": "interface", @@ -24288,7 +24376,7 @@ }, { "kind": "text", - "text": ".\r\nCall " + "text": ".\nCall " }, { "kind": "code", @@ -35161,6 +35249,26 @@ "isReadonly": true } }, + { + "name": "onUnhandledDragOverEvent", + "code": "Event", + "kind": "property", + "type": { + "type": "reference", + "value": "Event", + "source": "dockview-core", + "typeArguments": [ + { + "type": "reference", + "value": "PaneviewDndOverlayEvent", + "source": "dockview-core" + } + ] + }, + "flags": { + "isReadonly": true + } + }, { "name": "options", "code": "PaneviewComponentOptions", @@ -38650,72 +38758,6 @@ "PanelInitParameters" ] }, - "PaneviewDndOverlayEvent": { - "kind": "interface", - "name": "PaneviewDndOverlayEvent", - "children": [ - { - "name": "getData", - "code": "(): PaneTransfer | undefined", - "kind": "property", - "type": { - "type": "reflection", - "value": { - "name": "__type", - "code": "(): PaneTransfer | undefined", - "kind": "typeLiteral", - "signatures": [ - { - "name": "__type", - "typeParameters": [], - "parameters": [], - "returnType": { - "type": "or", - "values": [ - { - "type": "reference", - "value": "PaneTransfer", - "source": "dockview-core" - }, - { - "type": "intrinsic", - "value": "undefined" - } - ] - }, - "code": "(): PaneTransfer | undefined", - "kind": "callSignature" - } - ] - } - }, - "flags": {} - }, - { - "name": "nativeEvent", - "code": "DragEvent", - "kind": "property", - "type": { - "type": "reference", - "value": "DragEvent", - "source": "typescript" - }, - "flags": {} - }, - { - "name": "panel", - "code": "IPaneviewPanel", - "kind": "property", - "type": { - "type": "reference", - "value": "IPaneviewPanel", - "source": "dockview-core" - }, - "flags": {} - } - ], - "extends": [] - }, "PaneviewDropEvent": { "kind": "interface", "name": "PaneviewDropEvent", @@ -38945,46 +38987,6 @@ "flags": { "isOptional": true } - }, - { - "name": "showDndOverlay", - "code": "(event: PaneviewDndOverlayEvent): boolean", - "kind": "property", - "type": { - "type": "reflection", - "value": { - "name": "__type", - "code": "(event: PaneviewDndOverlayEvent): boolean", - "kind": "typeLiteral", - "signatures": [ - { - "name": "__type", - "typeParameters": [], - "parameters": [ - { - "name": "event", - "code": "event: PaneviewDndOverlayEvent", - "type": { - "type": "reference", - "value": "PaneviewDndOverlayEvent", - "source": "dockview-core" - }, - "kind": "parameter" - } - ], - "returnType": { - "type": "intrinsic", - "value": "boolean" - }, - "code": "(event: PaneviewDndOverlayEvent): boolean", - "kind": "callSignature" - } - ] - } - }, - "flags": { - "isOptional": true - } } ], "extends": [] @@ -41389,7 +41391,7 @@ "summary": [ { "kind": "text", - "text": "If true then add the panel without setting it as the active panel.\r\n\r\nDefaults to " + "text": "If true then add the panel without setting it as the active panel.\n\nDefaults to " }, { "kind": "code", @@ -41456,7 +41458,7 @@ "summary": [ { "kind": "text", - "text": "The rendering mode of the panel.\r\n\r\nThis dictates what happens to the HTML of the panel when it is hidden." + "text": "The rendering mode of the panel.\n\nThis dictates what happens to the HTML of the panel when it is hidden." } ] } @@ -41496,7 +41498,7 @@ "summary": [ { "kind": "text", - "text": "The title for the panel which can be accessed within both the tab and component.\r\n\r\nIf using the default tab renderer this title will be displayed in the tab." + "text": "The title for the panel which can be accessed within both the tab and component.\n\nIf using the default tab renderer this title will be displayed in the tab." } ] } @@ -43524,46 +43526,6 @@ }, "flags": {} }, - { - "name": "showDndOverlay", - "code": "(event: PaneviewDndOverlayEvent): boolean", - "kind": "property", - "type": { - "type": "reflection", - "value": { - "name": "__type", - "code": "(event: PaneviewDndOverlayEvent): boolean", - "kind": "typeLiteral", - "signatures": [ - { - "name": "__type", - "typeParameters": [], - "parameters": [ - { - "name": "event", - "code": "event: PaneviewDndOverlayEvent", - "type": { - "type": "reference", - "value": "PaneviewDndOverlayEvent", - "source": "dockview-core" - }, - "kind": "parameter" - } - ], - "returnType": { - "type": "intrinsic", - "value": "boolean" - }, - "code": "(event: PaneviewDndOverlayEvent): boolean", - "kind": "callSignature" - } - ] - } - }, - "flags": { - "isOptional": true - } - }, { "name": "onDidDrop", "code": "(event: PaneviewDropEvent): void",