Skip to content

Commit 689c45a

Browse files
zachahnbahung1221
authored andcommitted
Allow specifying an array of classNames
In order to prevent breaking changes, this adds a new method `getClassNamesFor` while keeping the existing behavior of `getClassNameFor` (the former returns an array, and the latter returns the first item of the array). There's one caveat when using this feature though. Since `classList.contains` only accepts a single class, it's somewhat important that the first class of each DraggableClassNames is unique.
1 parent 81c697c commit 689c45a

File tree

5 files changed

+58
-37
lines changed

5 files changed

+58
-37
lines changed

index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ declare module '@shopify/draggable' {
176176
delay?: number | DelayOptions;
177177
plugins?: Array<typeof AbstractPlugin>;
178178
sensors?: Sensor[];
179-
classes?: { [key in DraggableClassNames]: string };
179+
classes?: { [key in DraggableClassNames]: string | string[] };
180180
announcements?: AnnouncementOptions;
181181
collidables?: Collidables;
182182
mirror?: MirrorOptions;
@@ -204,6 +204,7 @@ declare module '@shopify/draggable' {
204204
addContainer(...containers: HTMLElement[]): this;
205205
removeContainer(...containers: HTMLElement[]): this;
206206
getClassNameFor(name: DraggableClassNames): string;
207+
getClassNamesFor(name: DraggableClassNames): string[];
207208
isDragging(): boolean;
208209
getDraggableElementsForContainer(container: HTMLElement): HTMLElement[];
209210
}

src/Draggable/Draggable.js

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,23 @@ export default class Draggable {
329329
* @return {String|null}
330330
*/
331331
getClassNameFor(name) {
332-
return this.options.classes[name];
332+
return this.getClassNamesFor(name)[0];
333+
}
334+
335+
/**
336+
* Returns class names for class identifier
337+
* @return {String[]}
338+
*/
339+
getClassNamesFor(name) {
340+
const classNames = this.options.classes[name];
341+
342+
if (classNames instanceof Array) {
343+
return classNames;
344+
} else if (typeof classNames === 'string' || classNames instanceof String) {
345+
return [classNames];
346+
} else {
347+
return [];
348+
}
333349
}
334350

335351
/**
@@ -393,8 +409,8 @@ export default class Draggable {
393409

394410
if (this.lastPlacedSource && this.lastPlacedContainer) {
395411
clearTimeout(this.placedTimeoutID);
396-
this.lastPlacedSource.classList.remove(this.getClassNameFor('source:placed'));
397-
this.lastPlacedContainer.classList.remove(this.getClassNameFor('container:placed'));
412+
this.lastPlacedSource.classList.remove(...this.getClassNamesFor('source:placed'));
413+
this.lastPlacedContainer.classList.remove(...this.getClassNamesFor('container:placed'));
398414
}
399415

400416
this.source = this.originalSource.cloneNode(true);
@@ -418,10 +434,10 @@ export default class Draggable {
418434
return;
419435
}
420436

421-
this.originalSource.classList.add(this.getClassNameFor('source:original'));
422-
this.source.classList.add(this.getClassNameFor('source:dragging'));
423-
this.sourceContainer.classList.add(this.getClassNameFor('container:dragging'));
424-
document.body.classList.add(this.getClassNameFor('body:dragging'));
437+
this.originalSource.classList.add(...this.getClassNamesFor('source:original'));
438+
this.source.classList.add(...this.getClassNamesFor('source:dragging'));
439+
this.sourceContainer.classList.add(...this.getClassNamesFor('container:dragging'));
440+
document.body.classList.add(...this.getClassNamesFor('body:dragging'));
425441
applyUserSelect(document.body, 'none');
426442

427443
requestAnimationFrame(() => {
@@ -479,7 +495,7 @@ export default class Draggable {
479495
over: this.currentOver,
480496
});
481497

482-
this.currentOver.classList.remove(this.getClassNameFor('draggable:over'));
498+
this.currentOver.classList.remove(...this.getClassNamesFor('draggable:over'));
483499
this.currentOver = null;
484500

485501
this.trigger(dragOutEvent);
@@ -494,14 +510,14 @@ export default class Draggable {
494510
overContainer: this.currentOverContainer,
495511
});
496512

497-
this.currentOverContainer.classList.remove(this.getClassNameFor('container:over'));
513+
this.currentOverContainer.classList.remove(...this.getClassNamesFor('container:over'));
498514
this.currentOverContainer = null;
499515

500516
this.trigger(dragOutContainerEvent);
501517
}
502518

503519
if (isOverContainer) {
504-
overContainer.classList.add(this.getClassNameFor('container:over'));
520+
overContainer.classList.add(...this.getClassNamesFor('container:over'));
505521

506522
const dragOverContainerEvent = new DragOverContainerEvent({
507523
source: this.source,
@@ -517,7 +533,7 @@ export default class Draggable {
517533
}
518534

519535
if (isOverDraggable) {
520-
target.classList.add(this.getClassNameFor('draggable:over'));
536+
target.classList.add(...this.getClassNamesFor('draggable:over'));
521537

522538
const dragOverEvent = new DragOverEvent({
523539
source: this.source,
@@ -559,32 +575,32 @@ export default class Draggable {
559575
this.source.parentNode.removeChild(this.source);
560576
this.originalSource.style.display = '';
561577

562-
this.source.classList.remove(this.getClassNameFor('source:dragging'));
563-
this.originalSource.classList.remove(this.getClassNameFor('source:original'));
564-
this.originalSource.classList.add(this.getClassNameFor('source:placed'));
565-
this.sourceContainer.classList.add(this.getClassNameFor('container:placed'));
566-
this.sourceContainer.classList.remove(this.getClassNameFor('container:dragging'));
567-
document.body.classList.remove(this.getClassNameFor('body:dragging'));
578+
this.source.classList.remove(...this.getClassNamesFor('source:dragging'));
579+
this.originalSource.classList.remove(...this.getClassNamesFor('source:original'));
580+
this.originalSource.classList.add(...this.getClassNamesFor('source:placed'));
581+
this.sourceContainer.classList.add(...this.getClassNamesFor('container:placed'));
582+
this.sourceContainer.classList.remove(...this.getClassNamesFor('container:dragging'));
583+
document.body.classList.remove(...this.getClassNamesFor('body:dragging'));
568584
applyUserSelect(document.body, '');
569585

570586
if (this.currentOver) {
571-
this.currentOver.classList.remove(this.getClassNameFor('draggable:over'));
587+
this.currentOver.classList.remove(...this.getClassNamesFor('draggable:over'));
572588
}
573589

574590
if (this.currentOverContainer) {
575-
this.currentOverContainer.classList.remove(this.getClassNameFor('container:over'));
591+
this.currentOverContainer.classList.remove(...this.getClassNamesFor('container:over'));
576592
}
577593

578594
this.lastPlacedSource = this.originalSource;
579595
this.lastPlacedContainer = this.sourceContainer;
580596

581597
this.placedTimeoutID = setTimeout(() => {
582598
if (this.lastPlacedSource) {
583-
this.lastPlacedSource.classList.remove(this.getClassNameFor('source:placed'));
599+
this.lastPlacedSource.classList.remove(...this.getClassNamesFor('source:placed'));
584600
}
585601

586602
if (this.lastPlacedContainer) {
587-
this.lastPlacedContainer.classList.remove(this.getClassNameFor('container:placed'));
603+
this.lastPlacedContainer.classList.remove(...this.getClassNamesFor('container:placed'));
588604
}
589605

590606
this.lastPlacedSource = null;

src/Draggable/Plugins/Mirror/Mirror.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ export default class Mirror extends AbstractPlugin {
275275
* @private
276276
*/
277277
[onMirrorCreated]({mirror, source, sensorEvent}) {
278-
const mirrorClass = this.draggable.getClassNameFor('mirror');
278+
const mirrorClass = this.draggable.getClassNamesFor('mirror');
279279

280280
const setState = ({mirrorOffset, initialX, initialY, ...args}) => {
281281
this.mirrorOffset = mirrorOffset;
@@ -446,13 +446,17 @@ function resetMirror({mirror, source, options, ...args}) {
446446
* Applys mirror class on mirror element
447447
* @param {Object} state
448448
* @param {HTMLElement} state.mirror
449-
* @param {String} state.mirrorClass
449+
* @param {String|String[]} state.mirrorClass
450450
* @return {Promise}
451451
* @private
452452
*/
453453
function addMirrorClasses({mirror, mirrorClass, ...args}) {
454454
return withPromise((resolve) => {
455-
mirror.classList.add(mirrorClass);
455+
if (mirrorClass instanceof Array) {
456+
mirror.classList.add(...mirrorClass);
457+
} else {
458+
mirror.classList.add(mirrorClass);
459+
}
456460
resolve({mirror, mirrorClass, ...args});
457461
});
458462
}

src/Droppable/Droppable.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export default class Droppable extends Draggable {
160160
continue;
161161
}
162162

163-
dropzoneElement.classList.add(this.getClassNameFor('droppable:active'));
163+
dropzoneElement.classList.add(...this.getClassNamesFor('droppable:active'));
164164
}
165165
}
166166

@@ -198,14 +198,14 @@ export default class Droppable extends Draggable {
198198

199199
this.trigger(droppableStopEvent);
200200

201-
const occupiedClass = this.getClassNameFor('droppable:occupied');
201+
const occupiedClasses = this.getClassNamesFor('droppable:occupied');
202202

203203
for (const dropzone of this.dropzones) {
204-
dropzone.classList.remove(this.getClassNameFor('droppable:active'));
204+
dropzone.classList.remove(...this.getClassNamesFor('droppable:active'));
205205
}
206206

207207
if (this.lastDropzone && this.lastDropzone !== this.initialDropzone) {
208-
this.initialDropzone.classList.remove(occupiedClass);
208+
this.initialDropzone.classList.remove(...occupiedClasses);
209209
}
210210

211211
this.dropzones = null;
@@ -231,14 +231,14 @@ export default class Droppable extends Draggable {
231231
return false;
232232
}
233233

234-
const occupiedClass = this.getClassNameFor('droppable:occupied');
234+
const occupiedClasses = this.getClassNamesFor('droppable:occupied');
235235

236236
if (this.lastDropzone) {
237-
this.lastDropzone.classList.remove(occupiedClass);
237+
this.lastDropzone.classList.remove(...occupiedClasses);
238238
}
239239

240240
dropzone.appendChild(event.source);
241-
dropzone.classList.add(occupiedClass);
241+
dropzone.classList.add(...occupiedClasses);
242242

243243
return true;
244244
}
@@ -261,7 +261,7 @@ export default class Droppable extends Draggable {
261261
}
262262

263263
this.initialDropzone.appendChild(event.source);
264-
this.lastDropzone.classList.remove(this.getClassNameFor('droppable:occupied'));
264+
this.lastDropzone.classList.remove(...this.getClassNamesFor('droppable:occupied'));
265265
}
266266

267267
/**

src/Plugins/Snappable/Snappable.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,12 @@ export default class Snappable extends AbstractPlugin {
127127
this.mirror.style.display = 'none';
128128
}
129129

130-
source.classList.remove(this.draggable.getClassNameFor('source:dragging'));
131-
source.classList.add(this.draggable.getClassNameFor('source:placed'));
130+
source.classList.remove(...this.draggable.getClassNamesFor('source:dragging'));
131+
source.classList.add(...this.draggable.getClassNamesFor('source:placed'));
132132

133133
// Need to cancel this in drag out
134134
setTimeout(() => {
135-
source.classList.remove(this.draggable.getClassNameFor('source:placed'));
135+
source.classList.remove(...this.draggable.getClassNamesFor('source:placed'));
136136
}, this.draggable.options.placedTimeout);
137137
}
138138

@@ -163,7 +163,7 @@ export default class Snappable extends AbstractPlugin {
163163
this.mirror.style.display = '';
164164
}
165165

166-
source.classList.add(this.draggable.getClassNameFor('source:dragging'));
166+
source.classList.add(...this.draggable.getClassNamesFor('source:dragging'));
167167
}
168168

169169
/**

0 commit comments

Comments
 (0)