Convert Figma logo to code with AI

Shopify logodraggable

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

17,946
1,093
17,946
147

Top Related Projects

29,570

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.

Beautiful and accessible drag and drop for lists with React

10,773

Infinite responsive, sortable, filterable and draggable layouts

21,948

:ok_hand: Drag and drop so simple it hurts

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

Quick Overview

Shopify/draggable is a lightweight, modular drag & drop library for JavaScript applications. It provides a flexible and customizable solution for creating drag and drop interfaces, sortable lists, and other interactive elements. The library is designed to be framework-agnostic and can be used with various front-end technologies.

Pros

  • Modular architecture allows for easy customization and extension
  • Lightweight and performant, with minimal dependencies
  • Framework-agnostic, can be used with various front-end technologies
  • Extensive documentation and examples provided

Cons

  • Learning curve may be steeper for developers new to drag and drop implementations
  • Limited built-in styling options, requiring more custom CSS work
  • Some advanced features may require additional plugins or custom development

Code Examples

  1. Basic Draggable initialization:
import { Draggable } from '@shopify/draggable';

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

draggable.on('drag:start', () => console.log('Drag started'));
draggable.on('drag:stop', () => console.log('Drag stopped'));
  1. Creating a sortable list:
import { Sortable } from '@shopify/draggable';

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

sortable.on('sortable:sort', (event) => {
  console.log(`${event.dragEvent.source.textContent} was moved`);
});
  1. Using the Swappable plugin:
import { Swappable } from '@shopify/draggable';

const swappable = new Swappable(document.querySelectorAll('.container'), {
  draggable: '.item',
  mirror: {
    appendTo: 'body',
    constrainDimensions: true
  }
});

swappable.on('swappable:swapped', (event) => {
  console.log(`${event.dragEvent.source.id} swapped with ${event.over.id}`);
});

Getting Started

  1. Install the library using npm or yarn:

    npm install @shopify/draggable
    
  2. Import the desired modules in your JavaScript file:

    import { Draggable, Sortable, Swappable } from '@shopify/draggable';
    
  3. Initialize the draggable instance on your desired elements:

    const draggable = new Draggable(document.querySelectorAll('.container'), {
      draggable: '.item'
    });
    
  4. Add event listeners to handle drag and drop actions:

    draggable.on('drag:start', (event) => {
      console.log('Drag started:', event.source);
    });
    
    draggable.on('drag:stop', (event) => {
      console.log('Drag stopped:', event.source);
    });
    

Competitor Comparisons

29,570

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.

Pros of Sortable

  • Wider browser support, including older versions of IE
  • More lightweight and focused solely on sorting functionality
  • Extensive plugin ecosystem for additional features

Cons of Sortable

  • Less modern API design compared to Draggable
  • Fewer built-in features for advanced drag and drop scenarios
  • Limited official documentation and examples

Code Comparison

Sortable:

new Sortable(document.getElementById('list'), {
  animation: 150,
  ghostClass: 'blue-background-class'
});

Draggable:

new Draggable.Sortable(document.querySelectorAll('ul'), {
  draggable: 'li',
  mirror: {
    appendTo: 'body',
    constrainDimensions: true
  }
});

Both libraries offer straightforward initialization, but Draggable provides a more modern and flexible API with additional options for customization. Sortable's simpler approach may be preferable for basic sorting needs, while Draggable's extensive features cater to more complex drag and drop scenarios.

Sortable excels in its lightweight nature and broad browser support, making it suitable for projects requiring compatibility with older systems. On the other hand, Draggable offers a more comprehensive solution with advanced features and better documentation, albeit with a slightly steeper learning curve.

Beautiful and accessible drag and drop for lists with React

Pros of react-beautiful-dnd

  • Specifically designed for React applications, offering seamless integration
  • Provides accessible drag and drop functionality out of the box
  • Offers a more declarative API, making it easier to implement complex drag and drop scenarios

Cons of react-beautiful-dnd

  • Limited to React applications, not suitable for vanilla JavaScript or other frameworks
  • Less flexible for custom styling and animations compared to Draggable
  • May have a steeper learning curve for developers not familiar with React concepts

Code Comparison

react-beautiful-dnd:

<DragDropContext onDragEnd={onDragEnd}>
  <Droppable droppableId="list">
    {(provided) => (
      <ul {...provided.droppableProps} ref={provided.innerRef}>
        {items.map((item, index) => (
          <Draggable key={item.id} draggableId={item.id} index={index}>
            {(provided) => (
              <li ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
                {item.content}
              </li>
            )}
          </Draggable>
        ))}
        {provided.placeholder}
      </ul>
    )}
  </Droppable>
</DragDropContext>

Draggable:

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

draggable.on('sortable:stop', (event) => {
  console.log(`Moved element from index ${event.oldIndex} to ${event.newIndex}`);
});
10,773

Infinite responsive, sortable, filterable and draggable layouts

Pros of Muuri

  • More comprehensive grid layout functionality, including responsive layouts and advanced sorting
  • Built-in support for animations and transitions
  • Smaller file size and potentially better performance

Cons of Muuri

  • Less actively maintained, with fewer recent updates
  • More complex API, which may have a steeper learning curve
  • Limited official documentation compared to Draggable

Code Comparison

Muuri:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  layout: {
    fillGaps: true,
    horizontal: false,
    alignRight: false,
    alignBottom: false,
    rounding: false
  }
});

Draggable:

