Skip to content

Commit 2931209

Browse files
committed
Add exclude field to Draggable options to allow disable default plugins and sensors
Remove duplicated code Refactor to more readable Change 'toBe' to 'toEqual' for compare value only
1 parent e6fa782 commit 2931209

File tree

4 files changed

+73
-3
lines changed

4 files changed

+73
-3
lines changed

src/Draggable/Draggable.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export const defaultOptions = {
5252
placedTimeout: 800,
5353
plugins: [],
5454
sensors: [],
55+
exclude: {
56+
plugins: [],
57+
sensors: [],
58+
},
5559
};
5660

5761
/**
@@ -72,6 +76,16 @@ export default class Draggable {
7276
*/
7377
static Plugins = {Announcement, Focusable, Mirror, Scrollable};
7478

79+
/**
80+
* Default sensors draggable uses
81+
* @static
82+
* @property {Object} Sensors
83+
* @property {MouseSensor} Sensors.MouseSensor
84+
* @property {TouchSensor} Sensors.TouchSensor
85+
* @type {Object}
86+
*/
87+
static Sensors = {MouseSensor, TouchSensor};
88+
7589
/**
7690
* Draggable constructor.
7791
* @constructs Draggable
@@ -103,6 +117,10 @@ export default class Draggable {
103117
...defaultAnnouncements,
104118
...(options.announcements || {}),
105119
},
120+
exclude: {
121+
plugins: (options.exclude && options.exclude.plugins) || [],
122+
sensors: (options.exclude && options.exclude.sensors) || [],
123+
},
106124
};
107125

108126
/**
@@ -143,8 +161,12 @@ export default class Draggable {
143161
document.addEventListener('drag:stop', this[onDragStop], true);
144162
document.addEventListener('drag:pressure', this[onDragPressure], true);
145163

146-
const defaultPlugins = Object.values(Draggable.Plugins).map((Plugin) => Plugin);
147-
const defaultSensors = [MouseSensor, TouchSensor];
164+
const defaultPlugins = Object.values(Draggable.Plugins).filter(
165+
(Plugin) => !this.options.exclude.plugins.includes(Plugin),
166+
);
167+
const defaultSensors = Object.values(Draggable.Sensors).filter(
168+
(sensor) => !this.options.exclude.sensors.includes(sensor),
169+
);
148170

149171
this.addPlugin(...[...defaultPlugins, ...this.options.plugins]);
150172
this.addSensor(...[...defaultSensors, ...this.options.sensors]);

src/Draggable/Plugins/Focusable/Focusable.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ export default class Focusable extends AbstractPlugin {
5151
*/
5252
detach() {
5353
this.draggable.off('draggable:initialize', this[onInitialize]).off('draggable:destroy', this[onDestroy]);
54+
55+
// Remove modified elements when detach
56+
this[onDestroy]();
5457
}
5558

5659
/**

src/Draggable/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ By default draggable includes the `MouseSensor` & `TouchSensor`. Default: `[]`
9696
Draggable adds classes to elements to indicate state. These classes can be used to add styling
9797
on elements in certain states.
9898

99+
**`exclude {plugins: Plugin[], sensors: Sensor[]}`**
100+
Allow excluding default plugins and default sensors. Use with caution as it may create strange behavior.
101+
99102
### Events
100103

101104
| Name | Description | Cancelable | Cancelable action |
@@ -151,3 +154,17 @@ draggable.on('drag:start', () => console.log('drag:start'));
151154
draggable.on('drag:move', () => console.log('drag:move'));
152155
draggable.on('drag:stop', () => console.log('drag:stop'));
153156
```
157+
158+
Create draggable which excluded some default plugins and sensor:
159+
160+
```js
161+
import { Draggable } from '@shopify/draggable';
162+
163+
const draggable = new Draggable(document.querySelectorAll('ul'), {
164+
draggable: 'li',
165+
exclude: {
166+
plugins: [Draggable.Plugins.Focusable],
167+
sensors: [Draggable.Sensors.TouchSensor],
168+
}
169+
});
170+
```

src/Draggable/tests/Draggable.test.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ describe('Draggable', () => {
6464

6565
for (const key in defaultOptions) {
6666
if (defaultOptions.hasOwnProperty(key)) {
67-
expect(newInstance.options[key]).toBe(defaultOptions[key]);
67+
expect(newInstance.options[key]).toEqual(defaultOptions[key]);
6868
}
6969
}
7070
});
@@ -105,6 +105,20 @@ describe('Draggable', () => {
105105
expect(newInstance.plugins[3]).toBeInstanceOf(Scrollable);
106106
});
107107

108+
it('should remove default plugins from the list of exclude plugins', () => {
109+
const newInstance = new Draggable([], {
110+
exclude: {
111+
plugins: [Draggable.Plugins.Focusable],
112+
},
113+
});
114+
115+
expect(newInstance.plugins).toHaveLength(3);
116+
117+
newInstance.plugins.forEach((plugin) => {
118+
expect(plugin).not.toBeInstanceOf(Focusable);
119+
});
120+
});
121+
108122
it('should attach custom plugins', () => {
109123
const newInstance = new Draggable([], {
110124
plugins: [TestPlugin],
@@ -133,6 +147,20 @@ describe('Draggable', () => {
133147
expect(newInstance.sensors[1]).toBeInstanceOf(TouchSensor);
134148
});
135149

150+
it('should remove default sensors from the list of exclude sensors', () => {
151+
const newInstance = new Draggable([], {
152+
exclude: {
153+
sensors: [Draggable.Sensors.TouchSensor],
154+
},
155+
});
156+
157+
expect(newInstance.sensors).toHaveLength(1);
158+
159+
newInstance.sensors.forEach((sensor) => {
160+
expect(sensor).not.toBeInstanceOf(TouchSensor);
161+
});
162+
});
163+
136164
it('should trigger DraggableInitializedEvent on init', () => {
137165
const spy = jest.spyOn(Draggable.prototype, 'trigger');
138166
const newInstance = new Draggable();

0 commit comments

Comments
 (0)