0
# Core Draggable
1
2
The base Draggable class provides fundamental drag-and-drop functionality with container management, event handling, and plugin system. It serves as the foundation for all specialized draggable types.
3
4
## Capabilities
5
6
### Draggable Constructor
7
8
Creates a new draggable instance with specified containers and options.
9
10
```typescript { .api }
11
/**
12
* Creates a new draggable instance
13
* @param containers - Elements that contain draggable items
14
* @param options - Configuration options for drag behavior
15
*/
16
constructor(containers: DraggableContainer, options?: DraggableOptions);
17
18
type DraggableContainer = HTMLElement | HTMLElement[] | NodeList;
19
```
20
21
**Usage Example:**
22
23
```typescript
24
import { Draggable } from "@shopify/draggable";
25
26
// Single container
27
const draggable = new Draggable(document.querySelector('.container'), {
28
draggable: '.item',
29
delay: 150
30
});
31
32
// Multiple containers
33
const containers = document.querySelectorAll('.drag-container');
34
const multiContainer = new Draggable(containers, {
35
draggable: '.draggable-item'
36
});
37
```
38
39
### Instance Management
40
41
Methods for managing the draggable instance lifecycle.
42
43
```typescript { .api }
44
/**
45
* Destroys the draggable instance and removes all event listeners
46
*/
47
destroy(): void;
48
49
/**
50
* Cancels the current drag operation immediately
51
*/
52
cancel(): void;
53
54
/**
55
* Returns true if currently dragging an element
56
*/
57
isDragging(): boolean;
58
```
59
60
### Event Handling
61
62
Methods for managing event listeners and triggering custom events.
63
64
```typescript { .api }
65
/**
66
* Adds an event listener for drag events
67
* @param eventName - Name of the event to listen for
68
* @param callback - Function to call when event occurs
69
* @returns This draggable instance for chaining
70
*/
71
on<T extends TEventListType>(eventName: T, callback: (event: GetEventByEventName<T>) => void): this;
72
73
/**
74
* Removes an event listener
75
* @param eventName - Name of the event
76
* @param callback - Function to remove
77
* @returns This draggable instance for chaining
78
*/
79
off<T extends TEventListType>(eventName: T, callback: (event: GetEventByEventName<T>) => void): this;
80
81
/**
82
* Triggers a custom event
83
* @param event - Event instance to trigger
84
* @returns This draggable instance for chaining
85
*/
86
trigger(event: AbstractEvent): void;
87
```
88
89
**Usage Example:**
90
91
```typescript
92
const draggable = new Draggable(containers, options);
93
94
// Add event listeners
95
draggable.on('drag:start', (event) => {
96
console.log('Drag started:', event.source);
97
// Optionally cancel the drag
98
// event.cancel();
99
});
100
101
draggable.on('drag:move', (event) => {
102
console.log('Dragging over:', event.over);
103
});
104
105
// Remove event listener
106
const handleDragStop = (event) => {
107
console.log('Drag stopped');
108
};
109
draggable.on('drag:stop', handleDragStop);
110
draggable.off('drag:stop', handleDragStop);
111
```
112
113
### Container Management
114
115
Methods for managing draggable containers after initialization.
116
117
```typescript { .api }
118
/**
119
* Adds containers to the draggable instance
120
* @param containers - Container elements to add
121
* @returns This draggable instance for chaining
122
*/
123
addContainer(...containers: HTMLElement[]): this;
124
125
/**
126
* Removes containers from the draggable instance
127
* @param containers - Container elements to remove
128
* @returns This draggable instance for chaining
129
*/
130
removeContainer(...containers: HTMLElement[]): this;
131
132
/**
133
* Returns all draggable elements across all containers
134
*/
135
getDraggableElements(): HTMLElement[];
136
137
/**
138
* Returns draggable elements for a specific container
139
* @param container - Container to get elements from
140
*/
141
getDraggableElementsForContainer(container: HTMLElement): HTMLElement[];
142
```
143
144
### Plugin Management
145
146
Methods for adding and removing plugins dynamically.
147
148
```typescript { .api }
149
/**
150
* Adds plugins to the draggable instance
151
* @param plugins - Plugin classes to add
152
* @returns This draggable instance for chaining
153
*/
154
addPlugin(...plugins: (typeof AbstractPlugin)[]): this;
155
156
/**
157
* Removes plugins from the draggable instance
158
* @param plugins - Plugin classes to remove
159
* @returns This draggable instance for chaining
160
*/
161
removePlugin(...plugins: (typeof AbstractPlugin)[]): this;
162
```
163
164
### Sensor Management
165
166
Methods for managing input sensors.
167
168
```typescript { .api }
169
/**
170
* Adds sensors to the draggable instance
171
* @param sensors - Sensor classes to add
172
* @returns This draggable instance for chaining
173
*/
174
addSensor(...sensors: (typeof Sensor)[]): this;
175
176
/**
177
* Removes sensors from the draggable instance
178
* @param sensors - Sensor classes to remove
179
* @returns This draggable instance for chaining
180
*/
181
removeSensor(...sensors: (typeof Sensor)[]): this;
182
```
183
184
### CSS Class Management
185
186
Methods for working with CSS classes applied during drag operations.
187
188
```typescript { .api }
189
/**
190
* Returns the first CSS class name for a class identifier
191
* @param name - Class identifier name
192
*/
193
getClassNameFor(name: DraggableClassNames): string;
194
195
/**
196
* Returns all CSS class names for a class identifier
197
* @param name - Class identifier name
198
*/
199
getClassNamesFor(name: DraggableClassNames): string[];
200
```
201
202
### Static Properties
203
204
Static properties available on the Draggable class.
205
206
```typescript { .api }
207
class Draggable {
208
static Plugins: {
209
Announcement: typeof Announcement;
210
Focusable: typeof Focusable;
211
Mirror: typeof Mirror;
212
Scrollable: typeof Scrollable;
213
};
214
215
static Sensors: {
216
MouseSensor: typeof MouseSensor;
217
TouchSensor: typeof TouchSensor;
218
};
219
}
220
```
221
222
## Options Interface
223
224
```typescript { .api }
225
interface DraggableOptions {
226
/** CSS selector for draggable elements within containers */
227
draggable?: string;
228
/** Minimum distance in pixels before drag starts */
229
distance?: number;
230
/** CSS selector, elements, or function defining drag handles */
231
handle?: string | NodeList | HTMLElement[] | HTMLElement | ((currentElement: HTMLElement) => HTMLElement);
232
/** Delay before drag starts (number or per-input delays) */
233
delay?: number | DelayOptions;
234
/** Timeout in milliseconds for removing placed classes after drop */
235
placedTimeout?: number;
236
/** Array of plugin classes to add */
237
plugins?: (typeof AbstractPlugin)[];
238
/** Array of sensor instances to use */
239
sensors?: Sensor[];
240
/** Plugins and sensors to exclude from defaults */
241
exclude?: {
242
plugins?: (typeof AbstractPlugin)[];
243
sensors?: (typeof Sensor)[];
244
};
245
/** CSS class names for different drag states */
246
classes?: {[key in DraggableClassNames]: string | string[]};
247
/** Accessibility announcement options */
248
announcements?: AnnouncementOptions;
249
/** Collidable elements for collision detection */
250
collidables?: Collidables;
251
/** Mirror plugin options */
252
mirror?: MirrorOptions;
253
/** Scrollable plugin options */
254
scrollable?: ScrollableOptions;
255
/** Swap animation options */
256
swapAnimation?: SwapAnimationOptions;
257
/** Sort animation options */
258
sortAnimation?: SortAnimationOptions;
259
}
260
261
interface DelayOptions {
262
mouse?: number;
263
drag?: number;
264
touch?: number;
265
}
266
267
type DraggableClassNames =
268
| 'body:dragging'
269
| 'container:dragging'
270
| 'source:dragging'
271
| 'source:placed'
272
| 'container:placed'
273
| 'draggable:over'
274
| 'container:over'
275
| 'source:original'
276
| 'mirror';
277
```
278
279
**Usage Example:**
280
281
```typescript
282
const draggable = new Draggable(containers, {
283
draggable: '.drag-item',
284
handle: '.drag-handle',
285
delay: { mouse: 100, touch: 150 },
286
distance: 10,
287
placedTimeout: 1000,
288
exclude: {
289
sensors: [TouchSensor], // Exclude touch sensor on desktop
290
plugins: [Announcement] // Exclude announcement plugin
291
},
292
classes: {
293
'source:dragging': 'my-dragging-class',
294
'body:dragging': 'drag-in-progress'
295
},
296
mirror: {
297
constrainDimensions: true,
298
xAxis: true,
299
yAxis: true
300
},
301
scrollable: {
302
speed: 15,
303
sensitivity: 50
304
}
305
});
306
```