katalyst-tables 3.11.3 → 3.12.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/app/assets/builds/katalyst/tables.esm.js +124 -64
- data/app/assets/builds/katalyst/tables.js +124 -64
- data/app/assets/builds/katalyst/tables.min.js +1 -1
- data/app/assets/builds/katalyst/tables.min.js.map +1 -1
- data/app/assets/stylesheets/katalyst/tables/table.css +7 -10
- data/app/javascript/tables/orderable/item_controller.js +50 -32
- data/app/javascript/tables/orderable/list_controller.js +74 -32
- data/lib/katalyst/tables/collection/type/helpers/multiple.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2c67bc4631e5e9cb0b84c73e61572dd2f7c2d049700a10172d56124a2e59a997
|
|
4
|
+
data.tar.gz: 897729b9bed4774e874fa09df37d6e3c6a1c651c465431d182f047843df7a2df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f02e1176c948660ecae3fde031492bdcbf1b7ffde9e20ca9018277da2cc80f5c353a7eabd97d070a2c5a4fb27923e52668edea461cd3008bd71d06407675e2e0
|
|
7
|
+
data.tar.gz: f519c5b3518213bebe01a994d0cf3573d11974d16949573fb5ab0f884887f407ed0fed655f2bd14c7d83884cf149b53983fb363bfe186181821d2d67371a63e7
|
data/CHANGELOG.md
CHANGED
|
@@ -19,7 +19,7 @@ class OrderableRowController extends Controller {
|
|
|
19
19
|
dragUpdate(offset) {
|
|
20
20
|
this.dragOffset = offset;
|
|
21
21
|
this.row.style.position = "relative";
|
|
22
|
-
this.row.style.
|
|
22
|
+
this.row.style.transform = `scale(1.01) translateY(${offset}px)`;
|
|
23
23
|
this.row.style.zIndex = "1";
|
|
24
24
|
this.row.toggleAttribute("dragging", true);
|
|
25
25
|
}
|
|
@@ -28,13 +28,27 @@ class OrderableRowController extends Controller {
|
|
|
28
28
|
* Called on items that are not the dragged item during drag. Updates the
|
|
29
29
|
* visual position of the item relative to the dragged item.
|
|
30
30
|
*
|
|
31
|
-
* @param
|
|
31
|
+
* @param offset {number} intended offset of the item during drag
|
|
32
32
|
*/
|
|
33
|
-
updateVisually(
|
|
34
|
-
this.row.style.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
updateVisually(offset) {
|
|
34
|
+
this.row.style.transform = `translateY(${offset - this.#offsetTop}px)`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
captureDropPosition() {
|
|
38
|
+
this.dropTop = this.#viewportTop;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
invertDropPosition() {
|
|
42
|
+
delete this.dragOffset;
|
|
43
|
+
this.row.removeAttribute("dragging");
|
|
44
|
+
this.row.style.transition = "transform 0s";
|
|
45
|
+
this.row.style.transform = "";
|
|
46
|
+
this.row.style.transform = `translateY(${this.dropTop - this.#viewportTop}px)`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
playDrop() {
|
|
50
|
+
this.row.style.transition = "";
|
|
51
|
+
this.row.style.transform = "";
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
/**
|
|
@@ -62,6 +76,7 @@ class OrderableRowController extends Controller {
|
|
|
62
76
|
*/
|
|
63
77
|
reset() {
|
|
64
78
|
delete this.dragOffset;
|
|
79
|
+
delete this.dropTop;
|
|
65
80
|
this.row.removeAttribute("style");
|
|
66
81
|
this.row.removeAttribute("dragging");
|
|
67
82
|
}
|
|
@@ -74,34 +89,15 @@ class OrderableRowController extends Controller {
|
|
|
74
89
|
}
|
|
75
90
|
|
|
76
91
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* to index caused by the drag offset.
|
|
80
|
-
*
|
|
81
|
-
* @returns {number} index for the purposes of drag and drop ordering
|
|
82
|
-
*/
|
|
83
|
-
get dragIndex() {
|
|
84
|
-
if (this.dragOffset && this.dragOffset !== 0) {
|
|
85
|
-
return this.index + Math.round(this.dragOffset / this.row.offsetHeight);
|
|
86
|
-
} else {
|
|
87
|
-
return this.index;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Index value for use in comparisons during drag. This is used to determine
|
|
93
|
-
* whether the dragged item is above or below another item. If this item is
|
|
94
|
-
* being dragged then we offset the index by 0.5 to ensure that it jumps up
|
|
95
|
-
* or down when it reaches the midpoint of the item above or below it.
|
|
92
|
+
* Value for use in comparisons during drag. Used by ListController to
|
|
93
|
+
* determine whether the dragged item is above or below another item.
|
|
96
94
|
*
|
|
97
95
|
* @returns {number}
|
|
98
96
|
*/
|
|
99
|
-
get
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return this.index;
|
|
104
|
-
}
|
|
97
|
+
get dragPosition() {
|
|
98
|
+
return this.dragOffset && this.dragOffset !== 0
|
|
99
|
+
? this.#leadingEdge
|
|
100
|
+
: this.#midpoint;
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
/**
|
|
@@ -112,6 +108,28 @@ class OrderableRowController extends Controller {
|
|
|
112
108
|
get row() {
|
|
113
109
|
return this.element.parentElement;
|
|
114
110
|
}
|
|
111
|
+
|
|
112
|
+
get height() {
|
|
113
|
+
return this.row.offsetHeight;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get #midpoint() {
|
|
117
|
+
return this.#offsetTop + this.height / 2;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get #leadingEdge() {
|
|
121
|
+
const top = this.#offsetTop + this.dragOffset;
|
|
122
|
+
|
|
123
|
+
return this.dragOffset < 0 ? top : top + this.height;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
get #offsetTop() {
|
|
127
|
+
return this.row.offsetTop;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get #viewportTop() {
|
|
131
|
+
return this.row.getBoundingClientRect().top;
|
|
132
|
+
}
|
|
115
133
|
}
|
|
116
134
|
|
|
117
135
|
function domIndex(element) {
|
|
@@ -133,7 +151,7 @@ class OrderableListController extends Controller {
|
|
|
133
151
|
this.element.style.position = "relative";
|
|
134
152
|
}
|
|
135
153
|
|
|
136
|
-
stopDragging() {
|
|
154
|
+
stopDragging({ reset = true } = {}) {
|
|
137
155
|
const dragState = this.dragState;
|
|
138
156
|
delete this.dragState;
|
|
139
157
|
|
|
@@ -142,7 +160,7 @@ class OrderableListController extends Controller {
|
|
|
142
160
|
window.removeEventListener("scroll", this.scroll, true);
|
|
143
161
|
|
|
144
162
|
this.element.removeAttribute("style");
|
|
145
|
-
this.
|
|
163
|
+
if (reset) this.items.forEach((item) => item.reset());
|
|
146
164
|
|
|
147
165
|
return dragState;
|
|
148
166
|
}
|
|
@@ -156,25 +174,30 @@ class OrderableListController extends Controller {
|
|
|
156
174
|
|
|
157
175
|
if (!dragItem) return;
|
|
158
176
|
|
|
159
|
-
const
|
|
160
|
-
|
|
177
|
+
const items = this.items;
|
|
178
|
+
items.forEach((item) => item.captureDropPosition());
|
|
161
179
|
|
|
162
|
-
|
|
180
|
+
this.#insertDragItem(this.orderedItems, dragItem);
|
|
163
181
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
targetItem.row.insertAdjacentElement("afterend", dragItem.row);
|
|
169
|
-
}
|
|
182
|
+
items.forEach((item) => item.invertDropPosition());
|
|
183
|
+
|
|
184
|
+
// Commit the inverted transforms before enabling transitions to play out.
|
|
185
|
+
this.element.offsetHeight;
|
|
170
186
|
|
|
171
187
|
// reindex all items based on their new positions
|
|
172
|
-
this.
|
|
173
|
-
item.updateIndex(index),
|
|
174
|
-
);
|
|
188
|
+
this.items.forEach((item, index) => item.updateIndex(index));
|
|
175
189
|
|
|
176
190
|
// save the changes
|
|
177
191
|
this.commitChanges();
|
|
192
|
+
|
|
193
|
+
window.requestAnimationFrame(() => {
|
|
194
|
+
items.forEach((item) => item.playDrop());
|
|
195
|
+
window.setTimeout(() => {
|
|
196
|
+
items.forEach((item) => item.reset());
|
|
197
|
+
}, this.#animationDuration);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return true;
|
|
178
201
|
}
|
|
179
202
|
|
|
180
203
|
commitChanges() {
|
|
@@ -182,7 +205,7 @@ class OrderableListController extends Controller {
|
|
|
182
205
|
this.tablesOrderableFormOutlet.clear();
|
|
183
206
|
|
|
184
207
|
// insert any items that have changed position
|
|
185
|
-
this.
|
|
208
|
+
this.items.forEach((item) => {
|
|
186
209
|
if (item.hasChanges) this.tablesOrderableFormOutlet.add(item);
|
|
187
210
|
});
|
|
188
211
|
|
|
@@ -245,9 +268,9 @@ class OrderableListController extends Controller {
|
|
|
245
268
|
mouseup = (event) => {
|
|
246
269
|
if (!this.isDragging) return;
|
|
247
270
|
|
|
248
|
-
this.drop();
|
|
249
|
-
this.stopDragging();
|
|
250
|
-
this.
|
|
271
|
+
const dropped = this.drop();
|
|
272
|
+
this.stopDragging({ reset: !dropped });
|
|
273
|
+
this.items.forEach((form) => delete form.dragState);
|
|
251
274
|
};
|
|
252
275
|
|
|
253
276
|
tablesOrderableFormOutletConnected(form, element) {
|
|
@@ -290,9 +313,11 @@ class OrderableListController extends Controller {
|
|
|
290
313
|
|
|
291
314
|
// Visually updates the position of all items in the list relative to the
|
|
292
315
|
// dragged item. No actual changes to orderings at this stage.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
316
|
+
let nextOffset = 0;
|
|
317
|
+
|
|
318
|
+
this.orderedItems.forEach((item) => {
|
|
319
|
+
if (item !== dragItem) item.updateVisually(nextOffset);
|
|
320
|
+
nextOffset += item.height;
|
|
296
321
|
});
|
|
297
322
|
};
|
|
298
323
|
|
|
@@ -303,23 +328,30 @@ class OrderableListController extends Controller {
|
|
|
303
328
|
get dragItem() {
|
|
304
329
|
if (!this.isDragging) return null;
|
|
305
330
|
|
|
306
|
-
return this.
|
|
307
|
-
(item) => item.id === this.dragState.targetId,
|
|
308
|
-
);
|
|
331
|
+
return this.items.find((item) => item.id === this.dragState.targetId);
|
|
309
332
|
}
|
|
310
333
|
|
|
311
334
|
/**
|
|
312
|
-
* Returns the current items in the list
|
|
313
|
-
* Current uses the drag index if the item is being dragged, if set.
|
|
335
|
+
* Returns the current items in the list in DOM order.
|
|
314
336
|
*
|
|
315
337
|
* @returns {Array[OrderableRowController]}
|
|
316
338
|
*/
|
|
317
|
-
get
|
|
318
|
-
|
|
319
|
-
|
|
339
|
+
get items() {
|
|
340
|
+
// Note, item outlets may include other items as the outlets do not have a
|
|
341
|
+
// mechanism to specify an element scope.
|
|
342
|
+
return this.tablesOrderableItemOutlets.filter((item) =>
|
|
343
|
+
this.element.contains(item.element),
|
|
320
344
|
);
|
|
321
345
|
}
|
|
322
346
|
|
|
347
|
+
get orderedItems() {
|
|
348
|
+
const dragItem = this.dragItem;
|
|
349
|
+
|
|
350
|
+
if (!dragItem) return this.items;
|
|
351
|
+
|
|
352
|
+
return this.items.toSorted((a, b) => a.dragPosition - b.dragPosition);
|
|
353
|
+
}
|
|
354
|
+
|
|
323
355
|
/**
|
|
324
356
|
* Returns the item outlet that was clicked on, if any.
|
|
325
357
|
*
|
|
@@ -327,14 +359,42 @@ class OrderableListController extends Controller {
|
|
|
327
359
|
* @returns {OrderableRowController}
|
|
328
360
|
*/
|
|
329
361
|
#targetItem(element) {
|
|
330
|
-
return this.
|
|
331
|
-
|
|
332
|
-
|
|
362
|
+
return this.items.find((item) => item.element === element);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
#insertDragItem(orderedItems, dragItem) {
|
|
366
|
+
const index = orderedItems.indexOf(dragItem);
|
|
367
|
+
const previousItem = orderedItems[index - 1];
|
|
368
|
+
const nextItem = orderedItems[index + 1];
|
|
369
|
+
|
|
370
|
+
if (previousItem) {
|
|
371
|
+
previousItem.row.insertAdjacentElement("afterend", dragItem.row);
|
|
372
|
+
} else if (nextItem) {
|
|
373
|
+
nextItem.row.insertAdjacentElement("beforebegin", dragItem.row);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
get #animationDuration() {
|
|
378
|
+
const duration =
|
|
379
|
+
window
|
|
380
|
+
.getComputedStyle(this.element)
|
|
381
|
+
.getPropertyValue("--animation-duration") || "150ms";
|
|
382
|
+
|
|
383
|
+
return parseTime(duration);
|
|
333
384
|
}
|
|
334
385
|
|
|
335
386
|
//endregion
|
|
336
387
|
}
|
|
337
388
|
|
|
389
|
+
function parseTime(value) {
|
|
390
|
+
value = value.trim();
|
|
391
|
+
|
|
392
|
+
if (value.endsWith("ms")) return parseFloat(value);
|
|
393
|
+
if (value.endsWith("s")) return parseFloat(value) * 1000;
|
|
394
|
+
|
|
395
|
+
return parseFloat(value) || 0;
|
|
396
|
+
}
|
|
397
|
+
|
|
338
398
|
/**
|
|
339
399
|
* During drag we want to be able to translate a document-relative coordinate
|
|
340
400
|
* into a coordinate relative to the list element. This state object calculates
|
|
@@ -19,7 +19,7 @@ class OrderableRowController extends Controller {
|
|
|
19
19
|
dragUpdate(offset) {
|
|
20
20
|
this.dragOffset = offset;
|
|
21
21
|
this.row.style.position = "relative";
|
|
22
|
-
this.row.style.
|
|
22
|
+
this.row.style.transform = `scale(1.01) translateY(${offset}px)`;
|
|
23
23
|
this.row.style.zIndex = "1";
|
|
24
24
|
this.row.toggleAttribute("dragging", true);
|
|
25
25
|
}
|
|
@@ -28,13 +28,27 @@ class OrderableRowController extends Controller {
|
|
|
28
28
|
* Called on items that are not the dragged item during drag. Updates the
|
|
29
29
|
* visual position of the item relative to the dragged item.
|
|
30
30
|
*
|
|
31
|
-
* @param
|
|
31
|
+
* @param offset {number} intended offset of the item during drag
|
|
32
32
|
*/
|
|
33
|
-
updateVisually(
|
|
34
|
-
this.row.style.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
updateVisually(offset) {
|
|
34
|
+
this.row.style.transform = `translateY(${offset - this.#offsetTop}px)`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
captureDropPosition() {
|
|
38
|
+
this.dropTop = this.#viewportTop;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
invertDropPosition() {
|
|
42
|
+
delete this.dragOffset;
|
|
43
|
+
this.row.removeAttribute("dragging");
|
|
44
|
+
this.row.style.transition = "transform 0s";
|
|
45
|
+
this.row.style.transform = "";
|
|
46
|
+
this.row.style.transform = `translateY(${this.dropTop - this.#viewportTop}px)`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
playDrop() {
|
|
50
|
+
this.row.style.transition = "";
|
|
51
|
+
this.row.style.transform = "";
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
/**
|
|
@@ -62,6 +76,7 @@ class OrderableRowController extends Controller {
|
|
|
62
76
|
*/
|
|
63
77
|
reset() {
|
|
64
78
|
delete this.dragOffset;
|
|
79
|
+
delete this.dropTop;
|
|
65
80
|
this.row.removeAttribute("style");
|
|
66
81
|
this.row.removeAttribute("dragging");
|
|
67
82
|
}
|
|
@@ -74,34 +89,15 @@ class OrderableRowController extends Controller {
|
|
|
74
89
|
}
|
|
75
90
|
|
|
76
91
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* to index caused by the drag offset.
|
|
80
|
-
*
|
|
81
|
-
* @returns {number} index for the purposes of drag and drop ordering
|
|
82
|
-
*/
|
|
83
|
-
get dragIndex() {
|
|
84
|
-
if (this.dragOffset && this.dragOffset !== 0) {
|
|
85
|
-
return this.index + Math.round(this.dragOffset / this.row.offsetHeight);
|
|
86
|
-
} else {
|
|
87
|
-
return this.index;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Index value for use in comparisons during drag. This is used to determine
|
|
93
|
-
* whether the dragged item is above or below another item. If this item is
|
|
94
|
-
* being dragged then we offset the index by 0.5 to ensure that it jumps up
|
|
95
|
-
* or down when it reaches the midpoint of the item above or below it.
|
|
92
|
+
* Value for use in comparisons during drag. Used by ListController to
|
|
93
|
+
* determine whether the dragged item is above or below another item.
|
|
96
94
|
*
|
|
97
95
|
* @returns {number}
|
|
98
96
|
*/
|
|
99
|
-
get
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return this.index;
|
|
104
|
-
}
|
|
97
|
+
get dragPosition() {
|
|
98
|
+
return this.dragOffset && this.dragOffset !== 0
|
|
99
|
+
? this.#leadingEdge
|
|
100
|
+
: this.#midpoint;
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
/**
|
|
@@ -112,6 +108,28 @@ class OrderableRowController extends Controller {
|
|
|
112
108
|
get row() {
|
|
113
109
|
return this.element.parentElement;
|
|
114
110
|
}
|
|
111
|
+
|
|
112
|
+
get height() {
|
|
113
|
+
return this.row.offsetHeight;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get #midpoint() {
|
|
117
|
+
return this.#offsetTop + this.height / 2;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get #leadingEdge() {
|
|
121
|
+
const top = this.#offsetTop + this.dragOffset;
|
|
122
|
+
|
|
123
|
+
return this.dragOffset < 0 ? top : top + this.height;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
get #offsetTop() {
|
|
127
|
+
return this.row.offsetTop;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get #viewportTop() {
|
|
131
|
+
return this.row.getBoundingClientRect().top;
|
|
132
|
+
}
|
|
115
133
|
}
|
|
116
134
|
|
|
117
135
|
function domIndex(element) {
|
|
@@ -133,7 +151,7 @@ class OrderableListController extends Controller {
|
|
|
133
151
|
this.element.style.position = "relative";
|
|
134
152
|
}
|
|
135
153
|
|
|
136
|
-
stopDragging() {
|
|
154
|
+
stopDragging({ reset = true } = {}) {
|
|
137
155
|
const dragState = this.dragState;
|
|
138
156
|
delete this.dragState;
|
|
139
157
|
|
|
@@ -142,7 +160,7 @@ class OrderableListController extends Controller {
|
|
|
142
160
|
window.removeEventListener("scroll", this.scroll, true);
|
|
143
161
|
|
|
144
162
|
this.element.removeAttribute("style");
|
|
145
|
-
this.
|
|
163
|
+
if (reset) this.items.forEach((item) => item.reset());
|
|
146
164
|
|
|
147
165
|
return dragState;
|
|
148
166
|
}
|
|
@@ -156,25 +174,30 @@ class OrderableListController extends Controller {
|
|
|
156
174
|
|
|
157
175
|
if (!dragItem) return;
|
|
158
176
|
|
|
159
|
-
const
|
|
160
|
-
|
|
177
|
+
const items = this.items;
|
|
178
|
+
items.forEach((item) => item.captureDropPosition());
|
|
161
179
|
|
|
162
|
-
|
|
180
|
+
this.#insertDragItem(this.orderedItems, dragItem);
|
|
163
181
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
targetItem.row.insertAdjacentElement("afterend", dragItem.row);
|
|
169
|
-
}
|
|
182
|
+
items.forEach((item) => item.invertDropPosition());
|
|
183
|
+
|
|
184
|
+
// Commit the inverted transforms before enabling transitions to play out.
|
|
185
|
+
this.element.offsetHeight;
|
|
170
186
|
|
|
171
187
|
// reindex all items based on their new positions
|
|
172
|
-
this.
|
|
173
|
-
item.updateIndex(index),
|
|
174
|
-
);
|
|
188
|
+
this.items.forEach((item, index) => item.updateIndex(index));
|
|
175
189
|
|
|
176
190
|
// save the changes
|
|
177
191
|
this.commitChanges();
|
|
192
|
+
|
|
193
|
+
window.requestAnimationFrame(() => {
|
|
194
|
+
items.forEach((item) => item.playDrop());
|
|
195
|
+
window.setTimeout(() => {
|
|
196
|
+
items.forEach((item) => item.reset());
|
|
197
|
+
}, this.#animationDuration);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return true;
|
|
178
201
|
}
|
|
179
202
|
|
|
180
203
|
commitChanges() {
|
|
@@ -182,7 +205,7 @@ class OrderableListController extends Controller {
|
|
|
182
205
|
this.tablesOrderableFormOutlet.clear();
|
|
183
206
|
|
|
184
207
|
// insert any items that have changed position
|
|
185
|
-
this.
|
|
208
|
+
this.items.forEach((item) => {
|
|
186
209
|
if (item.hasChanges) this.tablesOrderableFormOutlet.add(item);
|
|
187
210
|
});
|
|
188
211
|
|
|
@@ -245,9 +268,9 @@ class OrderableListController extends Controller {
|
|
|
245
268
|
mouseup = (event) => {
|
|
246
269
|
if (!this.isDragging) return;
|
|
247
270
|
|
|
248
|
-
this.drop();
|
|
249
|
-
this.stopDragging();
|
|
250
|
-
this.
|
|
271
|
+
const dropped = this.drop();
|
|
272
|
+
this.stopDragging({ reset: !dropped });
|
|
273
|
+
this.items.forEach((form) => delete form.dragState);
|
|
251
274
|
};
|
|
252
275
|
|
|
253
276
|
tablesOrderableFormOutletConnected(form, element) {
|
|
@@ -290,9 +313,11 @@ class OrderableListController extends Controller {
|
|
|
290
313
|
|
|
291
314
|
// Visually updates the position of all items in the list relative to the
|
|
292
315
|
// dragged item. No actual changes to orderings at this stage.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
316
|
+
let nextOffset = 0;
|
|
317
|
+
|
|
318
|
+
this.orderedItems.forEach((item) => {
|
|
319
|
+
if (item !== dragItem) item.updateVisually(nextOffset);
|
|
320
|
+
nextOffset += item.height;
|
|
296
321
|
});
|
|
297
322
|
};
|
|
298
323
|
|
|
@@ -303,23 +328,30 @@ class OrderableListController extends Controller {
|
|
|
303
328
|
get dragItem() {
|
|
304
329
|
if (!this.isDragging) return null;
|
|
305
330
|
|
|
306
|
-
return this.
|
|
307
|
-
(item) => item.id === this.dragState.targetId,
|
|
308
|
-
);
|
|
331
|
+
return this.items.find((item) => item.id === this.dragState.targetId);
|
|
309
332
|
}
|
|
310
333
|
|
|
311
334
|
/**
|
|
312
|
-
* Returns the current items in the list
|
|
313
|
-
* Current uses the drag index if the item is being dragged, if set.
|
|
335
|
+
* Returns the current items in the list in DOM order.
|
|
314
336
|
*
|
|
315
337
|
* @returns {Array[OrderableRowController]}
|
|
316
338
|
*/
|
|
317
|
-
get
|
|
318
|
-
|
|
319
|
-
|
|
339
|
+
get items() {
|
|
340
|
+
// Note, item outlets may include other items as the outlets do not have a
|
|
341
|
+
// mechanism to specify an element scope.
|
|
342
|
+
return this.tablesOrderableItemOutlets.filter((item) =>
|
|
343
|
+
this.element.contains(item.element),
|
|
320
344
|
);
|
|
321
345
|
}
|
|
322
346
|
|
|
347
|
+
get orderedItems() {
|
|
348
|
+
const dragItem = this.dragItem;
|
|
349
|
+
|
|
350
|
+
if (!dragItem) return this.items;
|
|
351
|
+
|
|
352
|
+
return this.items.toSorted((a, b) => a.dragPosition - b.dragPosition);
|
|
353
|
+
}
|
|
354
|
+
|
|
323
355
|
/**
|
|
324
356
|
* Returns the item outlet that was clicked on, if any.
|
|
325
357
|
*
|
|
@@ -327,14 +359,42 @@ class OrderableListController extends Controller {
|
|
|
327
359
|
* @returns {OrderableRowController}
|
|
328
360
|
*/
|
|
329
361
|
#targetItem(element) {
|
|
330
|
-
return this.
|
|
331
|
-
|
|
332
|
-
|
|
362
|
+
return this.items.find((item) => item.element === element);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
#insertDragItem(orderedItems, dragItem) {
|
|
366
|
+
const index = orderedItems.indexOf(dragItem);
|
|
367
|
+
const previousItem = orderedItems[index - 1];
|
|
368
|
+
const nextItem = orderedItems[index + 1];
|
|
369
|
+
|
|
370
|
+
if (previousItem) {
|
|
371
|
+
previousItem.row.insertAdjacentElement("afterend", dragItem.row);
|
|
372
|
+
} else if (nextItem) {
|
|
373
|
+
nextItem.row.insertAdjacentElement("beforebegin", dragItem.row);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
get #animationDuration() {
|
|
378
|
+
const duration =
|
|
379
|
+
window
|
|
380
|
+
.getComputedStyle(this.element)
|
|
381
|
+
.getPropertyValue("--animation-duration") || "150ms";
|
|
382
|
+
|
|
383
|
+
return parseTime(duration);
|
|
333
384
|
}
|
|
334
385
|
|
|
335
386
|
//endregion
|
|
336
387
|
}
|
|
337
388
|
|
|
389
|
+
function parseTime(value) {
|
|
390
|
+
value = value.trim();
|
|
391
|
+
|
|
392
|
+
if (value.endsWith("ms")) return parseFloat(value);
|
|
393
|
+
if (value.endsWith("s")) return parseFloat(value) * 1000;
|
|
394
|
+
|
|
395
|
+
return parseFloat(value) || 0;
|
|
396
|
+
}
|
|
397
|
+
|
|
338
398
|
/**
|
|
339
399
|
* During drag we want to be able to translate a document-relative coordinate
|
|
340
400
|
* into a coordinate relative to the list element. This state object calculates
|