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

events.mddocs/

0

# Events

1

2

Shopify Draggable provides a comprehensive event system with drag events, specialized events for each draggable type, and plugin-specific events. All events extend AbstractEvent and support cancellation.

3

4

## Capabilities

5

6

### Base Event Class

7

8

All events inherit from AbstractEvent providing common functionality.

9

10

```typescript { .api }

11

/**

12

* Base class for all draggable events

13

*/

14

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

15

readonly type: string;

16

readonly cancelable: boolean;

17

constructor(data: TData);

18

cancel(): void;

19

canceled(): boolean;

20

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

21

}

22

23

export {AbstractEvent as BaseEvent};

24

```

25

26

**Usage Example:**

27

28

```typescript

29

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

30

console.log('Event type:', event.type);

31

console.log('Can cancel:', event.cancelable);

32

33

// Cancel the event if needed

34

if (shouldCancelDrag()) {

35

event.cancel();

36

}

37

38

// Check if event was canceled

39

if (event.canceled()) {

40

console.log('Event was canceled');

41

}

42

});

43

```

44

45

### Core Drag Events

46

47

Base drag events that fire during drag operations for all draggable types.

48

49

```typescript { .api }

50

class DragEvent extends AbstractEvent {

51

readonly source: HTMLElement;

52

readonly originalSource: HTMLElement;

53

readonly mirror: HTMLElement;

54

readonly sourceContainer: HTMLElement;

55

readonly sensorEvent: SensorEvent;

56

readonly originalEvent: Event;

57

}

58

59

class DragStartEvent extends DragEvent {}

60

class DragMoveEvent extends DragEvent {}

61

class DragStopEvent extends DragEvent {}

62

class DragStoppedEvent extends DragEvent {}

63

64

class DragOverEvent extends DragEvent {

65

readonly overContainer: HTMLElement;

66

readonly over: HTMLElement;

67

}

68

69

class DragOutEvent extends DragEvent {

70

readonly overContainer: HTMLElement;

71

readonly over: HTMLElement;

72

}

73

74

class DragOverContainerEvent extends DragEvent {

75

readonly overContainer: HTMLElement;

76

}

77

78

class DragOutContainerEvent extends DragEvent {

79

readonly overContainer: HTMLElement;

80

}

81

82

class DragPressureEvent extends DragEvent {

83

readonly pressure: number;

84

}

85

```

86

87

**Event Names:**

88

89

```typescript { .api }

90

type DraggableEventNames =

91

| 'draggable:initialize'

92

| 'draggable:destroy'

93

| 'drag:start'

94

| 'drag:move'

95

| 'drag:over'

96

| 'drag:over:container'

97

| 'drag:out'

98

| 'drag:out:container'

99

| 'drag:stop'

100

| 'drag:stopped'

101

| 'drag:pressure'

102

| MirrorEventNames;

103

```

104

105

**Usage Example:**

106

107

```typescript

108

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

109

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

110

console.log('Original element:', event.originalSource);

111

console.log('From container:', event.sourceContainer);

112

});

113

114

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

115

console.log('Dragging over:', event.over);

116

console.log('In container:', event.overContainer);

117

});

118

119

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

120

console.log('Pressure level:', event.pressure);

121

// Handle force touch or pressure-sensitive input

122

if (event.pressure > 0.8) {

123

showContextMenu(event.source);

124

}

125

});

126

```

127

128

### Draggable Lifecycle Events

129

130

Events specific to Draggable instance lifecycle.

131

132

```typescript { .api }

133

class DraggableEvent extends AbstractEvent {

134

readonly draggable: Draggable;

135

}

136

137

class DraggableInitializedEvent extends DraggableEvent {}

138

class DraggableDestroyEvent extends DraggableEvent {}

139

```

140

141

**Usage Example:**

142

143

