nodeskini 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 +31 -0
- package/client/archive/bundle.js +11528 -0
- package/client/archive/golem.html +60 -0
- package/client/archive/golemClient.js +595 -0
- package/client/archive/golembundle.js +11634 -0
- package/client/archive/sequencer.html +43 -0
- package/client/archive/sequenceurClient.js +815 -0
- package/client/archive/stylegolem.css +158 -0
- package/client/archive/stylesequenceur.css +204 -0
- package/client/clientListe/Sortable-master/.circleci/config.yml +33 -0
- package/client/clientListe/Sortable-master/.editorconfig +15 -0
- package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/bug-report.md +73 -0
- package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/custom-template.md +48 -0
- package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/feature-request.md +41 -0
- package/client/clientListe/Sortable-master/.jshintrc +25 -0
- package/client/clientListe/Sortable-master/.testcaferc.json +7 -0
- package/client/clientListe/Sortable-master/CONTRIBUTING.md +26 -0
- package/client/clientListe/Sortable-master/LICENSE +21 -0
- package/client/clientListe/Sortable-master/README.md +813 -0
- package/client/clientListe/Sortable-master/Sortable.js +3709 -0
- package/client/clientListe/Sortable-master/Sortable.min.js +2 -0
- package/client/clientListe/Sortable-master/Sortable.min.old.js +2 -0
- package/client/clientListe/Sortable-master/Sortable.min.old.old.js +2 -0
- package/client/clientListe/Sortable-master/babel.config.js +27 -0
- package/client/clientListe/Sortable-master/bower.json +30 -0
- package/client/clientListe/Sortable-master/entry/entry-complete.js +8 -0
- package/client/clientListe/Sortable-master/entry/entry-core.js +19 -0
- package/client/clientListe/Sortable-master/entry/entry-defaults.js +19 -0
- package/client/clientListe/Sortable-master/index.html +460 -0
- package/client/clientListe/Sortable-master/modular/sortable.complete.esm.js +3701 -0
- package/client/clientListe/Sortable-master/modular/sortable.core.esm.js +3698 -0
- package/client/clientListe/Sortable-master/modular/sortable.esm.js +3699 -0
- package/client/clientListe/Sortable-master/package-lock.json +5704 -0
- package/client/clientListe/Sortable-master/package.json +56 -0
- package/client/clientListe/Sortable-master/plugins/AutoScroll/AutoScroll.js +270 -0
- package/client/clientListe/Sortable-master/plugins/AutoScroll/README.md +80 -0
- package/client/clientListe/Sortable-master/plugins/AutoScroll/index.js +1 -0
- package/client/clientListe/Sortable-master/plugins/MultiDrag/MultiDrag.js +617 -0
- package/client/clientListe/Sortable-master/plugins/MultiDrag/README.md +96 -0
- package/client/clientListe/Sortable-master/plugins/MultiDrag/index.js +1 -0
- package/client/clientListe/Sortable-master/plugins/OnSpill/OnSpill.js +79 -0
- package/client/clientListe/Sortable-master/plugins/OnSpill/README.md +60 -0
- package/client/clientListe/Sortable-master/plugins/OnSpill/index.js +1 -0
- package/client/clientListe/Sortable-master/plugins/README.md +178 -0
- package/client/clientListe/Sortable-master/plugins/Swap/README.md +55 -0
- package/client/clientListe/Sortable-master/plugins/Swap/Swap.js +90 -0
- package/client/clientListe/Sortable-master/plugins/Swap/index.js +1 -0
- package/client/clientListe/Sortable-master/scripts/banner.js +8 -0
- package/client/clientListe/Sortable-master/scripts/build.js +17 -0
- package/client/clientListe/Sortable-master/scripts/esm-build.js +28 -0
- package/client/clientListe/Sortable-master/scripts/minify.js +11 -0
- package/client/clientListe/Sortable-master/scripts/test-compat.js +30 -0
- package/client/clientListe/Sortable-master/scripts/test.js +21 -0
- package/client/clientListe/Sortable-master/scripts/umd-build.js +15 -0
- package/client/clientListe/Sortable-master/src/Animation.js +175 -0
- package/client/clientListe/Sortable-master/src/BrowserInfo.js +12 -0
- package/client/clientListe/Sortable-master/src/EventDispatcher.js +57 -0
- package/client/clientListe/Sortable-master/src/PluginManager.js +87 -0
- package/client/clientListe/Sortable-master/src/Sortable.js +1971 -0
- package/client/clientListe/Sortable-master/src/utils.js +556 -0
- package/client/clientListe/Sortable-master/st/app.js +224 -0
- package/client/clientListe/Sortable-master/st/iframe/frame.html +32 -0
- package/client/clientListe/Sortable-master/st/iframe/index.html +49 -0
- package/client/clientListe/Sortable-master/st/logo.png +0 -0
- package/client/clientListe/Sortable-master/st/og-image.png +0 -0
- package/client/clientListe/Sortable-master/st/prettify/prettify.css +1 -0
- package/client/clientListe/Sortable-master/st/prettify/prettify.js +46 -0
- package/client/clientListe/Sortable-master/st/prettify/run_prettify.js +64 -0
- package/client/clientListe/Sortable-master/st/saucelabs.svg +1 -0
- package/client/clientListe/Sortable-master/st/theme.css +254 -0
- package/client/clientListe/Sortable-master/tests/Sortable.compat.test.js +39 -0
- package/client/clientListe/Sortable-master/tests/Sortable.test.js +386 -0
- package/client/clientListe/Sortable-master/tests/dual-list.html +34 -0
- package/client/clientListe/Sortable-master/tests/empty-list.html +30 -0
- package/client/clientListe/Sortable-master/tests/filter.html +27 -0
- package/client/clientListe/Sortable-master/tests/handles.html +27 -0
- package/client/clientListe/Sortable-master/tests/nested.html +67 -0
- package/client/clientListe/Sortable-master/tests/single-list.html +25 -0
- package/client/clientListe/Sortable-master/tests/style.css +18 -0
- package/client/clientListe/clientListe.html +148 -0
- package/client/clientListe/clientListe.js +1508 -0
- package/client/clientListe/clientListebundle.js +13164 -0
- package/client/clientListe/images/poubelle.png +0 -0
- package/client/clientListe/images/start.png +0 -0
- package/client/clientListe/images/stop.png +0 -0
- package/client/clientListe/images/submit.png +0 -0
- package/client/clientListe/sortable-theme-bootstrap.css +90 -0
- package/client/configurateur/configReact.js +273 -0
- package/client/configurateur/configReactbundle.js +295 -0
- package/client/configurateur/configurateur.css +95 -0
- package/client/configurateur/configurateur.html +48 -0
- package/client/configurateur/lib/jexcel.css +755 -0
- package/client/configurateur/lib/jexcel.js +14970 -0
- package/client/configurateur/lib/jsuites.css +2801 -0
- package/client/configurateur/lib/jsuites.js +11822 -0
- package/client/configurateur/lib/react-dom.production.min.js +239 -0
- package/client/configurateur/lib/react.production.min.js +32 -0
- package/client/configurateur/src/configReact.js +247 -0
- package/client/controleur/clientcontroleur.js +536 -0
- package/client/controleur/clientcontroleur.test.js +282 -0
- package/client/controleur/controleur.html +51 -0
- package/client/controleur/controleurbundle.js +565 -0
- package/client/controleur/stylecontroleur.css +236 -0
- package/client/controleurHH/controleurHH.html +71 -0
- package/client/controleurHH/controleurHH.js +252 -0
- package/client/controleurHH/styles/index.css +320 -0
- package/client/controleurHH/styles/material.css +11552 -0
- package/client/parametrage/paramReact.js +473 -0
- package/client/parametrage/paramReactbundle.js +500 -0
- package/client/parametrage/parametrage.css +111 -0
- package/client/parametrage/parametrage.html +163 -0
- package/client/parametrage/src/paramReact.js +459 -0
- package/client/score/hash.js +83 -0
- package/client/score/p5.min.js +3 -0
- package/client/score/parto1.js +1171 -0
- package/client/score/parto1bundle.js +1181 -0
- package/client/score/processing.min.js +431 -0
- package/client/score/score.html +15 -0
- package/client/score/score.js +34 -0
- package/client/simulateurListe/simulateurFork.js +750 -0
- package/client/simulateurListe/simulateurFork.mjs +681 -0
- package/client/simulateurListe/simulateurForkSansReorg.js +569 -0
- package/client/simulateurListe/simulateurListe.js +628 -0
- package/myReact/archive/Nodeemitvaluedlocal1.hh.js +52 -0
- package/myReact/archive/abort-parNode.js +79 -0
- package/myReact/archive/abroNode.js +169 -0
- package/myReact/archive/abroNode2.js +80 -0
- package/myReact/archive/atom.compile.hh.js +51 -0
- package/myReact/archive/await-countNode.js +67 -0
- package/myReact/archive/await-nowvalNode.js +44 -0
- package/myReact/archive/callHH.js +96 -0
- package/myReact/archive/emit-if2.hh.compiled.js +113 -0
- package/myReact/archive/every1Node.js +35 -0
- package/myReact/archive/if-runNode.js +74 -0
- package/myReact/archive/if1Node.js +43 -0
- package/myReact/archive/makeawait.js +0 -0
- package/myReact/archive/myReact.old.js +684 -0
- package/myReact/archive/orchestration.js +281 -0
- package/myReact/archive/orchestration1.js +132 -0
- package/myReact/archive/orchestration1.xml +465 -0
- package/myReact/archive/orchestration2.js +161 -0
- package/myReact/archive/orchestrationHH.mano.js +280 -0
- package/myReact/archive/orchestrationHHTest.js +428 -0
- package/myReact/archive/orchestrationHHTest.xml +234 -0
- package/myReact/archive/orchestrationHHTestRun.js +104 -0
- package/myReact/archive/orchestrationHHTestRun.xml +34 -0
- package/myReact/archive/orchestrationTest0.js +178 -0
- package/myReact/archive/orchestrationTest1.js +181 -0
- package/myReact/archive/orchestrationTest2.js +281 -0
- package/myReact/archive/run3pointsNode.js +59 -0
- package/myReact/archive/runNode.js +123 -0
- package/myReact/archive/runNode2.js +91 -0
- package/myReact/archive/testAwait1.js +141 -0
- package/myReact/archive/testAwait1.xml +86 -0
- package/myReact/archive/testEvery1.js +122 -0
- package/myReact/archive/testEvery1.xml +79 -0
- package/myReact/archive/testHH1.js +135 -0
- package/myReact/archive/testHH1.xml +86 -0
- package/myReact/archive/testHH1revu.js +104 -0
- package/myReact/archive/testHH2.js +122 -0
- package/myReact/archive/testHH2.xml +79 -0
- package/myReact/archive/testHH3.js +130 -0
- package/myReact/archive/testHH3.xml +86 -0
- package/myReact/archive/testHHabort.js +121 -0
- package/myReact/archive/testHHabort.xml +83 -0
- package/myReact/archive/testMakeawait.js +202 -0
- package/myReact/archive/testRun1.js +168 -0
- package/myReact/archive/testRun1.xml +142 -0
- package/myReact/archive/titi.js +28 -0
- package/myReact/archive/titi.xml +110 -0
- package/myReact/archive/toto.js +73 -0
- package/myReact/archive/toto.xml +198 -0
- package/myReact/archive/trap-await-parallelNode.js +123 -0
- package/myReact/inutiles/hiver2022.xml +804 -0
- package/myReact/inutiles/hopeNode.xml +459 -0
- package/myReact/inutiles/mars2022.xml +871 -0
- package/myReact/inutiles/mystique1.xml +318 -0
- package/myReact/inutiles/mystiqueOSC.xml +277 -0
- package/myReact/inutiles/opus5Node.xml +1271 -0
- package/myReact/inutiles/opus5NodeLinux.xml +1241 -0
- package/myReact/inutiles/orchestrationHH.xml +541 -0
- package/myReact/inutiles/orchestrationHH2.xml +547 -0
- package/myReact/inutiles/testHH.xml +95 -0
- package/myReact/inutiles/trouveLaPercuTenor.xml +349 -0
- package/myReact/myReact.js +744 -0
- package/myReact/myReact.min.js +1 -0
- package/myReact/orchestrationHH.js +311 -0
- package/myReact/orchestrationHH.mjs +436 -0
- package/myReact/orchestrationHH.mjs.map +1 -0
- package/package.json +46 -0
- package/serveur/OSCandMidi.mjs +361 -0
- package/serveur/computeScore.mjs +415 -0
- package/serveur/controleDAW.mjs +1149 -0
- package/serveur/defaultSession.csv +2 -0
- package/serveur/defaultSkiniParametres.js +119 -0
- package/serveur/gameOSC.mjs +96 -0
- package/serveur/groupeClientsSons.mjs +1014 -0
- package/serveur/ipConfig.json +24 -0
- package/serveur/ipConfig127.json +19 -0
- package/serveur/ipConfig75.json +17 -0
- package/serveur/ipConfigBH.json +19 -0
- package/serveur/ipConfigLocal.json +19 -0
- package/serveur/midiConfig.json +26 -0
- package/serveur/midiConfigBH.json +26 -0
- package/serveur/midiConfigVoid.json +3 -0
- package/serveur/midimix.mjs +570 -0
- package/serveur/saveParam.mjs +159 -0
- package/serveur/skiniParametres.good.js +132 -0
- package/serveur/skiniParametres.js +106 -0
- package/serveur/utilsHHSkini.hh.js +64 -0
- package/serveur/utilsSkini.mjs +137 -0
- package/serveur/websocketServer.mjs +2052 -0
- package/serveur/workerInterfaceZ.mjs +327 -0
- package/serveur/workerSynchro.mjs +49 -0
- package/skini.mjs +141 -0
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
import {
|
|
2
|
+
toggleClass,
|
|
3
|
+
getRect,
|
|
4
|
+
index,
|
|
5
|
+
closest,
|
|
6
|
+
on,
|
|
7
|
+
off,
|
|
8
|
+
clone,
|
|
9
|
+
css,
|
|
10
|
+
setRect,
|
|
11
|
+
unsetRect,
|
|
12
|
+
matrix,
|
|
13
|
+
expando
|
|
14
|
+
} from '../../src/utils.js';
|
|
15
|
+
|
|
16
|
+
import dispatchEvent from '../../src/EventDispatcher.js';
|
|
17
|
+
|
|
18
|
+
let multiDragElements = [],
|
|
19
|
+
multiDragClones = [],
|
|
20
|
+
lastMultiDragSelect, // for selection with modifier key down (SHIFT)
|
|
21
|
+
multiDragSortable,
|
|
22
|
+
initialFolding = false, // Initial multi-drag fold when drag started
|
|
23
|
+
folding = false, // Folding any other time
|
|
24
|
+
dragStarted = false,
|
|
25
|
+
dragEl,
|
|
26
|
+
clonesFromRect,
|
|
27
|
+
clonesHidden;
|
|
28
|
+
|
|
29
|
+
function MultiDragPlugin() {
|
|
30
|
+
function MultiDrag(sortable) {
|
|
31
|
+
// Bind all private methods
|
|
32
|
+
for (let fn in this) {
|
|
33
|
+
if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
|
|
34
|
+
this[fn] = this[fn].bind(this);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (sortable.options.supportPointer) {
|
|
39
|
+
on(document, 'pointerup', this._deselectMultiDrag);
|
|
40
|
+
} else {
|
|
41
|
+
on(document, 'mouseup', this._deselectMultiDrag);
|
|
42
|
+
on(document, 'touchend', this._deselectMultiDrag);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
on(document, 'keydown', this._checkKeyDown);
|
|
46
|
+
on(document, 'keyup', this._checkKeyUp);
|
|
47
|
+
|
|
48
|
+
this.defaults = {
|
|
49
|
+
selectedClass: 'sortable-selected',
|
|
50
|
+
multiDragKey: null,
|
|
51
|
+
setData(dataTransfer, dragEl) {
|
|
52
|
+
let data = '';
|
|
53
|
+
if (multiDragElements.length && multiDragSortable === sortable) {
|
|
54
|
+
multiDragElements.forEach((multiDragElement, i) => {
|
|
55
|
+
data += (!i ? '' : ', ') + multiDragElement.textContent;
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
data = dragEl.textContent;
|
|
59
|
+
}
|
|
60
|
+
dataTransfer.setData('Text', data);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
MultiDrag.prototype = {
|
|
66
|
+
multiDragKeyDown: false,
|
|
67
|
+
isMultiDrag: false,
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
delayStartGlobal({ dragEl: dragged }) {
|
|
71
|
+
dragEl = dragged;
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
delayEnded() {
|
|
75
|
+
this.isMultiDrag = ~multiDragElements.indexOf(dragEl);
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
setupClone({ sortable, cancel }) {
|
|
79
|
+
if (!this.isMultiDrag) return;
|
|
80
|
+
for (let i = 0; i < multiDragElements.length; i++) {
|
|
81
|
+
multiDragClones.push(clone(multiDragElements[i]));
|
|
82
|
+
|
|
83
|
+
multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
|
|
84
|
+
|
|
85
|
+
multiDragClones[i].draggable = false;
|
|
86
|
+
multiDragClones[i].style['will-change'] = '';
|
|
87
|
+
|
|
88
|
+
toggleClass(multiDragClones[i], this.options.selectedClass, false);
|
|
89
|
+
multiDragElements[i] === dragEl && toggleClass(multiDragClones[i], this.options.chosenClass, false);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
sortable._hideClone();
|
|
93
|
+
cancel();
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
clone({ sortable, rootEl, dispatchSortableEvent, cancel }) {
|
|
97
|
+
if (!this.isMultiDrag) return;
|
|
98
|
+
if (!this.options.removeCloneOnHide) {
|
|
99
|
+
if (multiDragElements.length && multiDragSortable === sortable) {
|
|
100
|
+
insertMultiDragClones(true, rootEl);
|
|
101
|
+
dispatchSortableEvent('clone');
|
|
102
|
+
|
|
103
|
+
cancel();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
showClone({ cloneNowShown, rootEl, cancel }) {
|
|
109
|
+
if (!this.isMultiDrag) return;
|
|
110
|
+
insertMultiDragClones(false, rootEl);
|
|
111
|
+
multiDragClones.forEach(clone => {
|
|
112
|
+
css(clone, 'display', '');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
cloneNowShown();
|
|
116
|
+
clonesHidden = false;
|
|
117
|
+
cancel();
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
hideClone({ sortable, cloneNowHidden, cancel }) {
|
|
121
|
+
if (!this.isMultiDrag) return;
|
|
122
|
+
multiDragClones.forEach(clone => {
|
|
123
|
+
css(clone, 'display', 'none');
|
|
124
|
+
if (this.options.removeCloneOnHide && clone.parentNode) {
|
|
125
|
+
clone.parentNode.removeChild(clone);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
cloneNowHidden();
|
|
130
|
+
clonesHidden = true;
|
|
131
|
+
cancel();
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
dragStartGlobal({ sortable }) {
|
|
135
|
+
if (!this.isMultiDrag && multiDragSortable) {
|
|
136
|
+
multiDragSortable.multiDrag._deselectMultiDrag();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
multiDragElements.forEach(multiDragElement => {
|
|
140
|
+
multiDragElement.sortableIndex = index(multiDragElement);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Sort multi-drag elements
|
|
144
|
+
multiDragElements = multiDragElements.sort(function(a, b) {
|
|
145
|
+
return a.sortableIndex - b.sortableIndex;
|
|
146
|
+
});
|
|
147
|
+
dragStarted = true;
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
dragStarted({ sortable }) {
|
|
151
|
+
if (!this.isMultiDrag) return;
|
|
152
|
+
if (this.options.sort) {
|
|
153
|
+
// Capture rects,
|
|
154
|
+
// hide multi drag elements (by positioning them absolute),
|
|
155
|
+
// set multi drag elements rects to dragRect,
|
|
156
|
+
// show multi drag elements,
|
|
157
|
+
// animate to rects,
|
|
158
|
+
// unset rects & remove from DOM
|
|
159
|
+
|
|
160
|
+
sortable.captureAnimationState();
|
|
161
|
+
|
|
162
|
+
if (this.options.animation) {
|
|
163
|
+
multiDragElements.forEach(multiDragElement => {
|
|
164
|
+
if (multiDragElement === dragEl) return;
|
|
165
|
+
css(multiDragElement, 'position', 'absolute');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
let dragRect = getRect(dragEl, false, true, true);
|
|
169
|
+
|
|
170
|
+
multiDragElements.forEach(multiDragElement => {
|
|
171
|
+
if (multiDragElement === dragEl) return;
|
|
172
|
+
setRect(multiDragElement, dragRect);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
folding = true;
|
|
176
|
+
initialFolding = true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
sortable.animateAll(() => {
|
|
181
|
+
folding = false;
|
|
182
|
+
initialFolding = false;
|
|
183
|
+
|
|
184
|
+
if (this.options.animation) {
|
|
185
|
+
multiDragElements.forEach(multiDragElement => {
|
|
186
|
+
unsetRect(multiDragElement);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Remove all auxiliary multidrag items from el, if sorting enabled
|
|
191
|
+
if (this.options.sort) {
|
|
192
|
+
removeMultiDragElements();
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
dragOver({ target, completed, cancel }) {
|
|
198
|
+
if (folding && ~multiDragElements.indexOf(target)) {
|
|
199
|
+
completed(false);
|
|
200
|
+
cancel();
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
revert({ fromSortable, rootEl, sortable, dragRect }) {
|
|
205
|
+
if (multiDragElements.length > 1) {
|
|
206
|
+
// Setup unfold animation
|
|
207
|
+
multiDragElements.forEach(multiDragElement => {
|
|
208
|
+
sortable.addAnimationState({
|
|
209
|
+
target: multiDragElement,
|
|
210
|
+
rect: folding ? getRect(multiDragElement) : dragRect
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
unsetRect(multiDragElement);
|
|
214
|
+
|
|
215
|
+
multiDragElement.fromRect = dragRect;
|
|
216
|
+
|
|
217
|
+
fromSortable.removeAnimationState(multiDragElement);
|
|
218
|
+
});
|
|
219
|
+
folding = false;
|
|
220
|
+
insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
dragOverCompleted({ sortable, isOwner, insertion, activeSortable, parentEl, putSortable }) {
|
|
225
|
+
let options = this.options;
|
|
226
|
+
if (insertion) {
|
|
227
|
+
// Clones must be hidden before folding animation to capture dragRectAbsolute properly
|
|
228
|
+
if (isOwner) {
|
|
229
|
+
activeSortable._hideClone();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
initialFolding = false;
|
|
233
|
+
// If leaving sort:false root, or already folding - Fold to new location
|
|
234
|
+
if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
|
|
235
|
+
// Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
|
|
236
|
+
let dragRectAbsolute = getRect(dragEl, false, true, true);
|
|
237
|
+
|
|
238
|
+
multiDragElements.forEach(multiDragElement => {
|
|
239
|
+
if (multiDragElement === dragEl) return;
|
|
240
|
+
setRect(multiDragElement, dragRectAbsolute);
|
|
241
|
+
|
|
242
|
+
// Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
|
|
243
|
+
// while folding, and so that we can capture them again because old sortable will no longer be fromSortable
|
|
244
|
+
parentEl.appendChild(multiDragElement);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
folding = true;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
|
|
251
|
+
if (!isOwner) {
|
|
252
|
+
// Only remove if not folding (folding will remove them anyways)
|
|
253
|
+
if (!folding) {
|
|
254
|
+
removeMultiDragElements();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (multiDragElements.length > 1) {
|
|
258
|
+
let clonesHiddenBefore = clonesHidden;
|
|
259
|
+
activeSortable._showClone(sortable);
|
|
260
|
+
|
|
261
|
+
// Unfold animation for clones if showing from hidden
|
|
262
|
+
if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
|
|
263
|
+
multiDragClones.forEach(clone => {
|
|
264
|
+
activeSortable.addAnimationState({
|
|
265
|
+
target: clone,
|
|
266
|
+
rect: clonesFromRect
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
clone.fromRect = clonesFromRect;
|
|
270
|
+
clone.thisAnimationDuration = null;
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
activeSortable._showClone(sortable);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
dragOverAnimationCapture({ dragRect, isOwner, activeSortable }) {
|
|
281
|
+
multiDragElements.forEach(multiDragElement => {
|
|
282
|
+
multiDragElement.thisAnimationDuration = null;
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
|
|
286
|
+
clonesFromRect = Object.assign({}, dragRect);
|
|
287
|
+
let dragMatrix = matrix(dragEl, true);
|
|
288
|
+
clonesFromRect.top -= dragMatrix.f;
|
|
289
|
+
clonesFromRect.left -= dragMatrix.e;
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
dragOverAnimationComplete() {
|
|
294
|
+
if (folding) {
|
|
295
|
+
folding = false;
|
|
296
|
+
removeMultiDragElements();
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
drop({ originalEvent: evt, rootEl, parentEl, sortable, dispatchSortableEvent, oldIndex, putSortable }) {
|
|
301
|
+
let toSortable = (putSortable || this.sortable);
|
|
302
|
+
|
|
303
|
+
if (!evt) return;
|
|
304
|
+
|
|
305
|
+
let options = this.options,
|
|
306
|
+
children = parentEl.children;
|
|
307
|
+
|
|
308
|
+
// Multi-drag selection
|
|
309
|
+
if (!dragStarted) {
|
|
310
|
+
if (options.multiDragKey && !this.multiDragKeyDown) {
|
|
311
|
+
this._deselectMultiDrag();
|
|
312
|
+
}
|
|
313
|
+
toggleClass(dragEl, options.selectedClass, !~multiDragElements.indexOf(dragEl));
|
|
314
|
+
|
|
315
|
+
if (!~multiDragElements.indexOf(dragEl)) {
|
|
316
|
+
multiDragElements.push(dragEl);
|
|
317
|
+
dispatchEvent({
|
|
318
|
+
sortable,
|
|
319
|
+
rootEl,
|
|
320
|
+
name: 'select',
|
|
321
|
+
targetEl: dragEl,
|
|
322
|
+
originalEvt: evt
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// Modifier activated, select from last to dragEl
|
|
326
|
+
if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
|
|
327
|
+
let lastIndex = index(lastMultiDragSelect),
|
|
328
|
+
currentIndex = index(dragEl);
|
|
329
|
+
|
|
330
|
+
if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
|
|
331
|
+
// Must include lastMultiDragSelect (select it), in case modified selection from no selection
|
|
332
|
+
// (but previous selection existed)
|
|
333
|
+
let n, i;
|
|
334
|
+
if (currentIndex > lastIndex) {
|
|
335
|
+
i = lastIndex;
|
|
336
|
+
n = currentIndex;
|
|
337
|
+
} else {
|
|
338
|
+
i = currentIndex;
|
|
339
|
+
n = lastIndex + 1;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
for (; i < n; i++) {
|
|
343
|
+
if (~multiDragElements.indexOf(children[i])) continue;
|
|
344
|
+
toggleClass(children[i], options.selectedClass, true);
|
|
345
|
+
multiDragElements.push(children[i]);
|
|
346
|
+
|
|
347
|
+
dispatchEvent({
|
|
348
|
+
sortable,
|
|
349
|
+
rootEl,
|
|
350
|
+
name: 'select',
|
|
351
|
+
targetEl: children[i],
|
|
352
|
+
originalEvt: evt
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
lastMultiDragSelect = dragEl;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
multiDragSortable = toSortable;
|
|
361
|
+
} else {
|
|
362
|
+
multiDragElements.splice(multiDragElements.indexOf(dragEl), 1);
|
|
363
|
+
lastMultiDragSelect = null;
|
|
364
|
+
dispatchEvent({
|
|
365
|
+
sortable,
|
|
366
|
+
rootEl,
|
|
367
|
+
name: 'deselect',
|
|
368
|
+
targetEl: dragEl,
|
|
369
|
+
originalEvt: evt
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Multi-drag drop
|
|
375
|
+
if (dragStarted && this.isMultiDrag) {
|
|
376
|
+
// Do not "unfold" after around dragEl if reverted
|
|
377
|
+
if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
|
|
378
|
+
let dragRect = getRect(dragEl),
|
|
379
|
+
multiDragIndex = index(dragEl, ':not(.' + this.options.selectedClass + ')');
|
|
380
|
+
|
|
381
|
+
if (!initialFolding && options.animation) dragEl.thisAnimationDuration = null;
|
|
382
|
+
|
|
383
|
+
toSortable.captureAnimationState();
|
|
384
|
+
|
|
385
|
+
if (!initialFolding) {
|
|
386
|
+
if (options.animation) {
|
|
387
|
+
dragEl.fromRect = dragRect;
|
|
388
|
+
multiDragElements.forEach(multiDragElement => {
|
|
389
|
+
multiDragElement.thisAnimationDuration = null;
|
|
390
|
+
if (multiDragElement !== dragEl) {
|
|
391
|
+
let rect = folding ? getRect(multiDragElement) : dragRect;
|
|
392
|
+
multiDragElement.fromRect = rect;
|
|
393
|
+
|
|
394
|
+
// Prepare unfold animation
|
|
395
|
+
toSortable.addAnimationState({
|
|
396
|
+
target: multiDragElement,
|
|
397
|
+
rect: rect
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
|
|
404
|
+
// properly they must all be removed
|
|
405
|
+
removeMultiDragElements();
|
|
406
|
+
|
|
407
|
+
multiDragElements.forEach(multiDragElement => {
|
|
408
|
+
if (children[multiDragIndex]) {
|
|
409
|
+
parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
|
|
410
|
+
} else {
|
|
411
|
+
parentEl.appendChild(multiDragElement);
|
|
412
|
+
}
|
|
413
|
+
multiDragIndex++;
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// If initial folding is done, the elements may have changed position because they are now
|
|
417
|
+
// unfolding around dragEl, even though dragEl may not have his index changed, so update event
|
|
418
|
+
// must be fired here as Sortable will not.
|
|
419
|
+
if (oldIndex === index(dragEl)) {
|
|
420
|
+
let update = false;
|
|
421
|
+
multiDragElements.forEach(multiDragElement => {
|
|
422
|
+
if (multiDragElement.sortableIndex !== index(multiDragElement)) {
|
|
423
|
+
update = true;
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
if (update) {
|
|
429
|
+
dispatchSortableEvent('update');
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Must be done after capturing individual rects (scroll bar)
|
|
435
|
+
multiDragElements.forEach(multiDragElement => {
|
|
436
|
+
unsetRect(multiDragElement);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
toSortable.animateAll();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
multiDragSortable = toSortable;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Remove clones if necessary
|
|
446
|
+
if (rootEl === parentEl || (putSortable && putSortable.lastPutMode !== 'clone')) {
|
|
447
|
+
multiDragClones.forEach(clone => {
|
|
448
|
+
clone.parentNode && clone.parentNode.removeChild(clone);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
|
|
453
|
+
nullingGlobal() {
|
|
454
|
+
this.isMultiDrag =
|
|
455
|
+
dragStarted = false;
|
|
456
|
+
multiDragClones.length = 0;
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
destroyGlobal() {
|
|
460
|
+
this._deselectMultiDrag();
|
|
461
|
+
off(document, 'pointerup', this._deselectMultiDrag);
|
|
462
|
+
off(document, 'mouseup', this._deselectMultiDrag);
|
|
463
|
+
off(document, 'touchend', this._deselectMultiDrag);
|
|
464
|
+
|
|
465
|
+
off(document, 'keydown', this._checkKeyDown);
|
|
466
|
+
off(document, 'keyup', this._checkKeyUp);
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
_deselectMultiDrag(evt) {
|
|
470
|
+
if (typeof dragStarted !== "undefined" && dragStarted) return;
|
|
471
|
+
|
|
472
|
+
// Only deselect if selection is in this sortable
|
|
473
|
+
if (multiDragSortable !== this.sortable) return;
|
|
474
|
+
|
|
475
|
+
// Only deselect if target is not item in this sortable
|
|
476
|
+
if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
|
|
477
|
+
|
|
478
|
+
// Only deselect if left click
|
|
479
|
+
if (evt && evt.button !== 0) return;
|
|
480
|
+
|
|
481
|
+
while (multiDragElements.length) {
|
|
482
|
+
let el = multiDragElements[0];
|
|
483
|
+
toggleClass(el, this.options.selectedClass, false);
|
|
484
|
+
multiDragElements.shift();
|
|
485
|
+
dispatchEvent({
|
|
486
|
+
sortable: this.sortable,
|
|
487
|
+
rootEl: this.sortable.el,
|
|
488
|
+
name: 'deselect',
|
|
489
|
+
targetEl: el,
|
|
490
|
+
originalEvt: evt
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
|
|
495
|
+
_checkKeyDown(evt) {
|
|
496
|
+
if (evt.key === this.options.multiDragKey) {
|
|
497
|
+
this.multiDragKeyDown = true;
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
|
|
501
|
+
_checkKeyUp(evt) {
|
|
502
|
+
if (evt.key === this.options.multiDragKey) {
|
|
503
|
+
this.multiDragKeyDown = false;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
return Object.assign(MultiDrag, {
|
|
509
|
+
// Static methods & properties
|
|
510
|
+
pluginName: 'multiDrag',
|
|
511
|
+
utils: {
|
|
512
|
+
/**
|
|
513
|
+
* Selects the provided multi-drag item
|
|
514
|
+
* @param {HTMLElement} el The element to be selected
|
|
515
|
+
*/
|
|
516
|
+
select(el) {
|
|
517
|
+
let sortable = el.parentNode[expando];
|
|
518
|
+
if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
|
|
519
|
+
if (multiDragSortable && multiDragSortable !== sortable) {
|
|
520
|
+
multiDragSortable.multiDrag._deselectMultiDrag();
|
|
521
|
+
multiDragSortable = sortable;
|
|
522
|
+
}
|
|
523
|
+
toggleClass(el, sortable.options.selectedClass, true);
|
|
524
|
+
multiDragElements.push(el);
|
|
525
|
+
},
|
|
526
|
+
/**
|
|
527
|
+
* Deselects the provided multi-drag item
|
|
528
|
+
* @param {HTMLElement} el The element to be deselected
|
|
529
|
+
*/
|
|
530
|
+
deselect(el) {
|
|
531
|
+
let sortable = el.parentNode[expando],
|
|
532
|
+
index = multiDragElements.indexOf(el);
|
|
533
|
+
if (!sortable || !sortable.options.multiDrag || !~index) return;
|
|
534
|
+
toggleClass(el, sortable.options.selectedClass, false);
|
|
535
|
+
multiDragElements.splice(index, 1);
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
eventProperties() {
|
|
539
|
+
const oldIndicies = [],
|
|
540
|
+
newIndicies = [];
|
|
541
|
+
|
|
542
|
+
multiDragElements.forEach(multiDragElement => {
|
|
543
|
+
oldIndicies.push({
|
|
544
|
+
multiDragElement,
|
|
545
|
+
index: multiDragElement.sortableIndex
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
// multiDragElements will already be sorted if folding
|
|
549
|
+
let newIndex;
|
|
550
|
+
if (folding && multiDragElement !== dragEl) {
|
|
551
|
+
newIndex = -1;
|
|
552
|
+
} else if (folding) {
|
|
553
|
+
newIndex = index(multiDragElement, ':not(.' + this.options.selectedClass + ')');
|
|
554
|
+
} else {
|
|
555
|
+
newIndex = index(multiDragElement);
|
|
556
|
+
}
|
|
557
|
+
newIndicies.push({
|
|
558
|
+
multiDragElement,
|
|
559
|
+
index: newIndex
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
return {
|
|
563
|
+
items: [...multiDragElements],
|
|
564
|
+
clones: [...multiDragClones],
|
|
565
|
+
oldIndicies,
|
|
566
|
+
newIndicies
|
|
567
|
+
};
|
|
568
|
+
},
|
|
569
|
+
optionListeners: {
|
|
570
|
+
multiDragKey(key) {
|
|
571
|
+
key = key.toLowerCase();
|
|
572
|
+
if (key === 'ctrl') {
|
|
573
|
+
key = 'Control';
|
|
574
|
+
} else if (key.length > 1) {
|
|
575
|
+
key = key.charAt(0).toUpperCase() + key.substr(1);
|
|
576
|
+
}
|
|
577
|
+
return key;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function insertMultiDragElements(clonesInserted, rootEl) {
|
|
584
|
+
multiDragElements.forEach((multiDragElement, i) => {
|
|
585
|
+
let target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
|
|
586
|
+
if (target) {
|
|
587
|
+
rootEl.insertBefore(multiDragElement, target);
|
|
588
|
+
} else {
|
|
589
|
+
rootEl.appendChild(multiDragElement);
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Insert multi-drag clones
|
|
596
|
+
* @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
|
|
597
|
+
* @param {HTMLElement} rootEl
|
|
598
|
+
*/
|
|
599
|
+
function insertMultiDragClones(elementsInserted, rootEl) {
|
|
600
|
+
multiDragClones.forEach((clone, i) => {
|
|
601
|
+
let target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
|
|
602
|
+
if (target) {
|
|
603
|
+
rootEl.insertBefore(clone, target);
|
|
604
|
+
} else {
|
|
605
|
+
rootEl.appendChild(clone);
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function removeMultiDragElements() {
|
|
611
|
+
multiDragElements.forEach(multiDragElement => {
|
|
612
|
+
if (multiDragElement === dragEl) return;
|
|
613
|
+
multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export default MultiDragPlugin;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
## MultiDrag Plugin
|
|
2
|
+
This plugin allows users to select multiple items within a sortable at once, and drag them as one item.
|
|
3
|
+
Once placed, the items will unfold into their original order, but all beside each other at the new position.
|
|
4
|
+
[Read More](https://github.com/SortableJS/Sortable/wiki/Dragging-Multiple-Items-in-Sortable)
|
|
5
|
+
|
|
6
|
+
Demo: https://jsbin.com/wopavom/edit?js,output
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Mounting
|
|
13
|
+
```js
|
|
14
|
+
import { Sortable, MultiDrag } from 'sortablejs';
|
|
15
|
+
|
|
16
|
+
Sortable.mount(new MultiDrag());
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Options
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
new Sortable(el, {
|
|
27
|
+
multiDrag: true, // Enable the plugin
|
|
28
|
+
selectedClass: "sortable-selected", // Class name for selected item
|
|
29
|
+
multiDragKey: null, // Key that must be down for items to be selected
|
|
30
|
+
|
|
31
|
+
// Called when an item is selected
|
|
32
|
+
onSelect: function(/**Event*/evt) {
|
|
33
|
+
evt.item // The selected item
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
// Called when an item is deselected
|
|
37
|
+
onDeselect: function(/**Event*/evt) {
|
|
38
|
+
evt.item // The deselected item
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
#### `multiDragKey` option
|
|
48
|
+
The key that must be down for multiple items to be selected. The default is `null`, meaning no key must be down.
|
|
49
|
+
For special keys, such as the <kbd>CTRL</kbd> key, simply specify the option as `'CTRL'` (casing does not matter).
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
#### `selectedClass` option
|
|
56
|
+
Class name for the selected item(s) if multiDrag is enabled. Defaults to `sortable-selected`.
|
|
57
|
+
|
|
58
|
+
```css
|
|
59
|
+
.selected {
|
|
60
|
+
background-color: #f9c7c8;
|
|
61
|
+
border: solid red 1px;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
Sortable.create(list, {
|
|
67
|
+
multiDrag: true,
|
|
68
|
+
selectedClass: "selected"
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Event Properties
|
|
77
|
+
- items:`HTMLElement[]` — Array of selected items, or empty
|
|
78
|
+
- clones:`HTMLElement[]` — Array of clones, or empty
|
|
79
|
+
- oldIndicies:`Index[]` — Array containing information on the old indicies of the selected elements.
|
|
80
|
+
- newIndicies:`Index[]` — Array containing information on the new indicies of the selected elements.
|
|
81
|
+
|
|
82
|
+
#### Index Object
|
|
83
|
+
- element:`HTMLElement` — The element whose index is being given
|
|
84
|
+
- index:`Number` — The index of the element
|
|
85
|
+
|
|
86
|
+
#### Note on `newIndicies`
|
|
87
|
+
For any event that is fired during sorting, the index of any selected element that is not the main dragged element is given as `-1`.
|
|
88
|
+
This is because it has either been removed from the DOM, or because it is in a folding animation (folding to the dragged element) and will be removed after this animation is complete.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
### Sortable.utils
|
|
95
|
+
* select(el:`HTMLElement`) — select the given multi-drag item
|
|
96
|
+
* deselect(el:`HTMLElement`) — deselect the given multi-drag item
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './MultiDrag.js';
|