Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@shopify/draggable

Package Overview
Dependencies
Maintainers
40
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shopify/draggable

The JavaScript Drag & Drop library your grandparents warned you about.

  • 1.0.0-beta.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
52K
decreased by-15.19%
Maintainers
40
Weekly downloads
 
Created
Source
CircleCI status

Warning: Draggable is currently in beta

Get complete control over drag and drop behaviour with Draggable! Draggable abstracts native browser events into a comprehensive API to create a custom drag and drop experience. Draggable comes with additional modules: Sortable, Droppable, Swappable. Draggable itself does not perform any sorting behaviour while dragging, but does the heavy lifting, e.g. creates mirror, emits events, manages sensor events, makes elements draggable.

The additional modules are built on top of Draggable and therefore provide a similar API interface, for more information read the documentation below.

Features

  • Works with native drag, mouse, touch and force touch events
  • Can extend dragging behaviour by hooking into draggables event life cycle
  • Can extend drag detection by adding sensors to draggable
  • The library is targeted ES6 first

Table of Contents

Install

You can install the library via npm.

npm install @shopify/draggable --save

or via yarn:

yarn add @shopify/draggable

or via CDN

<script src="https://cdn.jsdelivr.net/npm/@shopify/draggable@1.0.0-beta/lib/draggable.js"></script>

Draggable

API

new Draggable(containers: Array[HTMLElement]|NodeList, options: Object): Draggable
To create a draggable instance you need to specify the containers that hold draggable items, e.g. [document.body] would work too. The second argument is an options object, which is described below.

draggable.on(eventName: String, listener: Function): Draggable
Draggable is an event emitter, so you can register callbacks for events. Draggable also supports method chaining.

draggable.off(eventName: String, listener: Function): Draggable
You can unregister listeners by using .off(), make sure to provide the same callback.

draggable.trigger(eventName: String, event: AbstractEvent): Draggable
You can trigger events through draggable. This is used to fire events internally or by extensions of Draggable.

draggable.destroy(): void
Detaches all sensors and listeners, and cleans up after itself.

Options

draggable {String}
A css selector for draggable elements within the containers specified. By default it will look for an element with .draggable-source class. Default: .draggable-source

handle {String}
Specify a css selector for a handle element if you don't want to allow drag action on the entire element. Default: null

delay {Number}
If you want to delay a drag:start you can specify delay in milliseconds. This can be useful for draggable elements within scrollable containers. Default: 0

native {Boolean}
If enabled, Draggable will use the browsers native drag events to detect drag behaviour. By default it will use mouse events to detect drag behaviour. You can only customize the mirror element when using mouse events, otherwise mirror will be null in events. Default: false

plugins {Array[Plugin]}
Plugins add behaviour to Draggable by hooking into its life cycle, e.g. one of the default plugins controls the mirror movement. Default: []

appendTo {String|HTMLElement|Function}
Draggable allows you to specify where the mirror should be appended to. You can specify a css selector, a HTMLElement or a function that returns a HTMLElement

classes {Object}
Draggable adds classes to elements to indicate state. These classes can be used to add styling on elements in certain states.

Events

NameDescriptionCancelableCancelable action
drag:startGets fired when drag action beginstruePrevents drag start
drag:moveGets fired when moving a draggable aroundfalse-
drag:overGets fired when dragging over other draggablefalse-
drag:over:containerGets fired when dragging over other draggable containerfalse-
drag:outGets fired when dragging out of other draggablefalse-
drag:out:containerGets fired when dragging out of other draggable containerfalse-
drag:stopGets fired when draggable has been releasedfalse-
drag:pressureGets fired when using force touch on draggable elementfalse-
mirror:createdGets fired when draggable mirror gets createdfalse-
mirror:attachedGets fired when draggable mirror gets attached to DOMfalse-
mirror:moveGets fired when draggable mirror movestrueStop mirror movement

Classes