```typescript

144

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

145

console.log('Draggable initialized:', event.draggable);

146

setupDragCallbacks(event.draggable);

147

});

148

149

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

150

console.log('Draggable being destroyed');

151

cleanupDragCallbacks();

152

});

153

```

154

155

### Sortable Events

156

157

Events specific to sortable operations.

158

159

```typescript { .api }

160

class SortableEvent extends AbstractEvent {

161

readonly dragEvent: DragEvent;

162

}

163

164

class SortableStartEvent extends SortableEvent {

165

readonly startIndex: number;

166

readonly startContainer: HTMLElement;

167

}

168

169

class SortableSortEvent extends SortableEvent {

170

readonly oldIndex: number;

171

readonly newIndex: number;

172

readonly oldContainer: HTMLElement;

173

readonly newContainer: HTMLElement;

174

}

175

176

class SortableSortedEvent extends SortableEvent {

177

readonly oldIndex: number;

178

readonly newIndex: number;

179

readonly oldContainer: HTMLElement;

180

readonly newContainer: HTMLElement;

181

}

182

183

class SortableStopEvent extends SortableEvent {

184

readonly oldIndex: number;

185

readonly newIndex: number;

186

readonly oldContainer: HTMLElement;

187

readonly newContainer: HTMLElement;

188

}

189

```

190

191

**Event Names:**

192

193

```typescript { .api }

194

type SortableEventNames =

195

| 'sortable:start'

196

| 'sortable:sort'

197

| 'sortable:sorted'

198

| 'sortable:stop'

199

| DraggableEventNames;

200

```

201

202

### Droppable Events

203

204

Events specific to droppable operations.

205

206

```typescript { .api }

207

class DroppableEvent extends AbstractEvent {

208

readonly dragEvent: DragEvent;

209

}

210

211

class DroppableStartEvent extends DroppableEvent {

212

dropzone: HTMLElement;

213

}

214

215

class DroppableDroppedEvent extends DroppableEvent {

216

dropzone: HTMLElement;

217

}

218

219

class DroppableReturnedEvent extends DroppableEvent {

220

dropzone: HTMLElement;

221

}

222

223

class DroppableStopEvent extends DroppableEvent {

224

dropzone: HTMLElement;

225

}

226

```

227

228

**Event Names:**

229

230

```typescript { .api }

231

type DroppableEventNames =

232

| 'droppable:start'

233

| 'droppable:dropped'

234

| 'droppable:returned'

235

| 'droppable:stop'

236

| DraggableEventNames;

237

```

238

239

### Swappable Events

240

241

Events specific to swappable operations.

242

243

```typescript { .api }

244

class SwappableEvent extends AbstractEvent {

245

readonly dragEvent: DragEvent;

246

}

247

248

class SwappableStartEvent extends SwappableEvent {}

249

250

class SwappableSwapEvent extends SwappableEvent {

251

readonly over: HTMLElement;

252

readonly overContainer: HTMLElement;

253

}

254

255

class SwappableSwappedEvent extends SwappableEvent {

256

readonly swappedElement: HTMLElement;

257

}

258

259

class SwappableStopEvent extends SwappableEvent {}

260

```

261

262

**Event Names:**

263

264

```typescript { .api }

265

type SwappableEventNames =

266

| 'swappable:start'

267

| 'swappable:swap'

268

| 'swappable:swapped'

269

| 'swappable:stop'

270

| DraggableEventNames;

271

```

272

273

### Mirror Events

274

275

Events related to the mirror plugin that creates drag representations.

276

277

