katalyst-tables 2.2.3 → 2.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8224ebb910f428c3f7750ae6e79c92f21440f5546a2baaede473bb286f217a82
4
- data.tar.gz: 6be02c8a263dda22b7faae734cb20e8cec5879db532adb50f257bd502fa51265
3
+ metadata.gz: 450377488700ebc511da5b3d515c217811ef60ce631df86edf62778ef8a3c5c9
4
+ data.tar.gz: 90040f0e73ad2858fd6b683b8046c9726d6a9223676edafc555dadf3e416e97b
5
5
  SHA512:
6
- metadata.gz: 61052d361a93ab2675274f9ed3b3f59e0acd08519261cf016c4db55006097d72f78114ba489e5eed9d066a82aa6bbaa9dd00675d378e24c996a5ccba775bce75
7
- data.tar.gz: e411c014472cd5d34338ad0a02d869d69352fd4c6abe70c68ead05d75b3d2f0f52bf11c263031cd6606d27d09c7565e76770eee0b9149b58ef5e91ec383d86bf
6
+ metadata.gz: 65cb752a4d5ad8620572f123f960b8378e31b5775b34b84bcc7787cd5d89234a5fee3ef2e5d850d19a4c422278aaed74eab8fddf254a92445c11d1e9f17296af
7
+ data.tar.gz: c72888fbed46322cc3adf8bb4a562079699ccacea0fac36a8b85879ddf4378c252f7090c35206b4ac0e7696b2d67e7baadd455c279be9e813efc81103efe7724
@@ -5,16 +5,22 @@ export default class OrderableRowController extends Controller {
5
5
  params: Object,
6
6
  };
7
7
 
8
+ connect() {
9
+ // index from server may be inconsistent with the visual ordering,
10
+ // especially if this is a new node. Use positional indexes instead,
11
+ // as these are the values we will send on save.
12
+ this.index = domIndex(this.row);
13
+ }
14
+
8
15
  paramsValueChanged(params) {
9
16
  this.id = params.id_value;
10
- this.index = params.index_value;
11
17
  }
12
18
 
13
19
  dragUpdate(offset) {
14
20
  this.dragOffset = offset;
15
21
  this.row.style.position = "relative";
16
22
  this.row.style.top = offset + "px";
17
- this.row.style.zIndex = 1;
23
+ this.row.style.zIndex = "1";
18
24
  this.row.toggleAttribute("dragging", true);
19
25
  }
20
26
 
@@ -98,3 +104,7 @@ export default class OrderableRowController extends Controller {
98
104
  return this.element.parentElement;
99
105
  }
100
106
  }
107
+
108
+ function domIndex(element) {
109
+ return Array.from(element.parentElement.children).indexOf(element);
110
+ }
@@ -10,6 +10,7 @@ export default class OrderableListController extends Controller {
10
10
 
11
11
  document.addEventListener("mousemove", this.mousemove);
12
12
  document.addEventListener("mouseup", this.mouseup);
13
+ window.addEventListener("scroll", this.scroll, true);
13
14
 
14
15
  this.element.style.position = "relative";
15
16
  }
