Skip to content

Commit

Permalink
feat: improved dnd model
Browse files Browse the repository at this point in the history
  • Loading branch information
mathuo committed Feb 2, 2025
1 parent bb93c9e commit ea1ba89
Show file tree
Hide file tree
Showing 26 changed files with 709 additions and 91 deletions.
6 changes: 4 additions & 2 deletions packages/dockview-core/src/dnd/abstractDragHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,17 @@ export abstract class DragHandler extends CompositeDisposable {
* 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
* dnd logic. You can see the code at
* https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
P * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
*/
event.dataTransfer.setData('text/plain', '');
}
}
}),
addDisposableListener(this.el, 'dragend', () => {
this.pointerEventsDisposable.dispose();
this.dataDisposable.dispose();
setTimeout(() => {
this.dataDisposable.dispose(); // allow the data to be read by other handlers before disposing
}, 0);
})
);
}
Expand Down
66 changes: 66 additions & 0 deletions packages/dockview-core/src/dnd/dropTragetAnchorContainer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { DropTargetTargetModel } from './droptarget';

export class DropTargetAnchorContainer {
private _model:
| { root: HTMLElement; overlay: HTMLElement; changed: boolean }
| undefined;

private _outline: HTMLElement | undefined;

get model(): DropTargetTargetModel {
return {
clear: () => {
this._model?.root.remove();
this._model = undefined;
},
exists: () => {
return !!this._model;
},
getElements: (event?: DragEvent, outline?: HTMLElement) => {
const changed = this._outline !== outline;
this._outline = outline;

if (this._model) {
this._model.changed = changed;
return this._model;
}

const container = this.createContainer();
const anchor = this.createAnchor();

this._model = { root: container, overlay: anchor, changed };

container.appendChild(anchor);
this.element.appendChild(container);

if (event?.target instanceof HTMLElement) {
const targetBox = event.target.getBoundingClientRect();
const box = this.element.getBoundingClientRect();
console.log(box, targetBox);

anchor.style.left = `${targetBox.left - box.left}px`;
anchor.style.top = `${targetBox.top - box.top}px`;
}

return this._model;
},
};
}

constructor(readonly element: HTMLElement) {}

private createContainer(): HTMLElement {
const el = document.createElement('div');
el.className = 'dv-drop-target-container';

return el;
}

private createAnchor(): HTMLElement {
const el = document.createElement('div');
el.className = 'dv-drop-target-anchor';
el.style.visibility = 'hidden';

return el;
}
}
34 changes: 31 additions & 3 deletions packages/dockview-core/src/dnd/droptarget.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.dv-drop-target {
position: relative;
--dv-transition-duration: 70ms;

> .dv-drop-target-dropzone {
position: absolute;
Expand All @@ -15,10 +16,13 @@
box-sizing: border-box;
height: 100%;
width: 100%;
border: var(--dv-drag-over-border);
background-color: var(--dv-drag-over-background-color);
transition: top 70ms ease-out, left 70ms ease-out,
width 70ms ease-out, height 70ms ease-out,
opacity 0.15s ease-out;
transition: top var(--dv-transition-duration) ease-out,
left var(--dv-transition-duration) ease-out,
width var(--dv-transition-duration) ease-out,
height var(--dv-transition-duration) ease-out,
opacity var(--dv-transition-duration) ease-out;
will-change: transform;
pointer-events: none;

Expand Down Expand Up @@ -48,3 +52,27 @@
}
}
}

.dv-drop-target-container {
position: absolute;
z-index: 9999;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
pointer-events: none;
overflow: hidden;
--dv-transition-duration: 300ms;

.dv-drop-target-anchor {
position: relative;
border: var(--dv-drag-over-border);
transition: opacity var(--dv-transition-duration) ease-in,
top var(--dv-transition-duration) ease-out,
left var(--dv-transition-duration) ease-out,
width var(--dv-transition-duration) ease-out,
height var(--dv-transition-duration) ease-out;
background-color: var(--dv-drag-over-background-color);
opacity: 1;
}
}
Loading

0 comments on commit ea1ba89

Please sign in to comment.