or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-draggable.mddroppable.mdevents.mdindex.mdplugins.mdsensors.mdsortable.mdswappable.md

index.mddocs/

0

# Shopify Draggable

1

2

Shopify Draggable is a comprehensive JavaScript drag-and-drop library built with TypeScript that offers complete control over drag-and-drop behavior through a flexible API. It abstracts native browser events (drag, mouse, touch, and force touch) into a unified interface and includes specialized modules: Sortable for reordering elements, Droppable for defining drop zones, and Swappable for element swapping.

3

4

## Package Information

5

6

- **Package Name**: @shopify/draggable

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @shopify/draggable`

10

11

## Core Imports

12

13

```typescript

14

import { Draggable, Sortable, Droppable, Swappable } from "@shopify/draggable";

15

```

16

17

Base classes and utilities:

18

19

```typescript

20

import { BaseEvent, BasePlugin, Sensors, Plugins } from "@shopify/draggable";

21

```

22

23

For CommonJS:

24

25

```javascript

26

const { Draggable, Sortable, Droppable, Swappable } = require("@shopify/draggable");

27

const { BaseEvent, BasePlugin, Sensors, Plugins } = require("@shopify/draggable");

28

```

29

30

ES modules (alternative imports):

31

32

```typescript

33

import Draggable from "@shopify/draggable/lib/draggable";

34

import Sortable from "@shopify/draggable/lib/sortable";

35

```

36

37

## Basic Usage

38

39

```typescript

40

import { Draggable } from "@shopify/draggable";

41

42

// Basic draggable setup

43

const draggable = new Draggable(document.querySelectorAll('.container'), {

44

draggable: '.item'

45

});

46

47

// Listen to drag events

48

draggable.on('drag:start', (event) => {

49

console.log('Started dragging:', event.source);

50

});

51

52

draggable.on('drag:stop', (event) => {

53

console.log('Stopped dragging:', event.source);

54

});

55

56

// Cleanup when done

57

draggable.destroy();

58

```

59

60

## Architecture

61

62

Shopify Draggable is built around several key components:

63

64

- **Core Draggable**: Base class providing fundamental drag-and-drop functionality

65

- **Specialized Classes**: Sortable, Droppable, and Swappable extend Draggable for specific use cases

66

- **Event System**: Comprehensive event lifecycle with cancelable events and custom data

67

- **Sensor System**: Pluggable input handling for mouse, touch, and native drag events

68

- **Plugin Architecture**: Extensible system with built-in plugins for mirrors, scrolling, announcements, etc.

69

- **Type Safety**: Full TypeScript integration with generic event types and comprehensive interfaces

70

71

## Capabilities

72

73

### Core Draggable

74

75

Basic drag-and-drop functionality with container management, event handling, and plugin system. Provides the foundation for all other draggable types.

76

77

```typescript { .api }

78

class Draggable<TEventListType = DraggableEventNames> {

79

constructor(containers: DraggableContainer, options?: DraggableOptions);

80

destroy(): void;

81

on<T extends TEventListType>(eventName: T, callback: (event: GetEventByEventName<T>) => void): this;

82

off<T extends TEventListType>(eventName: T, callback: (event: GetEventByEventName<T>) => void): this;

83

trigger(event: AbstractEvent): void;

84

isDragging(): boolean;

85

}

86

87

type DraggableContainer = HTMLElement | HTMLElement[] | NodeList;

88

```

89

90

[Core Draggable](./core-draggable.md)

91

92

### Sortable Lists

93

94

Reorder elements within or between containers with automatic position tracking and smooth animations. Perfect for to-do lists, priority queues, and dashboard widgets.

95

96

```typescript { .api }

97

class Sortable<T = SortableEventNames> extends Draggable<T> {

98

constructor(containers: DraggableContainer, options?: DraggableOptions);

99

index(element: HTMLElement): number;

100

getSortableElementsForContainer(container: HTMLElement): HTMLElement[];

101

}

102

```

103

104

[Sortable Lists](./sortable.md)

105

106

### Droppable Zones

107

108

Create designated drop zones where draggable elements can be placed. Includes visual feedback and validation for valid/invalid drop targets.

109

110

```typescript { .api }