```typescript { .api }

278

class MirrorEvent extends AbstractEvent {

279

readonly source: HTMLElement;

280

readonly originalSource: HTMLElement;

281

readonly sourceContainer: HTMLElement;

282

readonly sensorEvent: SensorEvent;

283

readonly originalEvent: Event;

284

}

285

286

class MirrorCreateEvent extends MirrorEvent {}

287

288

class MirrorCreatedEvent extends MirrorEvent {

289

readonly mirror: HTMLElement;

290

}

291

292

class MirrorAttachedEvent extends MirrorEvent {

293

readonly mirror: HTMLElement;

294

}

295

296

class MirrorMoveEvent extends MirrorEvent {

297

readonly mirror: HTMLElement;

298

readonly passedThreshX: boolean;

299

readonly passedThreshY: boolean;

300

}

301

302

class MirrorMovedEvent extends MirrorEvent {

303

readonly mirror: HTMLElement;

304

readonly passedThreshX: boolean;

305

readonly passedThreshY: boolean;

306

}

307

308

class MirrorDestroyEvent extends MirrorEvent {

309

readonly mirror: HTMLElement;

310

}

311

```

312

313

**Event Names:**

314

315

```typescript { .api }

316

type MirrorEventNames =

317

| 'mirror:create'

318

| 'mirror:created'

319

| 'mirror:attached'

320

| 'mirror:move'

321

| 'mirror:moved'

322

| 'mirror:destroy';

323

```

324

325

### Plugin Events

326

327

Events from additional plugins.

328

329

```typescript { .api }

330

// Collidable Plugin Events

331

class CollidableEvent extends AbstractEvent {

332

readonly dragEvent: DragEvent;

333

readonly collidingElement: HTMLElement;

334

}

335

336

class CollidableInEvent extends CollidableEvent {}

337

class CollidableOutEvent extends CollidableEvent {}

338

339

type CollidableEventNames = 'collidable:in' | 'collidable:out';

340

341

// Snappable Plugin Events

342

class SnapEvent extends AbstractEvent {

343

readonly dragEvent: DragEvent;

344

readonly snappable: HTMLElement;

345

}

346

347

class SnapInEvent extends SnapEvent {}

348

class SnapOutEvent extends SnapEvent {}

349

350

type SnappableEventNames = 'snap:in' | 'snap:out';

351

```

352

353

## Event Type Helper

354

355

TypeScript utility type for getting specific event types from event names.

356

357

```typescript { .api }

358

type GetEventByEventName<TEventName> =

359

TEventName extends 'draggable:initialize'

360

? DraggableInitializedEvent

361

: TEventName extends 'drag:start'

362

? DragStartEvent

363

: TEventName extends 'sortable:sorted'

364

? SortableSortedEvent

365

: TEventName extends 'droppable:dropped'

366

? DroppableDroppedEvent

367

: TEventName extends 'swappable:swapped'

368

? SwappableSwappedEvent

369

: AbstractEvent;

370

```

371

372

**Usage Example:**

373

374

```typescript

375

// TypeScript will correctly infer the event type

376

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

377

// event is correctly typed as DragStartEvent

378

console.log(event.source, event.originalSource);

379

});

380

381

sortable.on('sortable:sorted', (event) => {

382

// event is correctly typed as SortableSortedEvent

383

console.log(event.oldIndex, event.newIndex);

384

});

385

```

386

387

## Complete Event Example

388

389

```typescript

390

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

391

392

const draggable = new Draggable(containers, options);

393

394

// Set up comprehensive event logging

395

const events = [

396

'draggable:initialize',

397

'drag:start',

398

'drag:move',

399

'drag:over',

400

'drag:out',

401

'drag:stop',

402

'drag:stopped',

403

'mirror:create',

404

'mirror:created',

405

'mirror:move',

406

'mirror:destroy'

407

];

408

409

events.forEach(eventName => {

410

draggable.on(eventName, (event) => {

411

console.log(`Event: ${eventName}`, {

412

type: event.type,

413

cancelable: event.cancelable,

414

canceled: event.canceled(),

415

timestamp: Date.now()

416

});

417

});

418

});

419

420

// Handle cancellation scenarios

421

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

422

// Cancel drag if element is disabled

423

if (event.source.hasAttribute('disabled')) {

424

event.cancel();

425

showMessage('This item cannot be moved');

426

}

427

});

428

```