@@ -20,6 +21,7 @@ export default class OrderableListController extends Controller {
20
21
 
21
22
  document.removeEventListener("mousemove", this.mousemove);
22
23
  document.removeEventListener("mouseup", this.mouseup);
24
+ window.removeEventListener("scroll", this.scroll, true);
23
25
 
24
26
  this.element.removeAttribute("style");
25
27
  this.tablesOrderableItemOutlets.forEach((item) => item.reset());
@@ -84,7 +86,7 @@ export default class OrderableListController extends Controller {
84
86
 
85
87
  this.startDragging(new DragState(this.element, event, target.id));
86
88
 
87
- this.#updateDragItem(event);
89
+ this.dragState.updateCursor(this.element, target.row, event, this.animate);
88
90
  }
89
91
 
90
92
  mousemove = (event) => {
@@ -92,13 +94,33 @@ export default class OrderableListController extends Controller {
92
94
 
93
95
  event.preventDefault(); // prevent build-in drag
94
96
 
95
- const dragItem = this.#updateDragItem(event);
97
+ if (this.ticking) return;
96
98
 
97
- // Visually updates the position of all items in the list relative to the
98
- // dragged item. No actual changes to orderings at this stage.
99
- this.#currentItems.forEach((item, index) => {
100
- if (item === dragItem) return;
101
- item.updateVisually(index);
99
+ this.ticking = true;
100
+
101
+ window.requestAnimationFrame(() => {
102
+ this.ticking = false;
103
+ this.dragState.updateCursor(
104
+ this.element,
105
+ this.dragItem.row,
106
+ event,
107
+ this.animate,
108
+ );
109
+ });
110
+ };
111
+
112
+ scroll = (event) => {
113
+ if (!this.isDragging || this.ticking) return;
114
+
115
+ this.ticking = true;
116
+
117
+ window.requestAnimationFrame(() => {
118
+ this.ticking = false;
119
+ this.dragState.updateScroll(
120
+ this.element,
121
+ this.dragItem.row,
122
+ this.animate,
123
+ );
102
124
  });
103
125
  };
104
126
 
@@ -128,6 +150,27 @@ export default class OrderableListController extends Controller {
128
150
 
129
151
  //region Helpers
130
152
 
153
+ /**
154
+ * Updates the position of the drag item with a relative offset. Updates
155
+ * other items relative to the new position of the drag item, as required.
156
+ *
157
+ * @callback {OrderableListController~animate}
158
+ * @param {number} offset
159
+ */
160
+ animate = (offset) => {
161
+ const dragItem = this.dragItem;
162
+
163
+ // Visually update the dragItem so it follows the cursor
164
+ dragItem.dragUpdate(offset);
165
+
166
+ // Visually updates the position of all items in the list relative to the
167
+ // dragged item. No actual changes to orderings at this stage.
168
+ this.#currentItems.forEach((item, index) => {
169
+ if (item === dragItem) return;
170
+ item.updateVisually(index);
171
+ });
172
+ };
173
+
131
174
  get isDragging() {
132
175
  return !!this.dragState;
133
176
  }
@@ -155,7 +198,7 @@ export default class OrderableListController extends Controller {
155
198
  /**
156
199
  * Returns the item outlet that was clicked on, if any.
157
200
  *
158
- * @param event {HTMLElement} the clicked ordinal cell
201
+ * @param element {HTMLElement} the clicked ordinal cell
159
202
  * @returns {OrderableRowController}
160
203
  */
161
204
  #targetItem(element) {
@@ -164,17 +207,6 @@ export default class OrderableListController extends Controller {
164
207
  );
165
208
  }
166
209
 
167
- #updateDragItem(event) {
168
- const offset = this.dragState.itemOffset(
169
- this.element,
170
- this.dragItem.row,
171
- event,
172
- );
173
- const item = this.dragItem;
174
- item.dragUpdate(offset);
175
- return item;
176
- }
177
-
178
210
  //endregion
179
211
  }
180
212
 
