@lumjs/web-draggable-list 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/index.js +159 -0
- package/jsdoc.js +6 -0
- package/lum.build.js +4 -0
- package/package.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# lum.web-draggable-list.js
|
|
2
|
+
|
|
3
|
+
A class for making lists that allow drag-and-drop reordering of items.
|
|
4
|
+
Includes the [drag-drop-touch] wrapper class for ensuring the drag-and-drop
|
|
5
|
+
features work on touch screen devices as well.
|
|
6
|
+
|
|
7
|
+
## Official URLs
|
|
8
|
+
|
|
9
|
+
This library can be found in two places:
|
|
10
|
+
|
|
11
|
+
* [Github](https://github.com/supernovus/lum.web-draggable-list.js)
|
|
12
|
+
* [NPM](https://www.npmjs.com/package/@lumjs/web-draggable-list)
|
|
13
|
+
|
|
14
|
+
## Author
|
|
15
|
+
|
|
16
|
+
Timothy Totten <2010@totten.ca>
|
|
17
|
+
|
|
18
|
+
## License
|
|
19
|
+
|
|
20
|
+
[MIT](https://spdx.org/licenses/MIT.html)
|
|
21
|
+
|
|
22
|
+
[drag-drop-touch]: https://github.com/drag-drop-touch-js/dragdroptouch
|
package/index.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { enableDragDropTouch } from '@dragdroptouch/drag-drop-touch';
|
|
2
|
+
import WC from '@lumjs/web-core';
|
|
3
|
+
|
|
4
|
+
export {WC};
|
|
5
|
+
export const { indexOf, on } = WC.ez;
|
|
6
|
+
|
|
7
|
+
const DEF_OPTS = {
|
|
8
|
+
items: '& > li',
|
|
9
|
+
onDrop() {},
|
|
10
|
+
onEnd() {},
|
|
11
|
+
onEnter() {},
|
|
12
|
+
onLeave() {},
|
|
13
|
+
onOver() {},
|
|
14
|
+
onStart() {},
|
|
15
|
+
verbose: false,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DRAG_METHODS = [
|
|
19
|
+
'handleDragStart',
|
|
20
|
+
'handleDragEnter',
|
|
21
|
+
'handleDragOver',
|
|
22
|
+
'handleDragLeave',
|
|
23
|
+
'handleDrop',
|
|
24
|
+
'handleDragEnd',
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
export class DraggableList {
|
|
28
|
+
constructor(listElem, opts) {
|
|
29
|
+
this.opts = opts = Object.assign({}, DEF_OPTS, opts);
|
|
30
|
+
if (typeof listElem === 'string') {
|
|
31
|
+
listElem = document.querySelector(listElem);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!(listElem instanceof Element)) {
|
|
35
|
+
throw new TypeError("invalid Element");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
this.listElem = listElem;
|
|
39
|
+
this.dragging = null;
|
|
40
|
+
enableDragDropTouch(listElem, listElem, opts);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get listItems() {
|
|
44
|
+
return this.listElem.querySelectorAll(this.opts.items);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
makeDraggable(enabled=true, ...elems) {
|
|
48
|
+
if (elems.length === 0) {
|
|
49
|
+
elems = this.listItems;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let verbose = this.opts.verbose;
|
|
53
|
+
|
|
54
|
+
for (let elem of elems) {
|
|
55
|
+
if (typeof elem === 'string') {
|
|
56
|
+
elem = this.listElem.querySelector(elem);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!(elem instanceof Element)) {
|
|
60
|
+
throw new TypeError("invalid Element");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
elem.setAttribute('draggable', enabled.toString());
|
|
64
|
+
|
|
65
|
+
// Doing this here as delegated events on the list element didn't work.
|
|
66
|
+
// which is kind of annoying to be honest, but everything about the
|
|
67
|
+
// drag-and-drop API is. Like having to use a middleware to make it
|
|
68
|
+
// work with touch screens, how did that get fucked up so badly?
|
|
69
|
+
|
|
70
|
+
for (let meth of DRAG_METHODS)
|
|
71
|
+
{
|
|
72
|
+
let eventName = meth.replace('handle','').toLowerCase();
|
|
73
|
+
on(elem, eventName, ev => {
|
|
74
|
+
if (verbose) {
|
|
75
|
+
console.debug({eventName, meth, event: ev, elem, list: this});
|
|
76
|
+
}
|
|
77
|
+
this[meth](ev);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
handleDragStart(ev) {
|
|
86
|
+
this.dragging = ev.target;
|
|
87
|
+
ev.dataTransfer.effectAllowed = 'move';
|
|
88
|
+
this.opts.onStart.call(this, ev);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
handleDragOver(ev) {
|
|
92
|
+
if (this.dragging) {
|
|
93
|
+
ev.preventDefault();
|
|
94
|
+
ev.dataTransfer.dropEffect = 'move';
|
|
95
|
+
this.opts.onOver.call(this, ev);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
handleDragEnter(ev) {
|
|
100
|
+
if (this.dragging) {
|
|
101
|
+
this.opts.onEnter.call(this, ev);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
handleDragLeave(ev) {
|
|
106
|
+
if (this.dragging) {
|
|
107
|
+
this.opts.onLeave.call(this, ev);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
handleDragEnd(ev) {
|
|
112
|
+
this.opts.onEnd.call(this, ev);
|
|
113
|
+
this.dragging = null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
handleDrop(ev) {
|
|
117
|
+
if (this.dragging === null) return;
|
|
118
|
+
|
|
119
|
+
ev.stopPropagation();
|
|
120
|
+
ev.stopImmediatePropagation();
|
|
121
|
+
ev.preventDefault();
|
|
122
|
+
|
|
123
|
+
let {target} = ev;
|
|
124
|
+
let dragged = this.dragging;
|
|
125
|
+
|
|
126
|
+
if (dragged !== target) {
|
|
127
|
+
let ia = indexOf(dragged);
|
|
128
|
+
let ib = indexOf(target);
|
|
129
|
+
|
|
130
|
+
if (ia > ib) {
|
|
131
|
+
target.before(dragged);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
target.after(dragged);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
Object.assign(ev, { oldpos: ia, newpos: ib });
|
|
138
|
+
|
|
139
|
+
this.opts.onDrop.call(this, ev);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export default DraggableList;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* A Drag Event handler
|
|
149
|
+
* @callback DragEventHandler
|
|
150
|
+
* @param {DragEvent} event - The event being handled.
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* A Drop Event handler.
|
|
155
|
+
* @callback DropEventHandler
|
|
156
|
+
* @param {DragEvent} event - The event being handled; with extra metadata.
|
|
157
|
+
* @param {number} event.oldpos - The original position of the dragged item.
|
|
158
|
+
* @param {number} event.newpso - The new position of the dragged item.
|
|
159
|
+
*/
|
package/jsdoc.js
ADDED
package/lum.build.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lumjs/web-draggable-list",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": "./index.js",
|
|
7
|
+
"./package.json": "./package.json"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@dragdroptouch/drag-drop-touch": "^2.0.3",
|
|
11
|
+
"@lumjs/core": "^1.38.5",
|
|
12
|
+
"@lumjs/web-core": "^1.10.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@lumjs/build": "^1.1.0"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build-meta": "lum-build",
|
|
19
|
+
"build-jsdoc": "jsdoc -c ./jsdoc.js",
|
|
20
|
+
"build-docs": "npm run build-meta && npm run build-jsdoc"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/supernovus/lum.web-draggable-list.js.git"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT"
|
|
27
|
+
}
|