← 返回 Skills 市场
openlark

@shopify/draggable — Drag & Drop Interaction Skill

作者 OpenLark · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
44
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install shopify-draggable
功能描述
Implement drag-and-drop interactions with @shopify/draggable. Supports Draggable (basic drag), Sortable (reordering), Droppable (drop zones), Swappable (swap...
使用说明 (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)
安全使用建议
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.
能力评估
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.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install shopify-draggable
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /shopify-draggable 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
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
元数据
Slug shopify-draggable
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

@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... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 44 次。

如何安装 @shopify/draggable — Drag & Drop Interaction Skill?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install shopify-draggable」即可一键安装,无需额外配置。

@shopify/draggable — Drag & Drop Interaction Skill 是免费的吗?

是的,@shopify/draggable — Drag & Drop Interaction Skill 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

@shopify/draggable — Drag & Drop Interaction Skill 支持哪些平台?

@shopify/draggable — Drag & Drop Interaction Skill 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 @shopify/draggable — Drag & Drop Interaction Skill?

由 OpenLark(@openlark)开发并维护,当前版本 v1.0.0。

💬 留言讨论