NameDescriptionDefault
body:draggingClass added on the document body while draggingdraggable--is-dragging
container:draggingClass added on the container where the draggable was picked up fromdraggable-container--is-dragging
source:draggingClass added on the draggable element that has been picked updraggable-source--is-dragging
source:placedClass added on the draggable element on drag:stopdraggable-source--placed
container:placedClass added on the draggable container element on drag:stopdraggable-container--placed
draggable:overClass added on draggable element you are dragging overdraggable--over
container:overClass added on draggable container element you are dragging overdraggable-container--over
mirrorClass added on the mirror elementdraggable-mirror

Example

This sample code will make list items draggable:

import {Draggable} from '@shopify/draggable';

new Draggable(document.querySelectorAll('ul'))
  .on('drag:start', () => console.log('drag:start'))
  .on('drag:move',  () => console.log('drag:move'))
  .on('drag:stop',  () => console.log('drag:stop'));

Sortable

Sortable allows you to reorder elements. It maintains the order internally and fires three events on top of the draggable events: sortable:start, sortable:sorted and sortable:stop.

API

new Sortable(containers: Array[HTMLElement]|NodeList, options: Object): Sortable
To create a sortable instance you need to specify the containers that hold draggable items, e.g. [document.body] would work too. The second argument is an options object, which is described below.

sortable.on(eventName: String, listener: Function): Sortable
Sortable uses Draggables event emitter, so you can register callbacks for events. Sortable also supports method chaining.

sortable.off(eventName: String, listener: Function): Sortable
You can unregister listeners by using .off(), make sure to provide the same callback.

sortable.trigger(eventName: String, event: AbstractEvent): Sortable
You can trigger events through sortable. This is used to fire events internally or by extensions of Draggable.

sortable.destroy(): void
Detaches all sensors and listeners, and cleans up after itself.

Options

Same as Draggable

Events

NameDescriptionCancelableCancelable action
sortable:startGets fired when drag action beginstruePrevents drag start
sortable:sortedGets fired when the source gets sorted in the DOMfalse-
sortable:stopGets fired when dragging over other draggablefalse-

Classes

Same as Draggable

Example

This sample code will make list items draggable:

import {Sortable} from '@shopify/draggable';

new Sortable(document.querySelectorAll('ul'))
  .on('sortable:start', () => console.log('sortable:start'))
  .on('sortable:sorted', () => console.log('sortable:sorted'))
  .on('sortable:stop', () => console.log('sortable:stop'));

Droppable

Droppable allows you to declare draggable and droppable elements via options. Droppable fires two events on top of the draggable events: droppable:over and droppable:out.

API

new Droppable(containers: Array[HTMLElement]|NodeList, options: Object): Droppable
To create a droppable instance you need to specify the containers that hold draggable items, e.g. [document.body] would work too. The second argument is an options object, which is described below.

droppable.on(eventName: String, listener: Function): Droppable
Droppable uses Draggables event emitter, so you can register callbacks for events. Droppable also supports method chaining.

droppable.off(eventName: String, listener: Function): Droppable
You can unregister listeners by using .off(), make sure to provide the same callback.

droppable.trigger(eventName: String, event: AbstractEvent): Droppable
You can trigger events through droppable. This is used to fire events internally or by extensions of Draggable.

droppable.destroy(): void
Detaches all sensors and listeners, and cleans up after itself.

Options

droppable {String|Array[HTMLElement]|NodeList|Function}
A css selector string, an array of elements, a NodeList or a function returning elements for droppable elements within the containers specified.

Events

NameDescriptionCancelableCancelable action
droppable:overGets fired when dragging over droppable elementtruePrevents drop
droppable:outGets fired when dragging out of a droppable elementtruePrevents release

Classes

NameDescriptionDefault
droppable:activeClass added on droppables when drag startsdraggable-droppable--active
droppable:occupiedClass added on droppable element, when it contains a draggabledraggable-droppable--occupied

Example

This sample code will make list items draggable and allows to drop them inside another element:

import {Droppable} from '@shopify/draggable';

