← Back to Skills Marketplace
openlark

@shopify/draggable — Drag & Drop Interaction Skill

by OpenLark · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ Security Clean
44
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install shopify-draggable
Description
Implement drag-and-drop interactions with @shopify/draggable. Supports Draggable (basic drag), Sortable (reordering), Droppable (drop zones), Swappable (swap...
README (SKILL.md)

@shopify/draggable — Drag & Drop Interaction Skill

Built on Shopify's @shopify/draggable (MIT license, v1.2.1). Pure JS library, zero runtime dependencies, supports ES modules and UMD.

Use cases

sortable lists, droppable panels, custom drag interactions, kanban/grid drag-and-drop reorganization. No longer maintained, now community-maintained.

Install

npm install @shopify/draggable

Or via CDN (recommended for prototyping):

\x3Cscript type="module">
import { Draggable, Sortable, Droppable, Swappable } from 'https://cdn.jsdelivr.net/npm/@shopify/draggable/build/esm/index.mjs';
\x3C/script>

Module Overview

Module Class Purpose
Base Draggable Core drag engine, manages mirror, sensors, and events
Sorting Sortable Reorder on drag, tracks old and new indices
Drop Zone Droppable Drag elements into/out of specific dropzones
Swap Swappable Swap two element positions on drag (no sorting)

Quick Start

Basic Drag

import Draggable from '@shopify/draggable';

const draggable = new Draggable(document.querySelectorAll('.container'), {
  draggable: '.draggable-source',
});

draggable.on('drag:start', (event) => {
  console.log('Started dragging:', event.source);
});

draggable.on('drag:stop', () => {
  console.log('Drag ended');
});

Sortable List

import Sortable from '@shopify/draggable';

const sortable = new Sortable(document.querySelectorAll('.list'), {
  draggable: '.list-item',
  delay: { mouse: 200, touch: 300 },
});

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

Drag into Drop Zone

import Droppable from '@shopify/draggable';

const droppable = new Droppable(document.querySelectorAll('.source-container'), {
  draggable: '.card',
  dropzone: '.dropzone',
});

droppable.on('droppable:dropped', (event) => {
  console.log('Dropped into dropzone:', event.dropzone);
});

droppable.on('droppable:returned', (event) => {
  console.log('Returned to original position');
});

Element Swap

import Swappable from '@shopify/draggable';

const swappable = new Swappable(document.querySelectorAll('.grid'), {
  draggable: '.grid-item',
});

swappable.on('swappable:swapped', (event) => {
  console.log('Swapped element:', event.swappedElement);
});

Configuration Options

Option Type Default Description
draggable String '.draggable-source' CSS selector for draggable elements
handle String|null null CSS selector for drag handle
delay Object {} Delay before drag starts ({ mouse: ms, touch: ms })
distance Number 0 Minimum pixels to move before dragging
placedTimeout Number 800 Delay before removing placed CSS classes (ms)
plugins Array [] Additional plugins
sensors Array [] Additional sensors
classes Object see below Custom CSS class names
announcements Object see below Accessibility announcements

CSS Class Map

const defaultClasses = {
  'container:dragging': 'draggable-container--is-dragging',
  'source:dragging':    'draggable-source--is-dragging',
  'source:placed':      'draggable-source--placed',
  'container:placed':   'draggable-container--placed',
  'body:dragging':      'draggable--is-dragging',
  'draggable:over':     'draggable--over',
  'container:over':     'draggable-container--over',
  'source:original':    'draggable--original',
  mirror:               'draggable-mirror',
};

Droppable additional classes:

Identifier Default Class Description
droppable:active draggable-dropzone--active Accepting drop zones
droppable:occupied draggable-dropzone--occupied Occupied drop zones

Excluding Default Plugins/Sensors

new Draggable(containers, {
  exclude: {
    plugins: [],     // List of plugin constructors
    sensors: [],     // List of sensor constructors
  },
});

Events API

Base Events (All Modules)

Event Trigger
drag:start Drag started
drag:move Drag moving
drag:over Hovering over another draggable element
drag:over:container Hovering over another container
drag:out Moved out of an element
drag:out:container Moved out of a container
drag:stop Drag stopped
drag:pressure Pressure change (Force Touch)
drag:stopped Drag fully ended

Common Event Properties

draggable.on('drag:start', (event) => {
  event.source;           // Cloned source element
  event.originalSource;   // Original element (display:none)
  event.sourceContainer;  // Source container
  event.sensorEvent;      // Original sensor event
  event.cancel();         // Cancel the drag
});

Sortable Events

Event Additional Properties
sortable:start startIndex, startContainer
sortable:sort currentIndex, source, over
sortable:sorted oldIndex, newIndex, oldContainer, newContainer
sortable:stop oldIndex, newIndex, oldContainer, newContainer

Droppable Events

Event Additional Properties
droppable:start dragEvent, dropzone
droppable:dropped dragEvent, dropzone
droppable:returned dragEvent, dropzone
droppable:stop dragEvent, dropzone

Swappable Events

Event Additional Properties
swappable:start dragEvent
swappable:swap dragEvent, over, overContainer
swappable:swapped dragEvent, swappedElement
swappable:stop dragEvent

Plugins

Plugin Class Function
Announcement Draggable.Plugins.Announcement Live accessibility announcements during drag
Focusable Draggable.Plugins.Focusable Keyboard focus management
Mirror Draggable.Plugins.Mirror Shows mirror element while dragging (enabled by default)
Scrollable Draggable.Plugins.Scrollable Auto-scroll container when dragging near edge
Collidable Plugins.Collidable Collision detection (requires separate import)
ResizeMirror Plugins.ResizeMirror Auto-resize mirror element
Snappable Plugins.Snappable Snap to specific positions
SwapAnimation Plugins.SwapAnimation Swap animation
SortAnimation Plugins.SortAnimation Sort animation

Collidable

import { Plugins } from '@shopify/draggable';
import Collidable from '@shopify/draggable/build/esm/Plugins/Collidable';

new Draggable(containers, {
  plugins: [Collidable],
});

Collidable events: collidable:in (entered collision), collidable:out (left collision).

Snappable

import Snappable from '@shopify/draggable/build/esm/Plugins/Snappable';
new Draggable(containers, {
  plugins: [Snappable],
});

Sensors

Sensor Description Default
MouseSensor Mouse drag
TouchSensor Touch drag
ForceTouchSensor Force Touch pressure
DragSensor Native HTML5 Drag & Drop
import { Draggable } from '@shopify/draggable';
import ForceTouchSensor from '@shopify/draggable/build/esm/Draggable/Sensors/ForceTouchSensor';

new Draggable(containers, {
  sensors: [ForceTouchSensor],
});

Instance Methods

Method Description
addPlugin(...plugins) Add plugins
removePlugin(...plugins) Remove plugins
addSensor(...sensors) Add sensors
removeSensor(...sensors) Remove sensors
addContainer(...containers) Dynamically add containers
removeContainer(...containers) Dynamically remove containers
on(type, ...callbacks) Bind event listener
off(type, callback) Unbind event listener
trigger(event) Trigger an event
isDragging() Check if currently dragging
getDraggableElements() Get all draggable elements
cancel() Immediately cancel current drag
destroy() Destroy the instance

Common Patterns

Drag with Handle

new Sortable(document.querySelectorAll('.list'), {
  draggable: '.list-item',
  handle: '.drag-handle',   // Only .drag-handle can trigger drag
});

Delay & Minimum Distance (Prevent Accidental Drag)

new Draggable(containers, {
  delay: { mouse: 100, touch: 200 },
  distance: 5,            // Must move 5px before dragging
});

Cross-Container Sorting

const sortable = new Sortable(document.querySelectorAll('.column'), {
  draggable: '.card',
  delay: { touch: 200 },
});
// Cross-container drag is supported automatically

Prevent Specific Drags

draggable.on('drag:start', (event) => {
  if (event.source.dataset.draggable === 'false') {
    event.cancel();
  }
});

Custom Mirror Style

import Draggable from '@shopify/draggable';

const draggable = new Draggable(containers, {
  classes: {
    mirror: 'my-custom-mirror',
  },
});

// Or customize via CSS
// .draggable-mirror { opacity: 0.7; transform: scale(1.05); }

Lifecycle

constructor()
  ↓
draggable:initialized
  ↓
drag:start ──→ drag:move ──→ drag:stop ──→ drag:stopped
  ↓              ↓              ↓
Plugin events  sortable:sorted  sortable:stop
  ↓           droppable:       droppable:stop
cancel()      dropped          swappable:stop
              swappable:
              swapped
  ↓
destroy()

Notes

  • Draggable does not perform sorting by itself — Sortable, Droppable, and Swappable are its subclasses
  • The source element is set to display: none during drag; the mirror takes its visual place
  • No longer maintained by the original Shopify authors; now community-maintained. Evaluate risk for production use
  • TypeScript type definitions are bundled — no need to install @types separately
  • Does not support IE11; targets ES6 modern browsers
  • Use jsdelivr for CDN; avoid unpkg (incompatible paths)
Usage Guidance
This skill is reasonable to install if you want guidance for @shopify/draggable. For production apps, pin package versions, prefer npm/bundled builds over runtime CDN imports, and review the third-party library’s maintenance status and browser compatibility before adopting it.
Capability Assessment
Purpose & Capability
The artifact coherently explains how to implement drag-and-drop UI behavior with @shopify/draggable, including Draggable, Sortable, Droppable, Swappable, plugins, sensors, events, and configuration.
Instruction Scope
Instructions stay within library installation and frontend usage examples; no prompt overrides, hidden role changes, credential handling, local data access, or unrelated commands were found.
Install Mechanism
The package contains a single SKILL.md file. Its only install guidance is npm install @shopify/draggable or a jsDelivr CDN import, both expected for this frontend library purpose.
Credentials
The behavior is proportionate for a drag-and-drop integration skill. The main operational consideration is that it relies on a third-party library and mentions CDN use for prototyping.
Persistence & Privilege
No persistence, background workers, privilege escalation, system modification, auth/session access, or data exfiltration behavior appears in the artifact.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install shopify-draggable
  3. After installation, invoke the skill by name or use /shopify-draggable
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release of the Shopify Draggable skill. - Provides drag-and-drop interactions with @shopify/draggable (v1.2.1) - Supports Draggable (basic drag), Sortable (reordering), Droppable (drop zones), and Swappable (element swap) modules - Describes plugin and sensor options for advanced behaviors such as mirror, snapping, collision detection, scroll, and accessibility - Details configuration options, event APIs, and usage examples for sortable lists, grid swapping, and drop zones - Includes guidance for plugin use, events, CSS customization, and extending with sensors
Metadata
Slug shopify-draggable
Version 1.0.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is @shopify/draggable — Drag & Drop Interaction Skill?

Implement drag-and-drop interactions with @shopify/draggable. Supports Draggable (basic drag), Sortable (reordering), Droppable (drop zones), Swappable (swap... It is an AI Agent Skill for Claude Code / OpenClaw, with 44 downloads so far.

How do I install @shopify/draggable — Drag & Drop Interaction Skill?

Run "/install shopify-draggable" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is @shopify/draggable — Drag & Drop Interaction Skill free?

Yes, @shopify/draggable — Drag & Drop Interaction Skill is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does @shopify/draggable — Drag & Drop Interaction Skill support?

@shopify/draggable — Drag & Drop Interaction Skill is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created @shopify/draggable — Drag & Drop Interaction Skill?

It is built and maintained by OpenLark (@openlark); the current version is v1.0.0.

💬 Comments