Last active
April 30, 2024 18:00
-
-
Save andrienko/a754de7e615fa01435a526c8b6d238cd to your computer and use it in GitHub Desktop.
Monaco drag and drop provider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { editor } from 'monaco-editor'; | |
import IMouseTarget = editor.IMouseTarget; | |
import IStandaloneCodeEditor = editor.IStandaloneCodeEditor; | |
import IContentWidget = editor.IContentWidget; | |
const { ContentWidgetPositionPreference } = editor; | |
export type TDropHandler = (e: React.DragEvent, target: IMouseTarget, instance: IStandaloneCodeEditor) => void; | |
export type TInstanceGetter = () => IStandaloneCodeEditor; | |
export class MonacoDragNDropProvider { | |
onDrop = (e: React.DragEvent<HTMLDivElement>) => { | |
this.onDropHandler && this.onDropHandler(e, this.dragTarget, this.getInstance()); | |
this.removeMouseDownWidget(); | |
}; | |
onDragOver = (e: React.DragEvent<HTMLDivElement>) => { | |
const instance = this.getInstance(); | |
instance && this.displayMouseDropPosition(instance, instance.getTargetAtClientPoint(e.clientX, e.clientY)); | |
e.preventDefault(); | |
}; | |
removeMouseDownWidget = () => { | |
const instance = this.getInstance(); | |
if (instance && this.mouseDropWidget && this.domNode) { | |
instance.removeContentWidget(this.mouseDropWidget); | |
this.mouseDropWidget = null; | |
} | |
}; | |
props: React.HTMLAttributes<HTMLDivElement> = { | |
onDragOver: this.onDragOver, | |
onDropCapture: this.onDrop, | |
onDragLeaveCapture: this.removeMouseDownWidget | |
}; | |
domNode: HTMLDivElement = null; | |
mouseDropWidget: IContentWidget = null; | |
dragTarget: IMouseTarget; | |
buildMouseDropWidget = () => { | |
if (!this.domNode) { | |
this.domNode = document.createElement('div'); | |
this.domNode.className = this.dropClassName; | |
this.domNode.style.pointerEvents = 'none'; | |
this.domNode.style.borderLeft = '2px solid #ccc'; | |
this.domNode.innerHTML = ' '; | |
} | |
return { | |
getId: () => 'drag', | |
getDomNode: () => this.domNode, | |
getPosition: () => ({ | |
position: this.dragTarget.position, | |
preference: [ContentWidgetPositionPreference.EXACT, ContentWidgetPositionPreference.EXACT] | |
}) | |
}; | |
}; | |
displayMouseDropPosition = (instance: IStandaloneCodeEditor, target: IMouseTarget) => { | |
this.dragTarget = target; | |
if (this.mouseDropWidget) { | |
instance.layoutContentWidget(this.mouseDropWidget); | |
} else { | |
this.mouseDropWidget = this.buildMouseDropWidget(); | |
instance.addContentWidget(this.mouseDropWidget); | |
} | |
}; | |
getInstance: TInstanceGetter; | |
dropClassName: string; | |
onDropHandler: TDropHandler; | |
constructor(onDrop: TDropHandler, getInstance: TInstanceGetter, dropClassName: string = 'drop') { | |
this.dropClassName = dropClassName; | |
this.onDropHandler = onDrop; | |
this.getInstance = getInstance; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, Inspired by this I also wrote a functional version of this