@substrate-system/drag-drop v0.3.5
drag drop
Simplify the drag & drop API. Pass in a callback function, get drop events with a flat object of paths and files.
Inspired by feross/drag-drop -- drag & drop usable by humans.
install
npm i -S @substrate-system/drag-drop
Module format
This exposes ESM and common JS via the package.json exports
field.
ESM
import { dragDrop } from '@substrate-system/drag-drop'
Common JS
const { dragDrop } = require('@substrate-system/drag-drop')
pre-built JS
This package exposes minified JS files too. Copy them to a location that is accessible to your web server, then link to them in HTML.
copy
cp ./node_modules/@substrate-system/drag-drop/dist/index.min.js ./public/drag-drop.min.js
HTML
<script type="module" src="./drag-drop.min.js"></script>
Get started
This exposes a single function, dragDrop
. Pass in a callback function, and get data objects containing all the files or directories that were dropped.
import { dragDrop, type DropRecord } from '@substrate-system/drag-drop'
dragDrop('.dropper', { // <-- pass in an element or a string selector
onDrop: function (drop:DropRecord, { pos, files }) {
console.log('drop position', pos)
// => { x: 100, y: 200 }
// drop a folder or file
console.log('the dropped files', drop)
// we get the FileList object from the event too
console.log('the file list', files)
},
})
CSS
When someone hovers and drops something, a class .drag
is added to the drop target.
.drag {
border: 5px solid red;
}
API
types
DropRecord
A map from path name to file object.
type DropRecord = Record<string, File|Uint8Array>
example
{ '/abc/123': aFile }
Listener
type Listener = (dropped:DropRecord, opts:{
pos:{ x:number, y:number };
files:FileList;
})=>any
ListenerObject
type ListenerObject = {
onDrop:Listener;
onDropText?:(text:string, pos:{ x, y })=>any;
onDragEnter?:(event:DragEvent)=>any;
onDragOver?:(event:DragEvent)=>any;
onDragLeave?:(event:DragEvent)=>any;
}
Functions
A single function, dragDrop
, that takes an element, a listener, an an options object.
The third argument has a property showHiddenFiles
, which if true
will callback with all files, including ones that start with .
. By default is false
.
dragDrop
function dragDrop (
elem:HTMLElement|string,
listeners:Listener|ListenerObject,
opts?:{ showHiddenFiles?:boolean }
):void
Directories
Drop a folder, get a flat object containing the files mapped by their path names.
Given a folder structure like this:
abc
├── aaaaa
│ └── bbb
│ └── testbbb.txt
└── test.txt
3 directories, 2 files
If we drop the top folder, abc
into the drop zone, then we get an object like this:
{
"/abc/aaaaa/bbb/testbbb.txt": File,
"/abc/test.txt": File
}
Example
import { dragDrop, type DropRecord } from '@substrate-system/drag-drop'
dragDrop('.dropzone', (drop:DropRecord, { pos } => {
debug('the drop', drop)
// =>
// {
// "/abc/aaaaa/bbb/testbbb.txt": {},
// "/abc/test2.txt": {},
// "/abc/test.txt": {}
// }
}
Hidden files
Pass in an options object with { showHiddenFiles: true }
to get results including dot files. By default this will exclude hidden files from the results.
Example
import { dragDrop } from '@substrate-system/drag-drop'
dragDrop('.dropzone', (dropRecord) => {
debug('including hidden files...', dropRecord)
// =>
// {
// "/abc/.DS_Store": {},
// "/abc/aaaaa/.DS_Store": {},
// "/abc/aaaaa/bbb/testbbb.txt": {},
// "/abc/test2.txt": {},
// "/abc/test.txt": {}
// }
}, { showHiddenFiles: true })
The returned object is a flat record with path names pointing at File
objects.
Files
Drop a single file, get an object with just the one file:
{
"/test.txt": File
}
test
Do manual testing, because it is difficult to mock the drop events.
Start a local example server
npm start