111

class Droppable<T = DroppableEventNames> extends Draggable<T> {

112

constructor(containers: DraggableContainer, options: DroppableOptions);

113

getClassNameFor(name: DroppableClassNames): string;

114

}

115

116

interface DroppableOptions extends DraggableOptions {

117

dropzone: string | NodeList | HTMLElement[] | (() => NodeList | HTMLElement[]);

118

classes?: {[key in DroppableClassNames]: string};

119

}

120

```

121

122

[Droppable Zones](./droppable.md)

123

124

### Swappable Elements

125

126

Enable element swapping where dragging over another element exchanges their positions. Order-independent interaction for grid layouts and card arrangements.

127

128

```typescript { .api }

129

class Swappable<T = SwappableEventNames> extends Draggable<T> {

130

constructor(containers: DraggableContainer, options?: DraggableOptions);

131

}

132

```

133

134

[Swappable Elements](./swappable.md)

135

136

### Event System

137

138

Comprehensive event lifecycle with drag events, specialized events for each draggable type, and plugin-specific events. All events extend AbstractEvent with cancellation support.

139

140

```typescript { .api }

141

abstract class AbstractEvent<TData = {[key: string]: any}> {

142

readonly type: string;

143

readonly cancelable: boolean;

144

constructor(data: TData);

145

cancel(): void;

146

canceled(): boolean;

147

clone(data?: Partial<TData>): AbstractEvent<TData>;

148

}

149

150

export {AbstractEvent as BaseEvent};

151

```

152

153

[Events](./events.md)

154

155

### Sensors

156

157

Input detection system supporting mouse, touch, native drag events, and force touch. Pluggable architecture allows custom sensor implementation for specialized input handling.

158

159

```typescript { .api }

160

class Sensor {

161

constructor(containers: HTMLElement | HTMLElement[] | NodeList, options?: SensorOptions);

162

attach(): this;

163

detach(): this;

164

addContainer(...containers: HTMLElement[]): void;

165

removeContainer(...containers: HTMLElement[]): void;

166

trigger(element: HTMLElement, sensorEvent: SensorEvent): SensorEvent;

167

}

168

```

169

170

[Sensors](./sensors.md)

171

172

### Plugins

173

174

Extensible plugin system with built-in plugins for mirror elements, auto-scrolling, accessibility announcements, focus management, collision detection, and animations.

175

176

```typescript { .api }

177

abstract class AbstractPlugin {

178

constructor(draggable: Draggable);

179

protected abstract attach(): void;

180

protected abstract detach(): void;

181

}

182

183

export {AbstractPlugin as BasePlugin};

184

```

185

186

[Plugins](./plugins.md)

187

188

## Types

189

190

```typescript { .api }

191

interface DraggableOptions {

192

draggable?: string;

193

distance?: number;

194

handle?: string | NodeList | HTMLElement[] | HTMLElement | ((currentElement: HTMLElement) => HTMLElement);

195

delay?: number | DelayOptions;

196

placedTimeout?: number;

197

plugins?: (typeof AbstractPlugin)[];

198

sensors?: Sensor[];

199

exclude?: {

200

plugins?: (typeof AbstractPlugin)[];

201

sensors?: (typeof Sensor)[];

202

};

203

classes?: {[key in DraggableClassNames]: string | string[]};

204

announcements?: AnnouncementOptions;

205

collidables?: Collidables;

206

mirror?: MirrorOptions;

207

scrollable?: ScrollableOptions;

208

swapAnimation?: SwapAnimationOptions;

209

sortAnimation?: SortAnimationOptions;

210

}

211

212

interface DelayOptions {

213

mouse?: number;

214

drag?: number;

215

touch?: number;

216

}

217

218

type DraggableClassNames =

219

| 'body:dragging'

220

| 'container:dragging'

221

| 'source:dragging'

222

| 'source:placed'

223

| 'container:placed'

224

| 'draggable:over'

225

| 'container:over'

226

| 'source:original'

227

| 'mirror';

228

```