const droppable = new Droppable(document.querySelectorAll('ul'), {
  draggable: 'li',
  droppable: '#dropzone',
});

droppable.on('droppable:over', () => console.log('droppable:over'))
droppable.on('droppable:out', () => console.log('droppable:out'));

Swappable

Swappable allows you to swap elements by dragging over them. No order will be maintained (unlike Sortable), so any draggable element that gets dragged over will be swapped with the source element.

API

new Swappable(containers: Array[HTMLElement]|NodeList, options: Object): Swappable
To create a swappable instance you need to specify the containers that hold draggable items, e.g. [document.body] would work too. The second argument is an options object, which is described below.

swappable.on(eventName: String, listener: Function): Swappable
Swappable uses Draggables event emitter, so you can register callbacks for events. Swappable also supports method chaining.

swappable.off(eventName: String, listener: Function): Swappable
You can unregister listeners by using .off(), make sure to provide the same callback.

swappable.trigger(eventName: String, event: AbstractEvent): Swappable
You can trigger events through swappable. This is used to fire events internally or by extensions of Draggable.

droppable.destroy(): void
Detaches all sensors and listeners, and cleans up after itself.

Options

Same as Draggable

Events

NameDescriptionCancelableCancelable action
swappable:startGets fired when starting to dragtruePrevents drag
swappable:swappedGets fired before the source gets swappedtruePrevents swap
swappable:stopGets fired when dragging out of a droppable elementfalse-

Classes

Same as Draggable

Example

This sample code will make list items draggable and allows to drop them inside another element:

import {Swappable} from '@shopify/draggable';

const swappable = new Swappable(document.querySelectorAll('ul'), {
  draggable: 'li',
});

swappable.on('swappable:start', () => console.log('swappable:start'))
swappable.on('swappable:swapped', () => console.log('swappable:swapped'));
swappable.on('swappable:stop', () => console.log('swappable:stop'));

Plugins

Draggables ships with two optional plugins: Collidable & Snappable

Collidable

When you use the collidable plugin you can specify which elements you can't drag over and it will freeze the mirror movement for you. These currently only work with Sortable, Swappable and Droppable.

Options

collidables {String|Array[HTMLElement]|NodeList|HTMLElement|Function}
A css selector string, an array of elements, a NodeList, a HTMLElement or a function returning elements for collidable elements.

Events
NameDescriptionCancelableCancelable action
collidable:inGets fired when dragging near a collidable elementfalse-
collidable:outGets fired when dragging away from a collidable elementfalse-
Example
import {Sortable, Collidable} from '@shopify/draggable';

const sortable = new Sortable(document.querySelectorAll('ul'), {
  draggable: 'li',
  collidables: '.other-list',
  plugins: [Collidable]
});

sortable.on('collidable:in', () => console.log('collidable:in'));
sortable.on('collidable:out', () => console.log('collidable:out'));

Snappable

Snappable simulates a "snap" by hiding the mirror and removing the 'source:dragging' class from the source. It also sets the 'source:placed' class for potential drop animations.

Options

No options

Events
NameDescriptionCancelableCancelable action
snap:inGets fired when just before snapping intruePrevents snapping
snap:outGets fired when snapping outfalsePrevents snapping out
Example
import {Sortable, Snappable} from '@shopify/draggable';

const sortable = new Sortable(document.querySelectorAll('ul'), {
  draggable: 'li',
  plugins: [Snappable]
});

sortable.on('snap:in', () => console.log('snap:in'));
sortable.on('snap:out', () => console.log('snap:out'));

Known issues

  • Touch events freeze sometimes while dragging
  • Safari 11 uses force touch, but there are no visual guidelines on the website

Contributing

Contributions are more than welcome, the code base is still new and needs more love.

For more information, please checkout the contribution document.

Roadmap

The roadmap for the official release is still in the works. More to come

Copyright (c) 2017 Shopify. See LICENSE.md for further details.

Keywords

FAQs

Package last updated on 10 Oct 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc