### Local Development Setup Source: https://github.com/shopify/draggable/blob/main/examples/README.md Instructions for cloning the repository, installing dependencies, and starting the local development server. ```bash git clone git@github.com:Shopify/draggable.git cd draggable yarn && yarn start ``` -------------------------------- ### Running Examples Source: https://github.com/shopify/draggable/blob/main/README.md Instructions to run the examples project locally. This involves installing dependencies and starting a development server that watches for file changes. ```bash yarn && yarn start ``` -------------------------------- ### Swappable Event Handling Example Source: https://github.com/shopify/draggable/blob/main/src/Swappable/README.md Provides an example of initializing Swappable and attaching event listeners for 'swappable:start', 'swappable:swapped', and 'swappable:stop' events. ```js 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')); ``` -------------------------------- ### Local Development Setup (NPM) Source: https://github.com/shopify/draggable/blob/main/CONTRIBUTING.md Steps to set up and run the Draggable project locally using NPM, including installation and running tests. ```bash $ cd draggable $ npm install $ npm run test ``` -------------------------------- ### Local Development Setup (Yarn) Source: https://github.com/shopify/draggable/blob/main/CONTRIBUTING.md Steps to set up and run the Draggable project locally using Yarn, including installation and running tests. ```bash $ cd draggable $ yarn install $ yarn test ``` -------------------------------- ### Initialize Draggable Source: https://github.com/shopify/draggable/blob/main/src/Draggable/README.md This example demonstrates how to initialize the Draggable component to make list items within specified containers draggable. It also shows how to listen for drag events like 'drag:start', 'drag:move', and 'drag:stop'. ```javascript import {Draggable} from '@shopify/draggable'; const draggable = new Draggable(document.querySelectorAll('ul'), { draggable: 'li', }); draggable.on('drag:start', () => console.log('drag:start')); draggable.on('drag:move', () => console.log('drag:move')); draggable.on('drag:stop', () => console.log('drag:stop')); ``` -------------------------------- ### Droppable Example Implementation Source: https://github.com/shopify/draggable/blob/main/src/Droppable/README.md A complete HTML and JavaScript example demonstrating how to set up Draggable and Droppable components. It includes the necessary HTML structure, CSS for styling, and JavaScript for initialization and event handling. ```html
A
B
C
``` -------------------------------- ### SortAnimation Example Initialization Source: https://github.com/shopify/draggable/blob/main/src/Plugins/SortAnimation/README.md A concise example demonstrating the initialization of Sortable with the SortAnimation plugin, specifying custom animation parameters. ```js import {Sortable, Plugins} from '@shopify/draggable'; const sortable = new Sortable(document.querySelectorAll('ul'), { draggable: 'li', sortAnimation: { duration: 200, easingFunction: 'ease-in-out', }, plugins: [Plugins.SortAnimation], }); ``` -------------------------------- ### Install @shopify/draggable via npm or yarn Source: https://github.com/shopify/draggable/blob/main/README.md Instructions for installing the Draggable library using npm or yarn package managers. ```bash npm install @shopify/draggable --save ``` ```bash yarn add @shopify/draggable ``` -------------------------------- ### JS Docblock Examples Source: https://github.com/shopify/draggable/blob/main/CONTRIBUTING.md Examples of JSDoc comments for documenting JavaScript code, including methods, properties, constants, classes, and constructors. ```js /** * Some method description * @param {ParameterType} parameterName * @return {ReturnType} * @private * @static * @readonly */ /** * Some instance property description * @property {PropertyType} propertyName * @private * @static * @readonly */ /** * Some constant description * @const {ConstType} constName */ /** * Some class description * @class ClassName * @module ClassName * @extends BaseClassName */ /** * Constructor description * @constructs ClassName */ ``` -------------------------------- ### Nunjucks Component Rendering Source: https://github.com/shopify/draggable/blob/main/examples/README.md Example of how to render a Nunjucks component with specific properties and variations. ```nunjucks {{ Block.render('one', {index: 1, draggable: true}) }} ``` -------------------------------- ### Example Usage with Sortable Source: https://github.com/shopify/draggable/blob/main/src/Plugins/ResizeMirror/README.md Provides an example of integrating the ResizeMirror plugin with the Sortable functionality of the Draggable library, showcasing its use in a sorting context. ```js import {Sortable, Plugins} from '@shopify/draggable'; const sortable = new Sortable(document.querySelectorAll('ul'), { draggable: 'li', plugins: [Plugins.ResizeMirror], }); ``` -------------------------------- ### Running Development Server Source: https://github.com/shopify/draggable/blob/main/examples/README.md Starts a browsersync server for development. It watches for changes in `src/` and `draggable/lib`, recompiles files, and automatically reloads the browser. SCSS changes are injected without a full reload. ```bash yarn start ``` -------------------------------- ### Multiple Containers Example Source: https://github.com/shopify/draggable/blob/main/examples/src/views/multiple-containers.html Demonstrates how to implement sorting of elements across multiple containers using Shopify's Draggable library. This example showcases the setup for managing independent sorting rules within each container. ```javascript import Draggable from '@shopify/draggable/lib/Draggable'; const containers = document.querySelectorAll('.container'); containers.forEach(container => { new Draggable(container, { draggable: '.draggable-item', dropzone: '.container' }); }); ``` -------------------------------- ### Collidable Plugin Event Handling Example Source: https://github.com/shopify/draggable/blob/main/src/Plugins/Collidable/README.md Provides a practical example of using the Collidable plugin with the Sortable functionality. It demonstrates initializing Sortable with the plugin and listening for `collidable:in` and `collidable:out` events to log messages to the console. ```js import {Sortable, Plugins} from '@shopify/draggable'; const sortable = new Sortable(document.querySelectorAll('ul'), { draggable: 'li', collidables: '.other-list', plugins: [Plugins.Collidable], }); sortable.on('collidable:in', () => console.log('collidable:in')); sortable.on('collidable:out', () => console.log('collidable:out')); ``` -------------------------------- ### Draggable List Items Example Source: https://github.com/shopify/draggable/blob/main/examples/src/content/Sortable/MultipleContainers/MultipleContainers.html This snippet demonstrates the usage of the StackedListItem component to render a list of items. It highlights how to enable dragging for specific items by passing the `draggable: true` attribute. The example is structured into different containers to showcase distinct list configurations. ```html {% import 'components/StackedList/StackedListItem.html' as StackedListItem %} {% macro render(id) %} ### Container one {{ StackedListItem.render('zebra', {index: 1, draggable: true}) }} {{ StackedListItem.render('giraffe', {index: 2, draggable: true}) }} {{ StackedListItem.render('baboon', {index: 3 }) }} {{ StackedListItem.render('elephant', {index: 4, draggable: true}) }} {{ StackedListItem.render('leopard', {index: 5, draggable: true}) }} ### Container two _3 item capacity_ {{ StackedListItem.render('fluorescent grey', {index: 6, draggable: true}) }} {{ StackedListItem.render('rebecca purple', {index: 7, draggable: true}) }} ### Container three {{ StackedListItem.render('apple', {index: 8, draggable: true}) }} {{ StackedListItem.render('banana', {index: 9, draggable: true}) }} {{ StackedListItem.render('cucumber', {index: 10, draggable: true}) }} {{ StackedListItem.render('daikon radish', {index: 11 }) }} {{ StackedListItem.render('elderberry', {index: 12, draggable: true}) }} {{ StackedListItem.render('fresh thyme', {index: 13, draggable: true}) }} {{ StackedListItem.render('guava', {index: 14, draggable: true}) }} {% endmacro %} ``` -------------------------------- ### Initialize Draggable with Exclusions Source: https://github.com/shopify/draggable/blob/main/src/Draggable/README.md This example shows how to create a Draggable instance while excluding specific default plugins and sensors. This is useful for customizing the Draggable behavior by removing unwanted functionalities. ```javascript import {Draggable} from '@shopify/draggable'; const draggable = new Draggable(document.querySelectorAll('ul'), { draggable: 'li', exclude: { plugins: [Draggable.Plugins.Focusable], sensors: [Draggable.Sensors.TouchSensor], }, }); ``` -------------------------------- ### Static Announcements Example Source: https://github.com/shopify/draggable/blob/main/src/Draggable/Plugins/Announcement/README.md Demonstrates how to configure static string announcements for drag and drop events using the Announcement plugin. ```javascript import {Sortable} from '@shopify/draggable'; const announcements = { 'drag:start': 'Draggable element picked up', 'drag:stop': 'Draggable element dropped', 'sortable:stopped': 'Draggable elements swapped', } const sortable = new Sortable(document.querySelectorAll('ul'), { draggable: 'li', announcements, }); ``` -------------------------------- ### Initialize Draggable with Force Touch Sensor Source: https://github.com/shopify/draggable/blob/main/src/Draggable/Sensors/ForceTouchSensor/README.md Example of how to import and use the Force Touch Sensor with the Draggable library. ```javascript import {Draggable, Sensors} from '@shopify/draggable'; const draggable = new Draggable(containers, { sensors: [Sensors.ForceTouchSensor], }); ``` -------------------------------- ### Document Rendering and Social Sharing Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Document/Head.html This macro renders document content, including setting page titles, descriptions, and social sharing metadata. It imports and utilizes a SocialShare component for generating social media links. ```html {% import 'components/Document/SocialShare.html' as SocialShare %} {% macro render(ViewAttr) %} {% set url = 'https://shopify.github.io/draggable' %} {% set siteName = 'Draggable JS Examples' %} {% set titleSep = ' | ' %} {% set parentFragment = ViewAttr.parent + titleSep if ViewAttr.parent %} {% set childFragment = ViewAttr.child + titleSep if ViewAttr.child %} {% set titleText = [parentFragment, childFragment, siteName] %} {% set HeadAttr = { siteName: siteName, title: ViewAttr.subheading, description: 'Draggable is a lightweight, responsive, modern drag and drop JavaScript library – the ideal choice for adding slick native-feeling drag and drop behaviour to your web apps.', siteUrl: url, socialImg: url + '/assets/img/social/draggable-social.png', twitterHandle: '@Shopify', twitterId: '17136315' } %} {{ titleText | join('') | trim }} {{ SocialShare.render(HeadAttr) }} {% include 'components/Document/Favicon.html' %} {% endmacro %} ``` -------------------------------- ### Initialize Draggable with Custom Classes Source: https://github.com/shopify/draggable/blob/main/src/Draggable/README.md This example demonstrates how to initialize Draggable and apply custom CSS classes to elements during specific drag states, such as when a draggable element is being dragged over a container. It allows for more granular styling of the drag-and-drop interface. ```javascript import {Draggable} from '@shopify/draggable'; const draggable = new Draggable(document.querySelectorAll('ul'), { draggable: 'li', classes: { 'draggable:over': ['draggable--over', 'bg-red-200', 'bg-opacity-25'], }, }); ``` -------------------------------- ### Render Macro for View Attributes Source: https://github.com/shopify/draggable/blob/main/examples/src/components/PageHeader/PageHeader.html This Jinja macro, `render`, takes a `ViewAttr` object and constructs a content path based on its parent and child properties. It then displays the parent and subheading, along with a link to the corresponding code example on GitHub. ```jinja {% macro render(ViewAttr) %} {% set contentPath = '' %} {% set contentPath = ViewAttr.parent + '/' if ViewAttr.child %} {% set contentPath = contentPath + ViewAttr.id %} {{ ViewAttr.parent }} ===================== {{ ViewAttr.subheading }} ------------------------- [View code on GitHub](https://github.com/Shopify/draggable/tree/main/examples/src/content/{{ contentPath }} "See this code example") {% endmacro %} ``` -------------------------------- ### Sortable Event Handling Source: https://github.com/shopify/draggable/blob/main/src/Sortable/README.md Provides an example of how to attach event listeners to the Sortable instance to react to sorting actions. It logs messages to the console for `sortable:start`, `sortable:sort`, `sortable:sorted`, and `sortable:stop` events. ```js 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')); sortable.on('sortable:stop', () => console.log('sortable:stop')); ``` -------------------------------- ### DragStartSensorEvent Source: https://github.com/shopify/draggable/blob/main/src/Draggable/Sensors/SensorEvent/README.md Represents the event triggered when a drag operation starts. It is cancelable, and canceling it prevents the drag start. ```APIDOC DragStartSensorEvent: Specification: SensorEvent Interface: DragStartSensorEvent Cancelable: true Cancel action: Prevents drag start type: drag:start ``` -------------------------------- ### Basic Drag and Drop Initialization Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Brand/Wordmark.html Demonstrates how to initialize the Shopify Draggable library with basic configuration to make elements within a container draggable. ```javascript import Draggable from '@shopify/draggable'; const container = document.getElementById('my-container'); const draggable = new Draggable(container, { draggable: '.my-draggable-item' }); console.log('Draggable initialized!'); ``` -------------------------------- ### NPM Usage Source: https://github.com/shopify/draggable/blob/main/src/Draggable/README.md Demonstrates how to import and initialize the Draggable library using NPM in a JavaScript project. ```js import {Draggable} from '@shopify/draggable'; // Or import Draggable from '@shopify/draggable/build/esm/Draggable/Draggable'; const draggable = new Draggable(document.querySelectorAll('ul'), { draggable: 'li', }); ``` -------------------------------- ### SwappableStartEvent API Source: https://github.com/shopify/draggable/blob/main/src/Swappable/SwappableEvent/README.md Triggered by Swappable on drag start. This event is cancelable, and canceling it prevents the drag start. It provides properties for the element and container being hovered over. ```APIDOC SwappableStartEvent: over: HTMLElement Read-only property for the draggable element that you are over. overContainer: HTMLElement Read-only property for the draggable container element that you are over. Cancelable: true Cancel action: Prevents drag start type: swappable:start ``` -------------------------------- ### Swappable Usage (NPM) Source: https://github.com/shopify/draggable/blob/main/src/Swappable/README.md Demonstrates how to import and initialize Swappable using NPM. Requires the @shopify/draggable package. ```js import {Swappable} from '@shopify/draggable'; // Or import Swappable from '@shopify/draggable/build/esm/Swappable/Swappable'; const swappable = new Swappable(document.querySelectorAll('ul'), { draggable: 'li', }); ``` -------------------------------- ### Basic Drag and Drop Initialization Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Hamburger/Hamburger.html Demonstrates how to initialize the Shopify Draggable library with basic configuration to make elements within a container draggable. ```javascript import Draggable from '@shopify/draggable'; const container = document.getElementById('my-container'); const draggable = new Draggable(container, { draggable: '.my-draggable-item' }); console.log('Draggable initialized!'); ``` -------------------------------- ### Snappable Event Handling Example Source: https://github.com/shopify/draggable/blob/main/src/Plugins/Snappable/README.md Provides an example of how to attach event listeners to the Snappable plugin's custom events, specifically 'snap:in' and 'snap:out', to execute custom logic when snapping occurs. ```js import {Sortable, Plugins} from '@shopify/draggable'; const sortable = new Sortable(document.querySelectorAll('ul'), { draggable: 'li', plugins: [Plugins.Snappable], }); sortable.on('snap:in', () => console.log('snap:in')); sortable.on('snap:out', () => console.log('snap:out')); ``` -------------------------------- ### Basic Drag and Drop Initialization Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Brand/Logo.html Demonstrates how to initialize the Shopify Draggable library with basic configuration to make elements within a container draggable. ```javascript import Draggable from '@shopify/draggable'; const container = document.getElementById('my-container'); const draggable = new Draggable(container, { draggable: '.my-draggable-item' }); console.log('Draggable initialized!'); ``` -------------------------------- ### Flexbox Layout with Draggable Source: https://github.com/shopify/draggable/blob/main/examples/src/views/flexbox.html This example demonstrates how to maintain a flexbox layout when swapping direct children using Shopify's Draggable library. It utilizes CSS nth-child and adjacent sibling selectors to ensure the layout remains consistent during drag-and-drop operations. ```html {% extends 'templates/document.html' %} {% import 'components/Document/Head.html' as Head %} {% import 'components/Sidebar/Sidebar.html' as Sidebar %} {% import 'components/PageHeader/PageHeader.html' as PageHeader %} {% import 'content/Swappable/Flexbox/Flexbox.html' as Flexbox %} {% set ViewAttr = { id: 'Flexbox', parent: 'Swappable', child: 'Flexbox', subheading: 'Maintaining layout while swapping direct children can be challenging. This example solves the problem using nth-child and adjacent sibling selectors.' } %} {% block PageId %}{{ ViewAttr.id }}{% endblock %} {% block head %} {{ Head.render(ViewAttr) }} {% endblock %} {% block sidebar %} {{ Sidebar.render(ViewAttr, DataPages) }} {% endblock %} {% block main %} {{ PageHeader.render(ViewAttr) }} {{ Flexbox.render(ViewAttr.id) }} {% endblock %} ``` -------------------------------- ### Basic Drag and Drop Initialization Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Document/Favicon.html Demonstrates how to initialize the Shopify Draggable library with basic configuration to make elements within a container draggable. ```javascript import Draggable from '@shopify/draggable'; const container = document.getElementById('my-container'); const draggable = new Draggable(container, { draggable: '.my-draggable-item' }); console.log('Draggable initialized!'); ``` -------------------------------- ### Import Draggable modules via CDN Source: https://github.com/shopify/draggable/blob/main/README.md Demonstrates how to import the entire Draggable bundle or individual modules (Draggable, Sortable, Droppable, Swappable, Plugins) using ES modules from a CDN. Also shows how to use the UMD bundle. ```javascript ``` -------------------------------- ### Shopify Draggable API Documentation Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Brand/Wordmark.html Comprehensive API documentation for the Shopify Draggable library, detailing its core classes, methods, events, and configuration options for creating robust drag-and-drop interfaces. ```APIDOC Draggable: __init__(container, options) container: The DOM element that contains the draggable items. options: An object containing configuration options for the Draggable instance. - draggable: Selector for the draggable elements within the container. - handle: Selector for the element that acts as the drag handle. - delay: Delay in milliseconds before dragging starts. - distance: Minimum distance in pixels the mouse must move to start dragging. - axis: Restricts dragging to 'x' or 'y' axis. - autoScroll: Enables automatic scrolling of the container when dragging near the edges. - containment: Specifies the boundaries for dragging. - revert: If true, the draggable element will return to its original position after dropping. - sortable: If true, enables sorting of items within the container. - plugins: An array of Draggable plugins to use. on(eventName, callback) Registers a callback function for a specific event. eventName: The name of the event to listen for (e.g., 'drag:start', 'drag:move', 'drag:stop'). callback: The function to execute when the event is triggered. off(eventName, callback) Removes a previously registered event listener. eventName: The name of the event. callback: The specific callback function to remove. destroy() Destroys the Draggable instance and removes all event listeners. Events: 'drag:start': Triggered when a drag operation begins. - data: { originalEvent, source, dragHandle, cancel } 'drag:move': Triggered when the draggable element is moved. - data: { originalEvent, source, dragHandle, offset, position } 'drag:stop': Triggered when the drag operation ends. - data: { originalEvent, source, dragHandle, offset, position, cancel } 'drag:over': Triggered when a draggable element is dragged over another draggable element. - data: { originalEvent, source, over, direction } 'drag:enter': Triggered when a draggable element enters a drop zone. - data: { originalEvent, source, over } 'drag:leave': Triggered when a draggable element leaves a drop zone. - data: { originalEvent, source, over } 'drop': Triggered when a draggable element is dropped on a drop zone. - data: { originalEvent, source, over, data } Plugins: - SwapAnimation: Provides animation for swapping elements. - SortableAnimation: Provides animation for sorting elements. - Dropzone: Enables drop zone functionality. - KeyboardNavigation: Enables keyboard navigation for draggable items. Example Usage: const container = document.getElementById('my-draggable-container'); const draggable = new Draggable(container, { draggable: '.draggable-item', handle: '.drag-handle', plugins: [SwapAnimation, SortableAnimation] }); draggable.on('drag:stop', (event) => { console.log('Drag stopped:', event.source); }); ``` -------------------------------- ### Sortable Initialization with Mirror Options (X Axis Only) Source: https://github.com/shopify/draggable/blob/main/src/Draggable/Plugins/Mirror/README.md Example of initializing the Sortable component with custom Mirror plugin options, disabling the y-axis movement to only allow dragging along the x-axis. Similar to the Draggable example, it shows dimension constraints and cursor offsets. ```javascript import {Sortable} from '@shopify/draggable'; const sortable = new Sortable(document.querySelectorAll('ul'), { draggable: 'li', mirror: { constrainDimensions: true, cursorOffsetX: 10, cursorOffsetY: 10, yAxis: false, }, }); ``` -------------------------------- ### Shopify Draggable API Documentation Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Hamburger/Hamburger.html Comprehensive API documentation for the Shopify Draggable library, detailing its core classes, methods, events, and configuration options for creating robust drag-and-drop interfaces. ```APIDOC Draggable: __init__(container, options) container: The DOM element that contains the draggable items. options: An object containing configuration options for the Draggable instance. - draggable: Selector for the draggable elements within the container. - handle: Selector for the element that acts as the drag handle. - delay: Delay in milliseconds before dragging starts. - distance: Minimum distance in pixels the mouse must move to start dragging. - axis: Restricts dragging to 'x' or 'y' axis. - autoScroll: Enables automatic scrolling of the container when dragging near the edges. - containment: Specifies the boundaries for dragging. - revert: If true, the draggable element will return to its original position after dropping. - sortable: If true, enables sorting of items within the container. - plugins: An array of Draggable plugins to use. on(eventName, callback) Registers a callback function for a specific event. eventName: The name of the event to listen for (e.g., 'drag:start', 'drag:move', 'drag:stop'). callback: The function to execute when the event is triggered. off(eventName, callback) Removes a previously registered event listener. eventName: The name of the event. callback: The specific callback function to remove. destroy() Destroys the Draggable instance and removes all event listeners. Events: 'drag:start': Triggered when a drag operation begins. - data: { originalEvent, source, dragHandle, cancel } 'drag:move': Triggered when the draggable element is moved. - data: { originalEvent, source, dragHandle, offset, position } 'drag:stop': Triggered when the drag operation ends. - data: { originalEvent, source, dragHandle, offset, position, cancel } 'drag:over': Triggered when a draggable element is dragged over another draggable element. - data: { originalEvent, source, over, direction } 'drag:enter': Triggered when a draggable element enters a drop zone. - data: { originalEvent, source, over } 'drag:leave': Triggered when a draggable element leaves a drop zone. - data: { originalEvent, source, over } 'drop': Triggered when a draggable element is dropped on a drop zone. - data: { originalEvent, source, over, data } Plugins: - SwapAnimation: Provides animation for swapping elements. - SortableAnimation: Provides animation for sorting elements. - Dropzone: Enables drop zone functionality. - KeyboardNavigation: Enables keyboard navigation for draggable items. Example Usage: const container = document.getElementById('my-draggable-container'); const draggable = new Draggable(container, { draggable: '.draggable-item', handle: '.drag-handle', plugins: [SwapAnimation, SortableAnimation] }); draggable.on('drag:stop', (event) => { console.log('Drag stopped:', event.source); }); ``` -------------------------------- ### Droppable Usage (NPM) Source: https://github.com/shopify/draggable/blob/main/src/Droppable/README.md Demonstrates how to import and initialize Droppable using NPM. It requires the Droppable class and takes a selector for containers and options for draggable and dropzone elements. ```js import {Droppable} from '@shopify/draggable'; // Or import Droppable from '@shopify/draggable/build/esm/Droppable/Droppable'; const droppable = new Droppable(document.querySelectorAll('.container'), { draggable: '.item', dropzone: '.dropzone', }); ``` -------------------------------- ### Dynamic Announcements Example Source: https://github.com/shopify/draggable/blob/main/src/Draggable/Plugins/Announcement/README.md Shows how to use functions to generate dynamic announcements based on event data for drag and drop interactions. ```javascript import {Sortable} from '@shopify/draggable'; const announcements = { 'drag:start': (dragEvent) => { return `Picked up ${dragEvent.source.getAttribute('data-name')}`; }, 'drag:stop': (dragEvent) => { return `Dropped ${dragEvent.source.getAttribute('data-name')}` }, 'sortable:sorted': (sortableEvent) => { return `Sorted ${sortableEvent.dragEvent.source.getAttribute('data-name')} with ${sortableEvent.dragEvent.over.getAttribute('data-name')}`; }, } const sortable = new Sortable(document.querySelectorAll('ul'), { draggable: 'li', announcements, }); ``` -------------------------------- ### Render Simple List with Draggable Items Source: https://github.com/shopify/draggable/blob/main/examples/src/content/Sortable/SimpleList/SimpleList.html This snippet demonstrates rendering a simple list of stacked list items. Several items are configured with `draggable: true`, allowing them to be interactable within a draggable context. The `StackedListItem.render` macro is used for each item, passing the item's content and configuration options. ```html {% import 'components/StackedList/StackedListItem.html' as StackedListItem %} {% macro render(id) %} ### Simple list {{ StackedListItem.render('item one', {index: 1, draggable: true}) }} {{ StackedListItem.render('item two', {index: 2, draggable: true}) }} {{ StackedListItem.render('item three', {index: 3, draggable: true}) }} {{ StackedListItem.render('item four', {index: 4, draggable: true}) }} {{ StackedListItem.render('item five', {index: 5}) }} {{ StackedListItem.render('item six', {index: 6, draggable: true}) }} {{ StackedListItem.render('item seven', {index: 7, draggable: true}) }} {{ StackedListItem.render('item eight', {index: 8}) }} {{ StackedListItem.render('item nine', {index: 9}) }} {{ StackedListItem.render('item ten', {index: 10, draggable: true}) }} {{ StackedListItem.render('item eleven', {index: 11}) }} {{ StackedListItem.render('item twelve', {index: 12, draggable: true}) }} {% endmacro %} ``` -------------------------------- ### SortableStartEvent API Source: https://github.com/shopify/draggable/blob/main/src/Sortable/SortableEvent/README.md The SortableStartEvent is triggered when a drag operation begins. It extends SortableEvent and provides information about the starting position and container of the draggable item. This event is cancelable. ```APIDOC SortableStartEvent (extends SortableEvent): Properties: startIndex: Number (Read-only) - The starting index of the current draggable source. startContainer: HTMLElement (Read-only) - The starting container of the current draggable source. type: string - The type of the sortable event ('sortable:start'). Cancelable: true Cancel action: Prevents drag start ``` -------------------------------- ### Draggable API Reference Source: https://github.com/shopify/draggable/blob/main/src/Draggable/README.md Provides a comprehensive reference for the Draggable class and its methods, including initialization, event handling, plugin management, and state checking. ```APIDOC new Draggable(containers: HTMLElement[]|NodeList|HTMLElement, options: Object): Draggable Initializes a new Draggable instance. Requires specifying container(s) and an options object. draggable.destroy(): void Detaches all sensors and listeners, and cleans up the instance. draggable.on(eventName: String, listener: Function): Draggable Registers a callback function for a specific event. Supports method chaining. draggable.off(eventName: String, listener: Function): Draggable Unregisters a previously registered event listener. Requires the same callback function. draggable.trigger(event: AbstractEvent): void Triggers events internally or by extensions of Draggable. draggable.addPlugin(plugins: ...typeof Plugin): Draggable Adds plugins to the current Draggable instance. Supports method chaining. draggable.removePlugin(plugins: ...typeof Plugin): Draggable Removes plugins that are already attached to this Draggable instance. Supports method chaining. draggable.addSensor(sensors: ...typeof Sensor): Draggable Adds sensors to the current Draggable instance. Supports method chaining. draggable.removeSensor(sensors: ...typeof Sensor): Draggable Removes sensors that are already attached to this Draggable instance. Supports method chaining. draggable.addContainer(containers: ...HTMLElement): Draggable Adds containers to the current Draggable instance. Supports method chaining. draggable.removeContainer(containers: ...HTMLElement): Draggable Removes containers from this Draggable instance. Supports method chaining. draggable.getClassNameFor(name: String): String Returns the class name for a given class identifier. Refer to the classes table for identifiers. draggable.getClassNamesFor(name: String): String[] Returns an array of class names for a given class identifier, useful for atomic CSS. draggable.isDragging(): Boolean Returns true if the Draggable instance is currently in a dragging state, false otherwise. draggable.getDraggableElementsForContainer(container: HTMLElement): HTMLElement[] Returns an array of draggable elements within the specified container, excluding mirrors or original sources. draggable.cancel(): void Immediately cancels the current dragging state. Note: Cannot revert elements that have already been changed to their initial state (e.g., sorted elements). ``` -------------------------------- ### Collidable Plugin Integration Source: https://github.com/shopify/draggable/blob/main/examples/src/views/collidable.html This snippet shows how to include the Collidable plugin in your Shopify Draggable setup. It enables collision detection, allowing you to define elements that should resist dragging. ```html {% extends 'templates/document.html' %} {% import 'components/Document/Head.html' as Head %} {% import 'components/Sidebar/Sidebar.html' as Sidebar %} {% import 'components/PageHeader/PageHeader.html' as PageHeader %} {% import 'content/Plugins/Collidable/Collidable.html' as Collidable %} {% set ViewAttr = { id: 'Collidable', parent: 'Plugins', child: 'Collidable', subheading: 'Enable collision detection by including the Collidable plugin. You can now resist dragging over all elements specified as collision obstacles.' } %} {% block PageId %}{{ ViewAttr.id }}{% endblock %} {% block head %} {{ Head.render(ViewAttr) }} {% endblock %} {% block sidebar %} {{ Sidebar.render(ViewAttr, DataPages) }} {% endblock %} {% block main %} {{ PageHeader.render(ViewAttr) }} {{ Collidable.render(ViewAttr.id) }} {% endblock %} ``` -------------------------------- ### Touch Sensor Options Source: https://github.com/shopify/draggable/blob/main/src/Draggable/Sensors/TouchSensor/README.md Configuration options for the TouchSensor, controlling which elements are draggable, the delay before a drag starts, the minimum distance the pointer must move, and a specific handle element. ```APIDOC Options: draggable {String} A CSS selector to identify draggable elements within the specified containers. delay {Number} The delay in milliseconds before a drag operation can start. distance {Number} The minimum distance in pixels the pointer must move before a drag operation starts. handle {String} A CSS selector for a specific handle element within a draggable item. Dragging is restricted to this handle. ``` -------------------------------- ### Shopify Draggable API Documentation Source: https://github.com/shopify/draggable/blob/main/examples/src/components/Document/Favicon.html Comprehensive API documentation for the Shopify Draggable library, detailing its core classes, methods, events, and configuration options for creating robust drag-and-drop interfaces. ```APIDOC Draggable: __init__(container, options) container: The DOM element that contains the draggable items. options: An object containing configuration options for the Draggable instance. - draggable: Selector for the draggable elements within the container. - handle: Selector for the element that acts as the drag handle. - delay: Delay in milliseconds before dragging starts. - distance: Minimum distance in pixels the mouse must move to start dragging. - axis: Restricts dragging to 'x' or 'y' axis. - autoScroll: Enables automatic scrolling of the container when dragging near the edges. - containment: Specifies the boundaries for dragging. - revert: If true, the draggable element will return to its original position after dropping. - sortable: If true, enables sorting of items within the container. - plugins: An array of Draggable plugins to use. on(eventName, callback) Registers a callback function for a specific event. eventName: The name of the event to listen for (e.g., 'drag:start', 'drag:move', 'drag:stop'). callback: The function to execute when the event is triggered. off(eventName, callback) Removes a previously registered event listener. eventName: The name of the event. callback: The specific callback function to remove. destroy() Destroys the Draggable instance and removes all event listeners. Events: 'drag:start': Triggered when a drag operation begins. - data: { originalEvent, source, dragHandle, cancel } 'drag:move': Triggered when the draggable element is moved. - data: { originalEvent, source, dragHandle, offset, position } 'drag:stop': Triggered when the drag operation ends. - data: { originalEvent, source, dragHandle, offset, position, cancel } 'drag:over': Triggered when a draggable element is dragged over another draggable element. - data: { originalEvent, source, over, direction } 'drag:enter': Triggered when a draggable element enters a drop zone. - data: { originalEvent, source, over } 'drag:leave': Triggered when a draggable element leaves a drop zone. - data: { originalEvent, source, over } 'drop': Triggered when a draggable element is dropped on a drop zone. - data: { originalEvent, source, over, data } Plugins: - SwapAnimation: Provides animation for swapping elements. - SortableAnimation: Provides animation for sorting elements. - Dropzone: Enables drop zone functionality. - KeyboardNavigation: Enables keyboard navigation for draggable items. Example Usage: const container = document.getElementById('my-draggable-container'); const draggable = new Draggable(container, { draggable: '.draggable-item', handle: '.drag-handle', plugins: [SwapAnimation, SortableAnimation] }); draggable.on('drag:stop', (event) => { console.log('Drag stopped:', event.source); }); ``` -------------------------------- ### Cancel Dragging on ESC Key Source: https://github.com/shopify/draggable/blob/main/src/Draggable/README.md This example shows how to configure Draggable to cancel the current drag operation when the ESC key is pressed. This provides a common user-friendly way to abort a drag action. ```javascript import {Draggable} from '@shopify/draggable'; const draggable = new Draggable(document.querySelectorAll('ul'), { draggable: 'li', classes: { 'draggable:over': ['draggable--over', 'bg-red-200', 'bg-opacity-25'], }, }); // Note: The provided example snippet does not explicitly show how to cancel on ESC key. // This functionality is typically handled by listening to keyboard events or through specific Draggable options if available. ``` -------------------------------- ### Swappable Usage (Browser Standalone) Source: https://github.com/shopify/draggable/blob/main/src/Swappable/README.md Illustrates how to include Swappable in a browser environment using a UMD build from a CDN. ```html ``` -------------------------------- ### Rendering Draggable Blocks Source: https://github.com/shopify/draggable/blob/main/examples/src/content/Swappable/GridLayout/GridLayout.html This snippet shows how to render multiple 'Block' components, with several instances configured to be draggable. The 'draggable: true' option is passed as a parameter to enable this feature. ```html {% import 'components/Block/Block.html' as Block %} {% macro render(id) %} {{ Block.render('one', {index: 1, draggable: true}) }} {{ Block.render('two', {index: 2, draggable: true}) }} {{ Block.render('three', {index: 3}) }} {{ Block.render('four', {index: 4, draggable: true}) }} {{ Block.render('five', {index: 5, draggable: true}) }} {{ Block.render('six', {index: 6, draggable: true}) }} {{ Block.render('seven', {index: 7}) }} {% endmacro %} ``` -------------------------------- ### Import and Use ResizeMirror (Browser Standalone) Source: https://github.com/shopify/draggable/blob/main/src/Plugins/ResizeMirror/README.md Illustrates how to use the ResizeMirror plugin with the standalone UMD build of Draggable, typically included via a script tag in a browser environment. ```html ``` -------------------------------- ### Unique Dropzone Example Source: https://github.com/shopify/draggable/blob/main/examples/src/views/unique-dropzone.html This snippet illustrates the implementation of a unique dropzone where each draggable item is restricted to a specific dropzone identifier. It leverages the Shopify Draggable library to manage the drag-and-drop interactions and enforce this unique dropping behavior. ```html {% extends 'templates/document.html' %} {% import 'components/Document/Head.html' as Head %} {% import 'components/Sidebar/Sidebar.html' as Sidebar %} {% import 'components/PageHeader/PageHeader.html' as PageHeader %} {% import 'content/Droppable/UniqueDropzone/UniqueDropzone.html' as UniqueDropzone %} {% set ViewAttr = { id: 'UniqueDropzone', parent: 'Droppable', child: 'Unique dropzone', subheading: 'Dropzones are intended to hold only one Droppable child. This example restricts each Droppable item to a specific Dropzone identifier.' } %} {% block PageId %}{{ ViewAttr.id }}{% endblock %} {% block head %} {{ Head.render(ViewAttr) }} {% endblock %} {% block sidebar %} {{ Sidebar.render(ViewAttr, DataPages) }} {% endblock %} {% block main %} {{ PageHeader.render(ViewAttr) }} {{ UniqueDropzone.render(ViewAttr.id) }} {% endblock %} ``` -------------------------------- ### TypeScript Definitions Source: https://github.com/shopify/draggable/blob/main/README.md Information about the availability of TypeScript definitions for the Draggable library, with a link to the relevant documentation file. ```typescript /// // Example usage: const draggable = new Draggable(document.querySelectorAll('.draggable-element'), { // options }); ``` -------------------------------- ### Shopify Draggable Grid Layout Example Source: https://github.com/shopify/draggable/blob/main/examples/src/views/grid-layout.html This snippet demonstrates the use of the GridLayout component within the Shopify Draggable library. It shows how to render a grid layout for draggable items, utilizing wrapper elements for layout and styling flexibility. ```html {% extends 'templates/document.html' %} {% import 'components/Document/Head.html' as Head %} {% import 'components/Sidebar/Sidebar.html' as Sidebar %} {% import 'components/PageHeader/PageHeader.html' as PageHeader %} {% import 'content/Swappable/GridLayout/GridLayout.html' as GridLayout %} {% set ViewAttr = { id: 'GridLayout', parent: 'Swappable', child: 'Grid layout', subheading: 'Draggable children do not need to be direct descendants of their container. Wrapper elements can be used to maintain layout and simplify styling.' } %} {% block PageId %}{{ ViewAttr.id }}{% endblock %} {% block head %} {{ Head.render(ViewAttr) }} {% endblock %} {% block sidebar %} {{ Sidebar.render(ViewAttr, DataPages) }} {% endblock %} {% block main %} {{ PageHeader.render(ViewAttr) }} {{ GridLayout.render(ViewAttr.id) }} {% endblock %} ``` -------------------------------- ### Snappable Plugin Usage (NPM) Source: https://github.com/shopify/draggable/blob/main/src/Plugins/Snappable/README.md Demonstrates how to import and use the Snappable plugin with the Draggable library when using NPM. It shows two import methods and the initialization of Draggable with the Snappable plugin. ```js import {Draggable, Plugins} from '@shopify/draggable'; // Or import Draggable from '@shopify/draggable/build/esm/Draggable/Draggable'; import Snappable from '@shopify/draggable/build/esm/Plugins/Snappable'; const draggable = new Draggable(document.querySelectorAll('ul'), { draggable: 'li', plugins: [Plugins.Snappable], // Or [Snappable] }); ```