Skip to content

Commit 58db0e5

Browse files
authored
Merge pull request #403 from bahung1221/feature/remove-default-plugins-sensors
Add `exclude` field to Draggable options to allow disable default plugins and sensors
2 parents e6fa782 + 2931209 commit 58db0e5

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)