diff --git a/packages/notebook/src/browser/style/index.css b/packages/notebook/src/browser/style/index.css index 5fd8ce1e2f904..cdfdb60f934de 100644 --- a/packages/notebook/src/browser/style/index.css +++ b/packages/notebook/src/browser/style/index.css @@ -281,3 +281,11 @@ line-height: 22px; opacity: 0.7; } + +.theia-notebook-drag-ghost-image { + position: absolute; + top: -99999px; + left: -99999px; + height: 500px; + width: 500px; +} diff --git a/packages/notebook/src/browser/view/notebook-cell-list-view.tsx b/packages/notebook/src/browser/view/notebook-cell-list-view.tsx index 88a6416b2333d..065a2a19a2edb 100644 --- a/packages/notebook/src/browser/view/notebook-cell-list-view.tsx +++ b/packages/notebook/src/browser/view/notebook-cell-list-view.tsx @@ -25,6 +25,7 @@ import { NotebookCellActionContribution } from '../contributions/notebook-cell-a export interface CellRenderer { render(notebookData: NotebookModel, cell: NotebookCellModel, index: number): React.ReactNode + renderDragImage(cell: NotebookCellModel): HTMLElement } interface CellListProps { @@ -43,6 +44,8 @@ export class NotebookCellListView extends React.Component this.onDragStart(e, index)} + onDragStart={e => this.onDragStart(e, index, cell)} onDragOver={e => this.onDragOver(e, cell)} onDrop={e => this.onDrop(e, index)} draggable={true} @@ -114,12 +117,22 @@ export class NotebookCellListView extends React.Component, index: number): void { + protected onDragStart(event: React.DragEvent, index: number, cell: NotebookCellModel): void { event.stopPropagation(); if (!this.isEnabled()) { event.preventDefault(); return; } + + if (this.dragGhost) { + this.dragGhost.remove(); + } + this.dragGhost = document.createElement('div'); + this.dragGhost.classList.add('theia-notebook-drag-ghost-image'); + this.dragGhost.appendChild(this.props.renderers.get(cell.cellKind)?.renderDragImage(cell) ?? document.createElement('div')); + document.body.appendChild(this.dragGhost); + event.dataTransfer.setDragImage(this.dragGhost, -10, 0); + event.dataTransfer.setData('text/theia-notebook-cell-index', index.toString()); event.dataTransfer.setData('text/plain', this.props.notebookModel.cells[index].source); } diff --git a/packages/notebook/src/browser/view/notebook-code-cell-view.tsx b/packages/notebook/src/browser/view/notebook-code-cell-view.tsx index 11f5ac626baf3..596cc22af4c26 100644 --- a/packages/notebook/src/browser/view/notebook-code-cell-view.tsx +++ b/packages/notebook/src/browser/view/notebook-code-cell-view.tsx @@ -99,6 +99,13 @@ export class NotebookCodeCellRenderer implements CellRenderer { ; } + renderDragImage(cell: NotebookCellModel): HTMLElement { + const dragImage = document.createElement('div'); + dragImage.className = 'theia-notebook-drag-image'; + dragImage.textContent = nls.localize('theia/notebook/dragGhostImage/codeText', 'Code cell selected'); + return dragImage; + } + protected getOrCreateMonacoFontInfo(): BareFontInfo { if (!this.fontInfo) { this.fontInfo = this.createFontInfo(); diff --git a/packages/notebook/src/browser/view/notebook-markdown-cell-view.tsx b/packages/notebook/src/browser/view/notebook-markdown-cell-view.tsx index e02c82c11db4d..1b5cd348dde63 100644 --- a/packages/notebook/src/browser/view/notebook-markdown-cell-view.tsx +++ b/packages/notebook/src/browser/view/notebook-markdown-cell-view.tsx @@ -42,6 +42,12 @@ export class NotebookMarkdownCellRenderer implements CellRenderer { cell={cell} notebookModel={notebookModel} notebookContextManager={this.notebookContextManager} />; } + renderDragImage(cell: NotebookCellModel): HTMLElement { + const dragImage = document.createElement('div'); + dragImage.className = 'theia-notebook-drag-image'; + dragImage.textContent = nls.localize('theia/notebook/dragGhostImage/markdownText', 'Mardown cell selected'); + return dragImage; + } } interface MarkdownCellProps {