@@ -195,23 +227,11 @@ class DragState {
195
227
  * @param id {String} the id of the element being dragged
196
228
  */
197
229
  constructor(list, event, id) {
198
- // calculate the offset top of the tbody element relative to offsetParent
199
- const offsetParent = list.offsetParent;
200
- let offsetTop = event.offsetY;
201
- let current = event.target;
202
- while (current && current !== offsetParent) {
203
- offsetTop += current.offsetTop;
204
- current = current.offsetParent;
205
- }
206
-
207
- // page offset is the offset of the tbody element relative to the page
208
- this.pageOffset = event.pageY - offsetTop + list.offsetTop;
209
-
210
230
  // cursor offset is the offset of the cursor relative to the drag item
211
231
  this.cursorOffset = event.offsetY;
212
232
 
213
233
  // initial offset is the offset position of the drag item at drag start
214
- this.initialOffset = event.target.offsetTop - list.offsetTop;
234
+ this.initialPosition = event.target.offsetTop - list.offsetTop;
215
235
 
216
236
  // id of the item being dragged
217
237
  this.targetId = id;
@@ -223,25 +243,62 @@ class DragState {
223
243
  * @param list {HTMLElement} the list controller's element (tbody)
224
244
  * @param row {HTMLElement} the row being dragged
225
245
  * @param event {MouseEvent} the current event
226
- * @returns {number} relative offset for the item being dragged
246
+ * @param callback {OrderableListController~animate} updates the drag item with a relative offset
227
247
  */
228
- itemOffset(list, row, event) {
229
- // cursor position relative to the list
230
- const cursorPosition = event.pageY - this.pageOffset;
248
+ updateCursor(list, row, event, callback) {
249
+ // Calculate and store the list offset relative to the viewport
250
+ // This value is cached so we can calculate the outcome of any scroll events
251
+ this.listOffset = list.getBoundingClientRect().top;
252
+
253
+ // Calculate the position of the cursor relative to the list.
254
+ // Accounts for scroll offsets by using the item's bounding client rect.
255
+ const cursorPosition = event.clientY - this.listOffset;
231
256
 
232
- // item position relative to the list
257
+ // intended item position relative to the list, from cursor position
233
258
  let itemPosition = cursorPosition - this.cursorOffset;
234
259
 
260
+ this.#updateItemPosition(list, row, itemPosition, callback);
261
+ }
262
+
263
+ /**
264
+ * Animates the item's position as the list scrolls. Requires a previous call
265
+ * to set the scroll offset.
266
+ *
267
+ * @param list {HTMLElement} the list controller's element (tbody)
268
+ * @param row {HTMLElement} the row being dragged
269
+ * @param callback {OrderableListController~animate} updates the drag item with a relative offset
270
+ */
271
+ updateScroll(list, row, callback) {
272
+ const previousScrollOffset = this.listOffset;
273
+
274
+ // Calculate and store the list offset relative to the viewport
275
+ // This value is cached so we can calculate the outcome of any scroll events
276
+ this.listOffset = list.getBoundingClientRect().top;
277
+
278
+ // Calculate the change in scroll offset since the last update
279
+ const scrollDelta = previousScrollOffset - this.listOffset;
280
+
281
+ // intended item position relative to the list, from cursor position
282
+ const position = this.position + scrollDelta;
283
+
284
+ this.#updateItemPosition(list, row, position, callback);
285
+ }
286
+
287
+ #updateItemPosition(list, row, position, callback) {
235
288
  // ensure itemPosition is within the bounds of the list (tbody)
236
- itemPosition = Math.max(itemPosition, 0);
237
- itemPosition = Math.min(itemPosition, list.offsetHeight - row.offsetHeight);
289
+ position = Math.max(position, 0);
290
+ position = Math.min(position, list.offsetHeight - row.offsetHeight);
291
+
292
+ // cache the item's position relative to the list for use in scroll events
293
+ this.position = position;
238
294
 
239
295
  // Item has position: relative, so we want to calculate the amount to move
240
296
  // the item relative to it's DOM position to represent how much it has been
241
297
  // dragged by.
298
+ const offset = position - this.initialPosition;
242
299
 
243
300
  // Convert itemPosition from offset relative to list to offset relative to
244
301
  // its position within the DOM (if it hadn't moved).
245
- return itemPosition - this.initialOffset;
302
+ callback(offset);
246
303
  }
247
304
  }
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Katalyst
4
4
  module Tables
5
- VERSION = "2.2.3"
5
+ VERSION = "2.2.4"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katalyst-tables
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katalyst Interactive