* chore: extend linting of code blocks in the docs * chore: combine lint:markdownlint and lint:markdown scripts
		
			
				
	
	
		
			116 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Native File Drag & Drop
 | 
						|
 | 
						|
## Overview
 | 
						|
 | 
						|
Certain kinds of applications that manipulate files might want to support
 | 
						|
the operating system's native file drag & drop feature. Dragging files into
 | 
						|
web content is common and supported by many websites. Electron additionally
 | 
						|
supports dragging files and content out from web content into the operating
 | 
						|
system's world.
 | 
						|
 | 
						|
To implement this feature in your app, you need to call the
 | 
						|
[`webContents.startDrag(item)`](../api/web-contents.md#contentsstartdragitem)
 | 
						|
API in response to the `ondragstart` event.
 | 
						|
 | 
						|
## Example
 | 
						|
 | 
						|
An example demonstrating how you can create a file on the fly to be dragged out of the window.
 | 
						|
 | 
						|
### Preload.js
 | 
						|
 | 
						|
In `preload.js` use the [`contextBridge`][] to inject a method `window.electron.startDrag(...)` that will send an IPC message to the main process.
 | 
						|
 | 
						|
```js
 | 
						|
const { contextBridge, ipcRenderer } = require('electron')
 | 
						|
const path = require('node:path')
 | 
						|
 | 
						|
contextBridge.exposeInMainWorld('electron', {
 | 
						|
  startDrag: (fileName) => {
 | 
						|
    ipcRenderer.send('ondragstart', path.join(process.cwd(), fileName))
 | 
						|
  }
 | 
						|
})
 | 
						|
```
 | 
						|
 | 
						|
### Index.html
 | 
						|
 | 
						|
Add a draggable element to `index.html`, and reference your renderer script:
 | 
						|
 | 
						|
```html
 | 
						|
<div style="border:2px solid black;border-radius:3px;padding:5px;display:inline-block" draggable="true" id="drag">Drag me</div>
 | 
						|
<script src="renderer.js"></script>
 | 
						|
```
 | 
						|
 | 
						|
### Renderer.js
 | 
						|
 | 
						|
In `renderer.js` set up the renderer process to handle drag events by calling the method you added via the [`contextBridge`][] above.
 | 
						|
 | 
						|
```js @ts-expect-error=[3]
 | 
						|
document.getElementById('drag').ondragstart = (event) => {
 | 
						|
  event.preventDefault()
 | 
						|
  window.electron.startDrag('drag-and-drop.md')
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### Main.js
 | 
						|
 | 
						|
In the Main process (`main.js` file), expand the received event with a path to the file that is
 | 
						|
being dragged and an icon:
 | 
						|
 | 
						|
```fiddle docs/fiddles/features/drag-and-drop
 | 
						|
const { app, BrowserWindow, ipcMain } = require('electron/main')
 | 
						|
const path = require('node:path')
 | 
						|
const fs = require('node:fs')
 | 
						|
const https = require('node:https')
 | 
						|
 | 
						|
function createWindow () {
 | 
						|
  const win = new BrowserWindow({
 | 
						|
    width: 800,
 | 
						|
    height: 600,
 | 
						|
    webPreferences: {
 | 
						|
      preload: path.join(__dirname, 'preload.js')
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  win.loadFile('index.html')
 | 
						|
}
 | 
						|
 | 
						|
const iconName = path.join(__dirname, 'iconForDragAndDrop.png')
 | 
						|
const icon = fs.createWriteStream(iconName)
 | 
						|
 | 
						|
// Create a new file to copy - you can also copy existing files.
 | 
						|
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-1.md'), '# First file to test drag and drop')
 | 
						|
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-2.md'), '# Second file to test drag and drop')
 | 
						|
 | 
						|
https.get('https://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
 | 
						|
  response.pipe(icon)
 | 
						|
})
 | 
						|
 | 
						|
app.whenReady().then(createWindow)
 | 
						|
 | 
						|
ipcMain.on('ondragstart', (event, filePath) => {
 | 
						|
  event.sender.startDrag({
 | 
						|
    file: path.join(__dirname, filePath),
 | 
						|
    icon: iconName
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
app.on('window-all-closed', () => {
 | 
						|
  if (process.platform !== 'darwin') {
 | 
						|
    app.quit()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
app.on('activate', () => {
 | 
						|
  if (BrowserWindow.getAllWindows().length === 0) {
 | 
						|
    createWindow()
 | 
						|
  }
 | 
						|
})
 | 
						|
```
 | 
						|
 | 
						|
After launching the Electron application, try dragging and dropping
 | 
						|
the item from the BrowserWindow onto your desktop. In this guide,
 | 
						|
the item is a Markdown file located in the root of the project:
 | 
						|
 | 
						|

 | 
						|
 | 
						|
[`contextBridge`]: ../api/context-bridge.md
 |