bullet_train-sortable 1.29.0 → 1.30.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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a042c5807b320f70fa014128ac0e84f4a3e6e3c58bb61d43a7c4a0ef8647bfec
|
4
|
+
data.tar.gz: a7389b72a4490bbd42d11e0ff56b44d1e40c621858a5c9f262fe066beb7b295c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01131f75504043564573448aa18d84cf7130d64964f754f7f4861ef6fd1d6f1baa635d3775a807ccf8e91bb1068ec875c8207d3ef78b12810e50574bb26f2849
|
7
|
+
data.tar.gz: e70c3d68ec7b2df0c237267eab2a917e13d4e0cd0b9f58ec019a6d5f27b5b747e2fdac73d6e8db4e49b9a2a9289cd9ae08be3f78c7a092f01efe186d5efd4fea
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
import { post } from '@rails/request.js'
|
3
|
+
import jquery from "jquery";
|
4
|
+
require("dragula/dist/dragula.min.css")
|
5
|
+
|
6
|
+
import dragula from 'dragula';
|
7
|
+
|
8
|
+
export default class extends Controller {
|
9
|
+
static values = {
|
10
|
+
reorderPath: String,
|
11
|
+
saveOnReorder: { type: Boolean, default: true }
|
12
|
+
}
|
13
|
+
|
14
|
+
// will be reissued as native dom events name prepended with 'sortable:' e.g. 'sortable:drag', 'sortable:drop', etc
|
15
|
+
static pluginEventsToReissue = [ "drag", "dragend", "drop", "cancel", "remove", "shadow", "over", "out", "cloned" ]
|
16
|
+
|
17
|
+
initialize() {
|
18
|
+
if (window.jQuery === undefined) {
|
19
|
+
window.jQuery = jquery // required for select2 used for time zone select, but we also use global jQuery throughout below
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
connect() {
|
24
|
+
if (!this.hasReorderPathValue) { return }
|
25
|
+
this.initPluginInstance()
|
26
|
+
}
|
27
|
+
|
28
|
+
disconnect() {
|
29
|
+
this.teardownPluginInstance()
|
30
|
+
}
|
31
|
+
|
32
|
+
initPluginInstance() {
|
33
|
+
const self = this
|
34
|
+
this.plugin = dragula([this.element], {
|
35
|
+
moves: function(el, container, handle) {
|
36
|
+
var $handles = jQuery(el).find('.reorder-handle')
|
37
|
+
if ($handles.length) {
|
38
|
+
return !!jQuery(handle).closest('.reorder-handle').length
|
39
|
+
} else {
|
40
|
+
if (!jQuery(handle).closest('.undraggable').length) {
|
41
|
+
return self.element === container
|
42
|
+
} else {
|
43
|
+
return false
|
44
|
+
}
|
45
|
+
}
|
46
|
+
},
|
47
|
+
accepts: function (el, target, source, sibling) {
|
48
|
+
if (jQuery(sibling).hasClass('undraggable') && jQuery(sibling).prev().hasClass('undraggable')) {
|
49
|
+
return false
|
50
|
+
} else {
|
51
|
+
return true
|
52
|
+
}
|
53
|
+
},
|
54
|
+
}).on('drop', function (el) {
|
55
|
+
// save order here.
|
56
|
+
if (self.saveOnReorderValue) {
|
57
|
+
self.saveSortOrder()
|
58
|
+
}
|
59
|
+
}).on('over', function (el, container) {
|
60
|
+
// deselect any text fields, or else things go slow!
|
61
|
+
jQuery(document.activeElement).blur()
|
62
|
+
})
|
63
|
+
|
64
|
+
this.initReissuePluginEventsAsNativeEvents()
|
65
|
+
}
|
66
|
+
|
67
|
+
initReissuePluginEventsAsNativeEvents() {
|
68
|
+
this.constructor.pluginEventsToReissue.forEach((eventName) => {
|
69
|
+
this.plugin.on(eventName, (...args) => {
|
70
|
+
this.dispatch(eventName, { detail: { plugin: 'dragula', type: eventName, args: args }})
|
71
|
+
})
|
72
|
+
})
|
73
|
+
}
|
74
|
+
|
75
|
+
teardownPluginInstance() {
|
76
|
+
if (this.plugin === undefined) { return }
|
77
|
+
|
78
|
+
// revert to original markup, remove any event listeners
|
79
|
+
this.plugin.destroy()
|
80
|
+
}
|
81
|
+
|
82
|
+
saveSortOrder() {
|
83
|
+
var idsInOrder = Array.from(this.element.childNodes).map((el) => { return parseInt(el.dataset?.id) });
|
84
|
+
|
85
|
+
post(this.reorderPathValue, { body: JSON.stringify({ids_in_order: idsInOrder}) })
|
86
|
+
}
|
87
|
+
|
88
|
+
}
|
@@ -1,88 +1,327 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus"
|
2
2
|
import { post } from '@rails/request.js'
|
3
|
-
import jquery from "jquery";
|
4
|
-
require("dragula/dist/dragula.min.css")
|
5
|
-
|
6
|
-
import dragula from 'dragula';
|
7
3
|
|
4
|
+
// Connects to data-controller="sortable"
|
8
5
|
export default class extends Controller {
|
9
6
|
static values = {
|
10
7
|
reorderPath: String,
|
11
8
|
saveOnReorder: { type: Boolean, default: true }
|
12
9
|
}
|
13
|
-
|
14
|
-
|
15
|
-
static pluginEventsToReissue = [ "drag", "dragend", "drop", "cancel", "remove", "shadow", "over", "out", "cloned" ]
|
10
|
+
static classes = ["activeDropzone", "activeItem", "dropTarget"];
|
11
|
+
static targets = [ "handle"];
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
window.jQuery = jquery // required for select2 used for time zone select, but we also use global jQuery throughout below
|
20
|
-
}
|
13
|
+
async saveSortOrder(idsInOrder) {
|
14
|
+
await post(this.reorderPathValue, { body: JSON.stringify({ids_in_order: idsInOrder}) })
|
21
15
|
}
|
22
16
|
|
23
17
|
connect() {
|
24
|
-
|
25
|
-
this.
|
18
|
+
const saveOrderCallback = this.saveOnReorderValue ? this.saveSortOrder.bind(this) : null;
|
19
|
+
this.sortingPlugin = new SortableTable(
|
20
|
+
this.element,
|
21
|
+
saveOrderCallback,
|
22
|
+
this.handleTargets,
|
23
|
+
{
|
24
|
+
activeDropzoneClasses: this.activeDropzoneClasses,
|
25
|
+
activeItemClasses: this.activeItemClasses,
|
26
|
+
dropTargetClasses: this.dropTargetClasses
|
27
|
+
}
|
28
|
+
);
|
26
29
|
}
|
27
30
|
|
28
31
|
disconnect() {
|
29
|
-
this.
|
30
|
-
}
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
32
|
+
this.sortingPlugin.destroy();
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
function getDataNode(node) {
|
37
|
+
return node.closest("[data-id]");
|
38
|
+
}
|
39
|
+
|
40
|
+
function getHandleNode(node) {
|
41
|
+
return node.closest("[data-sortable-target='handle']");
|
42
|
+
}
|
43
|
+
|
44
|
+
function getMetaValue(name) {
|
45
|
+
const element = document.head.querySelector(`meta[name="${name}"]`);
|
46
|
+
return element.getAttribute("content");
|
47
|
+
}
|
48
|
+
|
49
|
+
class SortableTable{
|
50
|
+
// We'll emit events using this prefix. `sortable:drag` & `sortable:drop` for instance.
|
51
|
+
static eventPrefix = "sortable";
|
52
|
+
// These are defaults so that we don't have to require people to update their templates.
|
53
|
+
// If the template does contain values for any of these the template values will be used instead.
|
54
|
+
static defaultClasses = {
|
55
|
+
"activeDropzoneClasses": "border-dashed bg-gray-50 border-slate-400",
|
56
|
+
"activeItemClasses": "shadow bg-white bg-white *:bg-white opacity-100 *:opacity-100",
|
57
|
+
"dropTargetClasses": "shadow-inner shadow-gray-500 hover:shadow-inner bg-gray-100 *:opacity-0 *:bg-gray-100"
|
58
|
+
};
|
59
|
+
|
60
|
+
constructor(tbodyElement, saveSortOrder, handleTargets, styles, customEventPrefix){
|
61
|
+
this.element = tbodyElement;
|
62
|
+
this.saveSortOrder = saveSortOrder;
|
63
|
+
this.handleTargets = handleTargets;
|
64
|
+
|
65
|
+
this.activeDropzoneClassesWithDefaults = styles.activeDropzoneClasses.length == 0 ? this.constructor.defaultClasses["activeDropzoneClasses"].split(" ") : styles.activeDropzoneClasses;
|
66
|
+
this.activeItemClassesWithDefaults = styles.activeItemClasses.length == 0 ? this.constructor.defaultClasses["activeItemClasses"].split(" ") : styles.activeItemClasses;
|
67
|
+
this.dropTargetClassesWithDefaults = styles.dropTargetClasses.length == 0 ? this.constructor.defaultClasses["dropTargetClasses"].split(" ") : styles.dropTargetClasses;
|
68
|
+
this.eventPrefixWithDefaults = customEventPrefix ? customEventPrefix : this.constructor.eventPrefix;
|
69
|
+
|
70
|
+
this.element.addEventListener('dragstart', this.dragstart.bind(this));
|
71
|
+
this.element.addEventListener('dragover', this.dragover.bind(this));
|
72
|
+
this.element.addEventListener('dragenter', this.dragenter.bind(this));
|
73
|
+
this.element.addEventListener('dragleave', this.dragleave.bind(this));
|
74
|
+
this.element.addEventListener('dragend', this.dragend.bind(this));
|
75
|
+
this.element.addEventListener('drop', this.drop.bind(this));
|
76
|
+
|
77
|
+
if(this.handleTargets.length == 0){
|
78
|
+
this.addDragHandles();
|
79
|
+
}
|
80
|
+
|
81
|
+
this.element.addEventListener('mousedown', this.dragHandleMouseDown.bind(this));
|
82
|
+
this.element.addEventListener('mouseup', this.dragHandleMouseUp.bind(this));
|
83
|
+
|
84
|
+
// We set this when we've detected `mousedown` in a handle. Then all of the `drag*` handlers
|
85
|
+
// bail out if we don't have a draggable row. This prevents problems and weird behavior if you
|
86
|
+
// drag something other than the handle. Like highlighted text, or a link, for instance.
|
87
|
+
this.aRowIsDraggable = false;
|
88
|
+
}
|
89
|
+
|
90
|
+
destroy(){
|
91
|
+
this.element.removeEventListener('dragstart', this.dragstart.bind(this));
|
92
|
+
this.element.removeEventListener('dragover', this.dragover.bind(this));
|
93
|
+
this.element.removeEventListener('dragenter', this.dragenter.bind(this));
|
94
|
+
this.element.removeEventListener('dragleave', this.dragleave.bind(this));
|
95
|
+
this.element.removeEventListener('dragend', this.dragend.bind(this));
|
96
|
+
this.element.removeEventListener('drop', this.drop.bind(this));
|
97
|
+
|
98
|
+
this.element.removeEventListener('mousedown', this.dragHandleMouseDown.bind(this));
|
99
|
+
this.element.removeEventListener('mouseup', this.dragHandleMouseUp.bind(this));
|
100
|
+
}
|
101
|
+
|
102
|
+
dragHandleMouseDown(event){
|
103
|
+
const handle = getHandleNode(event.target);
|
104
|
+
if(!handle){
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
const draggableItem = getDataNode(event.target);
|
108
|
+
if(draggableItem){
|
109
|
+
draggableItem.setAttribute('draggable', true);
|
110
|
+
this.aRowIsDraggable = true;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
dragHandleMouseUp(event){
|
115
|
+
const handle = getHandleNode(event.target);
|
116
|
+
if(!handle){
|
117
|
+
return;
|
118
|
+
}
|
119
|
+
const draggableItem = getDataNode(event.target);
|
120
|
+
if(draggableItem){
|
121
|
+
draggableItem.setAttribute('draggable', false);
|
122
|
+
this.aRowIsDraggable = false;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
dragstart(event) {
|
127
|
+
if(!this.aRowIsDraggable){
|
128
|
+
return;
|
129
|
+
}
|
130
|
+
this.element.classList.add(...this.activeDropzoneClassesWithDefaults);
|
131
|
+
const draggableItem = getDataNode(event.target);
|
132
|
+
draggableItem.classList.add(...this.activeItemClassesWithDefaults);
|
133
|
+
event.dataTransfer.setData(
|
134
|
+
"application/drag-key",
|
135
|
+
draggableItem.dataset.id
|
136
|
+
);
|
137
|
+
event.dataTransfer.effectAllowed = "move";
|
138
|
+
// For most browsers we could rely on the dataTransfer.setData call above,
|
139
|
+
// but Safari doesn't seem to allow us access to that data at any time other
|
140
|
+
// than during a drop. But we need it during dragenter to reorder the list
|
141
|
+
// as the drag happens. So, we just stash the value here and then use it later.
|
142
|
+
this.draggingDataId = draggableItem.dataset.id;
|
143
|
+
|
144
|
+
this.dispatch('start', { detail: { type: 'start', args: [draggableItem, this.element] }})
|
145
|
+
// We're dispatching drag here in addition to start to retain backwards compatibility with dragula.js.
|
146
|
+
// It emits a single 'drag' event when an item is first dragged, but not on each movement thereafter.
|
147
|
+
this.dispatch('drag', { detail: { type: 'drag', args: [draggableItem, this.element] }})
|
148
|
+
}
|
149
|
+
|
150
|
+
dragover(event) {
|
151
|
+
if(!this.aRowIsDraggable){
|
152
|
+
return;
|
153
|
+
}
|
154
|
+
event.preventDefault();
|
155
|
+
return true;
|
156
|
+
}
|
157
|
+
|
158
|
+
dragenter(event) {
|
159
|
+
if(!this.aRowIsDraggable){
|
160
|
+
return;
|
161
|
+
}
|
162
|
+
let parent = getDataNode(event.target);
|
163
|
+
|
164
|
+
// We keep a count of the `dragenter` events for the row being dragged to fix jank. When dragging between cells
|
165
|
+
// (or cell content) within a row a dragenter event is fired before the dragleave event from the previous cell.
|
166
|
+
// If we removed the activeItemClasses when the dragleave happens then the UI doesn't match expectations.
|
167
|
+
if(parent.dataset.dragEnterCount){
|
168
|
+
parent.dataset.dragEnterCount = parseInt(parent.dataset.dragEnterCount) + 1;
|
169
|
+
}else{
|
170
|
+
parent.dataset.dragEnterCount = 1;
|
171
|
+
}
|
172
|
+
|
173
|
+
if (parent != null && parent.dataset.id != null) {
|
174
|
+
parent.classList.add(...this.dropTargetClassesWithDefaults);
|
175
|
+
var data = this.draggingDataId;
|
176
|
+
const draggedItem = this.element.querySelector(
|
177
|
+
`[data-id='${data}']`
|
178
|
+
);
|
179
|
+
|
180
|
+
if (draggedItem) {
|
181
|
+
draggedItem.classList.remove(...this.activeItemClassesWithDefaults);
|
182
|
+
|
183
|
+
let dispatchEvent = false;
|
184
|
+
|
185
|
+
if (parent.compareDocumentPosition(draggedItem) & Node.DOCUMENT_POSITION_FOLLOWING) {
|
186
|
+
let result = parent.insertAdjacentElement( "beforebegin", draggedItem);
|
187
|
+
dispatchEvent = true;
|
188
|
+
} else if (parent.compareDocumentPosition(draggedItem) & Node.DOCUMENT_POSITION_PRECEDING) {
|
189
|
+
let result = parent.insertAdjacentElement("afterend", draggedItem);
|
190
|
+
dispatchEvent = true;
|
45
191
|
}
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
192
|
+
|
193
|
+
if(dispatchEvent){
|
194
|
+
this.dispatch('reordered', { detail: { type: 'shadow', args: [draggedItem, this.element, this.element] }});
|
195
|
+
// We're dispatching 'shadow' here to retain backwards compatibility with dragula.js.
|
196
|
+
// It emits a 'shadow' event when the items in the list are rearranged mid-drag.
|
197
|
+
// TODO: This is firing more often than dragula fires it. Is that a problem?
|
198
|
+
this.dispatch('shadow', { detail: { type: 'shadow', args: [draggedItem, this.element, this.element] }});
|
52
199
|
}
|
53
|
-
|
54
|
-
}).on('drop', function (el) {
|
55
|
-
// save order here.
|
56
|
-
if (self.saveOnReorderValue) {
|
57
|
-
self.saveSortOrder()
|
200
|
+
|
58
201
|
}
|
59
|
-
|
60
|
-
|
61
|
-
jQuery(document.activeElement).blur()
|
62
|
-
})
|
63
|
-
|
64
|
-
this.initReissuePluginEventsAsNativeEvents()
|
202
|
+
event.preventDefault();
|
203
|
+
}
|
65
204
|
}
|
66
|
-
|
67
|
-
|
68
|
-
this.
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
205
|
+
|
206
|
+
dragleave(event) {
|
207
|
+
if(!this.aRowIsDraggable){
|
208
|
+
return;
|
209
|
+
}
|
210
|
+
let parent = getDataNode(event.target);
|
211
|
+
|
212
|
+
if(parent.dataset.dragEnterCount > 0){
|
213
|
+
parent.dataset.dragEnterCount = parseInt(parent.dataset.dragEnterCount) - 1;
|
214
|
+
}
|
215
|
+
|
216
|
+
if (parent != null && parent.dataset.id != null && parent.dataset.dragEnterCount == 0) {
|
217
|
+
parent.classList.remove(...this.dropTargetClassesWithDefaults);
|
218
|
+
event.preventDefault();
|
219
|
+
}
|
73
220
|
}
|
74
221
|
|
75
|
-
|
76
|
-
if
|
222
|
+
async drop(event) {
|
223
|
+
if(!this.aRowIsDraggable){
|
224
|
+
return;
|
225
|
+
}
|
226
|
+
this.element.classList.remove(...this.activeDropzoneClassesWithDefaults);
|
227
|
+
|
228
|
+
const dropTarget = getDataNode(event.target);
|
229
|
+
dropTarget.classList.remove(...this.dropTargetClassesWithDefaults);
|
77
230
|
|
78
|
-
|
79
|
-
this.
|
231
|
+
var data = this.draggingDataId;
|
232
|
+
const draggedItem = this.element.querySelector(
|
233
|
+
`[data-id='${data}']`
|
234
|
+
);
|
235
|
+
|
236
|
+
if (draggedItem) {
|
237
|
+
draggedItem.classList.remove(...this.activeItemClassesWithDefaults);
|
238
|
+
|
239
|
+
if (
|
240
|
+
dropTarget.compareDocumentPosition(draggedItem) &
|
241
|
+
Node.DOCUMENT_POSITION_FOLLOWING
|
242
|
+
) {
|
243
|
+
let result = dropTarget.insertAdjacentElement(
|
244
|
+
"beforebegin",
|
245
|
+
draggedItem
|
246
|
+
);
|
247
|
+
} else if (
|
248
|
+
dropTarget.compareDocumentPosition(draggedItem) &
|
249
|
+
Node.DOCUMENT_POSITION_PRECEDING
|
250
|
+
) {
|
251
|
+
let result = dropTarget.insertAdjacentElement("afterend", draggedItem);
|
252
|
+
}
|
253
|
+
|
254
|
+
if (this.saveSortOrder) {
|
255
|
+
var idsInOrder = Array.from(this.element.childNodes).map((el) => { return el.dataset?.id ? parseInt(el.dataset?.id) : null });
|
256
|
+
idsInOrder = idsInOrder.filter(element => element !== null);
|
257
|
+
await this.saveSortOrder(idsInOrder);
|
258
|
+
this.dispatch('saved', { detail: { type: 'saved', args: [this.element] }})
|
259
|
+
}
|
260
|
+
|
261
|
+
// TODO: This fires more often than dragula fires it. Dragula does not fire this when an item was dragged but not moved/reorded.
|
262
|
+
// Instead dragula fires a `cancel` event. But we're firing a `drop` and no `cancel` in that situation.
|
263
|
+
this.dispatch('drop', { detail: { type: 'drop', args: [draggedItem, this.element, this.element, draggedItem.nextElementSibling] }})
|
264
|
+
}
|
265
|
+
event.preventDefault();
|
266
|
+
}
|
267
|
+
|
268
|
+
dragend(event) {
|
269
|
+
if(!this.aRowIsDraggable){
|
270
|
+
return;
|
271
|
+
}
|
272
|
+
this.element.classList.remove(...this.activeDropzoneClassesWithDefaults);
|
273
|
+
|
274
|
+
const draggableItem = getDataNode(event.target);
|
275
|
+
draggableItem.setAttribute('draggable', false);
|
276
|
+
draggableItem.dataset.dragEnterCount = 0;
|
277
|
+
|
278
|
+
this.dispatch('end', { detail: { type: 'end', args: [draggableItem, this.element] }})
|
279
|
+
// We emit dragend here as well to maintain some backwards compatiblity with the old dragula controller.
|
280
|
+
this.dispatch('dragend', { detail: { type: 'dragend', args: [draggableItem, this.element] }})
|
281
|
+
}
|
282
|
+
|
283
|
+
addDragHandles(){
|
284
|
+
// Here we assume that this controller is connected to a tbody element
|
285
|
+
const table = this.element.parentNode;
|
286
|
+
const thead = table.querySelector('thead');
|
287
|
+
const headRow = thead.querySelector('tr');
|
288
|
+
const newTh = document.createElement('th');
|
289
|
+
newTh.classList.add(...'w-6'.split(' '))
|
290
|
+
headRow.prepend(newTh);
|
291
|
+
|
292
|
+
const draggables = this.element.querySelectorAll('tr');
|
293
|
+
for (const draggable of draggables) {
|
294
|
+
const newCell = document.createElement('td');
|
295
|
+
newCell.dataset.sortableTarget = 'handle';
|
296
|
+
newCell.classList.add(...'cursor-grab active:cursor-grabbing'.split(' '));
|
297
|
+
|
298
|
+
const icon = document.createElement('i');
|
299
|
+
icon.classList.add(...'ti ti-menu opacity-25 group-hover:opacity-100'.split(' '));
|
300
|
+
|
301
|
+
newCell.append(icon);
|
302
|
+
draggable.prepend(newCell);
|
303
|
+
this.handleTargets.push(newCell);
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
dispatch(eventName,data){
|
308
|
+
const fullEventName = this.eventPrefixWithDefaults + ":" + eventName;
|
309
|
+
const event = new CustomEvent(fullEventName, data);
|
310
|
+
this.element.dispatchEvent(event);
|
80
311
|
}
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
312
|
+
|
313
|
+
// TODO: I'm not sure this is adequate. I think we may need to "manually" dispatch these from within the
|
314
|
+
// approriate event handles so that we can add more info to `args`. For instance, the "drop" event may
|
315
|
+
// need to include the sibling that the dropped element was dropped in front of. Related, do people actually
|
316
|
+
// use these re-issued events?
|
317
|
+
/*
|
318
|
+
initReissuePluginEventsAsNativeEvents() {
|
319
|
+
this.constructor.pluginEventsToReissue.forEach((eventName) => {
|
320
|
+
this.element.addEventListener(eventName, (...args) => {
|
321
|
+
this.dispatch(eventName, { detail: { type: eventName, args: args }})
|
322
|
+
})
|
323
|
+
})
|
86
324
|
}
|
325
|
+
*/
|
87
326
|
|
88
|
-
}
|
327
|
+
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet_train-sortable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.30.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- README.md
|
63
63
|
- Rakefile
|
64
64
|
- app/controllers/concerns/sortable_actions.rb
|
65
|
+
- app/javascript/controllers/dragula-sortable_controller.js
|
65
66
|
- app/javascript/controllers/index.js
|
66
67
|
- app/javascript/controllers/sortable_controller.js
|
67
68
|
- app/javascript/index.js
|