const sortable = new Sortable(document.querySelectorAll('.container'), {
  draggable: '.item',
  mirror: {
    appendTo: 'body',
    constrainDimensions: true
  }
});

Both libraries offer drag-and-drop functionality, but Muuri provides more built-in options for grid layouts and animations. Draggable, on the other hand, offers a simpler API and is more focused on drag-and-drop interactions. The choice between the two depends on the specific requirements of your project, with Muuri being better suited for complex grid layouts and Draggable for simpler drag-and-drop needs.

21,948

:ok_hand: Drag and drop so simple it hurts

Pros of Dragula

  • Lightweight and simple to use, with minimal setup required
  • Supports nested dragging and touch events out of the box
  • Extensive browser support, including older versions

Cons of Dragula

  • Less customizable and feature-rich compared to Draggable
  • Limited built-in animations and transitions
  • Fewer options for handling complex drag-and-drop scenarios

Code Comparison

Dragula:

dragula([document.querySelector('#left'), document.querySelector('#right')])
  .on('drag', function(el) {
    el.className += ' is-moving';
  })
  .on('drop', function(el) {
    el.className = el.className.replace('is-moving', '');
  });

Draggable:

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

const sortable = new Sortable(document.querySelectorAll('ul'), {
  draggable: 'li',
  mirror: {
    appendTo: 'body',
    constrainDimensions: true,
  },
});

sortable.on('sortable:start', () => console.log('Drag started'));
sortable.on('sortable:stop', () => console.log('Drag stopped'));

Both libraries offer drag-and-drop functionality, but Draggable provides more advanced features and customization options. Dragula is simpler to set up and use, while Draggable offers greater flexibility for complex scenarios. The code examples demonstrate the difference in setup and event handling between the two libraries.

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

Pros of react-sortable-hoc

  • Specifically designed for React applications, providing seamless integration
  • Supports both vertical and horizontal sorting out of the box
  • Offers a higher-order component approach, allowing for easy composition

Cons of react-sortable-hoc

  • Limited to React ecosystem, not suitable for vanilla JavaScript projects
  • May have a steeper learning curve for developers unfamiliar with HOCs
  • Less flexible for complex, multi-dimensional dragging scenarios

Code Comparison

react-sortable-hoc:

import { SortableContainer, SortableElement } from 'react-sortable-hoc';

const SortableItem = SortableElement(({value}) => <li>{value}</li>);
const SortableList = SortableContainer(({items}) => {
  return (
    <ul>
      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}
    </ul>
  );
});

Draggable:

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

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

sortable.on('sortable:start', () => console.log('sortable:start'));
sortable.on('sortable:sort', () => console.log('sortable:sort'));
sortable.on('sortable:sorted', () => console.log('sortable:sorted'));

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

npm version CI PRs Welcome Bundle size

Development

Draggable is no longer maintained by its original authors. Maintenance of this repo has been passed on to new collaborators and is no longer worked on by anyone at Shopify.

We are still looking for more maintainers! If anyone is interested in answering / triaging issues, reviewing / rejecting / approving PRs, and authoring code for bug fixes / new features — please send an email to max.hoffmann (at) shopify (dot) com. You may be asked a few questions before obtaining collaboration permission, but if everything checks out, we will happily add you as a collaborator.


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

<!-- Entire bundle -->
<script type="module">
  import {
    Draggable,
    Sortable,
    Droppable,
    Swappable,
  } from 'https://cdn.jsdelivr.net/npm/@shopify/draggable/build/esm/index.mjs';
</script>
<!-- Draggable only -->
<script type="module">
  import Draggable from 'https://cdn.jsdelivr.net/npm/@shopify/draggable/build/esm/Draggable/Draggable.mjs';
</script>
<!-- Sortable only -->
<script type="module">
  import Sortable from 'https://cdn.jsdelivr.net/npm/@shopify/draggable/build/esm/Sortable/Sortable.mjs';
</script>
<!-- Droppable only -->
<script type="module">
  import Droppable from 'https://cdn.jsdelivr.net/npm/@shopify/draggable/build/esm/Droppable/Droppable.mjs';
</script>
<!-- Swappable only -->
<script type="module">
  import Swappable from 'https://cdn.jsdelivr.net/npm/@shopify/draggable/build/esm/Swappable/Swappable.mjs';
</script>
<!-- Plugins only -->
<script type="module">
  import * as Plugins from 'https://cdn.jsdelivr.net/npm/@shopify/draggable/build/esm/Plugins/index.mjs';
</script>
<!-- UMD browser -->
<script src="https://cdn.jsdelivr.net/npm/@shopify/draggable/build/umd/index.min.js"></script>
<script>
  console.log(window.Draggable);
</script>

Browser Compatibility

Check the "browserlist" property in package.json for more info

ChromeFirefoxOperaSafariEdge
Last 3 versions ✔Last 3 versions ✔Last 3 versions ✔Last 3 versions ✔Last 3 versions ✔

Documentation

You can find the documentation for each module within their respective directories.

TypeScript

Draggable includes TypeScript definitions.

Documentation

Running examples

To run the examples project locally, simply run the following from the draggable root:

yarn && yarn start

This will start a server that hosts the contents of examples/. It also watches for file changes from both src/ and examples/src and reloads the browser.

Contributing

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

For more information, please checkout the contributing document.

Related resources

Copyright

Copyright (c) 2018-present Shopify. See LICENSE.md for further details.

NPM DownloadsLast 30 Days