Skip to content

substrate-system/drag-drop

Repository files navigation

drag drop

tests types module semantic versioning Common Changelog install size GZip size dependencies license

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.

See a live demo

Contents

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. By default the callback will not see any hidden files (dot files). Pass in another argument with { showHiddenFiles: true } if you do want to see hidden files.

import { dragDrop, type DropRecord } from '@substrate-system/drag-drop'

// pass in an element or a CSS query selector
dragrop('.dropper',  (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)
}, { showHiddenFiles: true })  // <-- third argument is optional

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

About

HTML5 drag & drop for humans

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •