ember-sortable 2.2.5 → 3.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/.github/ISSUE_TEMPLATE/bug_report.md +2 -2
- package/.github/workflows/github_ci.yml +15 -13
- package/.huskyrc +0 -1
- package/CHANGELOG.md +234 -104
- package/MIGRATION_GUIDE_MODIFIERS.md +20 -13
- package/MIGRATION_GUIDE_V2.md +20 -8
- package/README.md +83 -149
- package/V2_MIGRATION_RFC.md +188 -222
- package/addon/modifiers/sortable-group.js +59 -52
- package/addon/modifiers/sortable-handle.js +16 -18
- package/addon/modifiers/sortable-item.js +124 -84
- package/addon/services/ember-sortable.js +3 -6
- package/addon/system/scroll-parent.js +1 -1
- package/addon/utils/coordinate.js +1 -1
- package/addon/utils/css-calculation.js +2 -2
- package/addon/utils/defaults.js +4 -3
- package/addon/utils/keyboard.js +3 -12
- package/addon-test-support/helpers/drag.js +3 -11
- package/addon-test-support/helpers/index.js +1 -4
- package/addon-test-support/helpers/reorder.js +4 -6
- package/addon-test-support/utils/keyboard.js +3 -12
- package/addon-test-support/utils/offset.js +6 -6
- package/config/environment.js +2 -2
- package/index.js +0 -20
- package/package.json +32 -18
- package/addon/components/sortable-group.js +0 -726
- package/addon/components/sortable-handle.js +0 -11
- package/addon/components/sortable-item.js +0 -753
- package/addon/styles/components/sortable-group.css +0 -9
- package/addon/templates/components/sortable-group.hbs +0 -16
- package/addon/templates/components/sortable-handle.hbs +0 -1
- package/addon/templates/components/sortable-item.hbs +0 -2
- package/addon/utils/transitionend.js +0 -22
- package/app/components/sortable-group.js +0 -3
- package/app/components/sortable-handle.js +0 -4
- package/app/components/sortable-item.js +0 -3
- package/jsconfig.json +0 -1
- package/vendor/polyfills/closest.js +0 -21
|
@@ -1,29 +1,29 @@
|
|
|
1
|
+
/* eslint-disable ember/no-computed-properties-in-native-classes */
|
|
1
2
|
import Modifier from 'ember-modifier';
|
|
2
3
|
import { Promise, defer } from 'rsvp';
|
|
3
|
-
import {action, set} from '@ember/object';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {DRAG_ACTIONS, ELEMENT_CLICK_ACTION, END_ACTIONS} from "../utils/constant";
|
|
7
|
-
import { run, throttle } from '@ember/runloop';
|
|
4
|
+
import { action, set } from '@ember/object';
|
|
5
|
+
import { DRAG_ACTIONS, ELEMENT_CLICK_ACTION, END_ACTIONS } from '../utils/constant';
|
|
6
|
+
import { run, throttle, bind, scheduleOnce, later } from '@ember/runloop';
|
|
8
7
|
import { DEBUG } from '@glimmer/env';
|
|
9
|
-
import {getX, getY} from
|
|
10
|
-
import ScrollContainer from
|
|
11
|
-
import scrollParent from
|
|
12
|
-
import {getBorderSpacing} from
|
|
8
|
+
import { getX, getY } from '../utils/coordinate';
|
|
9
|
+
import ScrollContainer from '../system/scroll-container';
|
|
10
|
+
import scrollParent from '../system/scroll-parent';
|
|
11
|
+
import { getBorderSpacing } from '../utils/css-calculation';
|
|
13
12
|
import { buildWaiter } from '@ember/test-waiters';
|
|
14
|
-
import {inject as service} from '@ember/service';
|
|
15
|
-
import {assert} from '@ember/debug';
|
|
13
|
+
import { inject as service } from '@ember/service';
|
|
14
|
+
import { assert, deprecate } from '@ember/debug';
|
|
16
15
|
import config from 'ember-get-config';
|
|
16
|
+
|
|
17
17
|
const { environment } = config;
|
|
18
18
|
const isTesting = environment === 'test';
|
|
19
19
|
|
|
20
|
-
const sortableItemWaiter = buildWaiter(
|
|
20
|
+
const sortableItemWaiter = buildWaiter('sortable-item-waiter');
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Modifier to mark an element as an item to be reordered
|
|
24
24
|
*
|
|
25
25
|
* @param {Object} model The model that this item will represent
|
|
26
|
-
* @param {boolean} [
|
|
26
|
+
* @param {boolean} [disabled=false] Set to true to make this item not sortable
|
|
27
27
|
* @param {Function} [onDragStart] An optional callback for when dragging starts.
|
|
28
28
|
* @param {Function} [onDragStop] An optional callback for when dragging stops.
|
|
29
29
|
*
|
|
@@ -39,8 +39,9 @@ const sortableItemWaiter = buildWaiter("sortable-item-waiter");
|
|
|
39
39
|
* </ol>
|
|
40
40
|
*/
|
|
41
41
|
export default class SortableItemModifier extends Modifier {
|
|
42
|
+
className = 'sortable-item';
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
@service('ember-sortable@ember-sortable') sortableService;
|
|
44
45
|
|
|
45
46
|
_sortableGroup;
|
|
46
47
|
/**
|
|
@@ -52,19 +53,25 @@ export default class SortableItemModifier extends Modifier {
|
|
|
52
53
|
get sortableGroup() {
|
|
53
54
|
if (this._sortableGroup === undefined) {
|
|
54
55
|
this._sortableGroup = this.sortableService.fetchGroup(this.groupName);
|
|
55
|
-
assert(
|
|
56
|
+
assert(
|
|
57
|
+
`No sortable group named ${this.groupName} found. Please check that the groups and items have the same groupName`,
|
|
58
|
+
this._sortableGroup !== undefined
|
|
59
|
+
);
|
|
56
60
|
}
|
|
57
61
|
return this._sortableGroup.groupModifier;
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
get model() {
|
|
65
|
+
return this.args.named.model;
|
|
66
|
+
}
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
get direction() {
|
|
69
|
+
return this.sortableGroup.direction;
|
|
70
|
+
}
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
get groupDisabled() {
|
|
73
|
+
return this.sortableGroup.disabled;
|
|
74
|
+
}
|
|
68
75
|
|
|
69
76
|
/**
|
|
70
77
|
* This is the group name used to keep groups separate if there are more than one on the screen at a time.
|
|
@@ -74,7 +81,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
74
81
|
* @returns {*|string}
|
|
75
82
|
*/
|
|
76
83
|
get groupName() {
|
|
77
|
-
return this.args.named.groupName ||
|
|
84
|
+
return this.args.named.groupName || '_EmberSortableGroup';
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
/**
|
|
@@ -99,13 +106,28 @@ export default class SortableItemModifier extends Modifier {
|
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
/**
|
|
102
|
-
Removes the ability for the current item to be
|
|
103
|
-
@property
|
|
109
|
+
Removes the ability for the current item to be sorted
|
|
110
|
+
@property disabled
|
|
104
111
|
@type boolean
|
|
105
112
|
@default false
|
|
106
113
|
*/
|
|
107
|
-
get
|
|
108
|
-
|
|
114
|
+
get isDisabled() {
|
|
115
|
+
deprecate(
|
|
116
|
+
'"isDraggingDisabled" is deprecated. Please migrate to "disabled" named argument',
|
|
117
|
+
!('isDraggingDisabled' in this.args.named),
|
|
118
|
+
{
|
|
119
|
+
id: 'ember-sortable.is-dragging-disabled',
|
|
120
|
+
url: 'https://github.com/adopted-ember-addons/ember-sortable#readme',
|
|
121
|
+
until: '3.0.0',
|
|
122
|
+
for: 'ember-sortable',
|
|
123
|
+
since: {
|
|
124
|
+
available: '2.2.6',
|
|
125
|
+
enabled: '2.2.6',
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return this.groupDisabled || this.args.named.disabled || this.args.named.isDraggingDisabled || false;
|
|
109
131
|
}
|
|
110
132
|
|
|
111
133
|
/**
|
|
@@ -120,7 +142,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
120
142
|
@default "[data-sortable-handle]"
|
|
121
143
|
*/
|
|
122
144
|
get handle() {
|
|
123
|
-
return this.args.named.handle ||
|
|
145
|
+
return this.args.named.handle || '[data-sortable-handle]';
|
|
124
146
|
}
|
|
125
147
|
|
|
126
148
|
handleElement;
|
|
@@ -153,9 +175,9 @@ export default class SortableItemModifier extends Modifier {
|
|
|
153
175
|
}
|
|
154
176
|
set isDragging(value) {
|
|
155
177
|
if (value) {
|
|
156
|
-
this.element.classList.add(
|
|
178
|
+
this.element.classList.add('is-dragging');
|
|
157
179
|
} else {
|
|
158
|
-
this.element.classList.remove(
|
|
180
|
+
this.element.classList.remove('is-dragging');
|
|
159
181
|
}
|
|
160
182
|
this._isDragging = value;
|
|
161
183
|
}
|
|
@@ -168,7 +190,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
168
190
|
@default null
|
|
169
191
|
*/
|
|
170
192
|
get onDragStart() {
|
|
171
|
-
return this.args.named.onDragStart || (item => item);
|
|
193
|
+
return this.args.named.onDragStart || ((item) => item);
|
|
172
194
|
}
|
|
173
195
|
|
|
174
196
|
/**
|
|
@@ -179,7 +201,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
179
201
|
@default null
|
|
180
202
|
*/
|
|
181
203
|
get onDragStop() {
|
|
182
|
-
return this.args.named.onDragStop || (item => item);
|
|
204
|
+
return this.args.named.onDragStop || ((item) => item);
|
|
183
205
|
}
|
|
184
206
|
|
|
185
207
|
/**
|
|
@@ -194,9 +216,9 @@ export default class SortableItemModifier extends Modifier {
|
|
|
194
216
|
}
|
|
195
217
|
set isDropping(value) {
|
|
196
218
|
if (value) {
|
|
197
|
-
this.element.classList.add(
|
|
219
|
+
this.element.classList.add('is-dropping');
|
|
198
220
|
} else {
|
|
199
|
-
this.element.classList.remove(
|
|
221
|
+
this.element.classList.remove('is-dropping');
|
|
200
222
|
}
|
|
201
223
|
this._isDropping = value;
|
|
202
224
|
}
|
|
@@ -213,14 +235,12 @@ export default class SortableItemModifier extends Modifier {
|
|
|
213
235
|
@property isBusy
|
|
214
236
|
@type Boolean
|
|
215
237
|
*/
|
|
216
|
-
|
|
217
|
-
|
|
238
|
+
get isBusy() {
|
|
239
|
+
return this.isDragging || this.isDropping;
|
|
240
|
+
}
|
|
218
241
|
|
|
219
242
|
/**
|
|
220
|
-
|
|
221
|
-
@property isDraggingDisabled
|
|
222
|
-
@type boolean
|
|
223
|
-
@default false
|
|
243
|
+
@property disableCheckScrollBounds
|
|
224
244
|
*/
|
|
225
245
|
get disableCheckScrollBounds() {
|
|
226
246
|
return this.args.named.disableCheckScrollBounds != undefined ? this.args.named.disableCheckScrollBounds : isTesting;
|
|
@@ -231,14 +251,22 @@ export default class SortableItemModifier extends Modifier {
|
|
|
231
251
|
*/
|
|
232
252
|
@action
|
|
233
253
|
mouseDown(event) {
|
|
234
|
-
if (event.which !== 1) {
|
|
235
|
-
|
|
254
|
+
if (event.which !== 1) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (event.ctrlKey) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
236
260
|
|
|
237
261
|
this._primeDrag(event);
|
|
238
262
|
}
|
|
239
263
|
|
|
240
264
|
@action
|
|
241
265
|
keyDown(event) {
|
|
266
|
+
if (this.isDisabled) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
242
270
|
// If the event is coming from within the item, we do not want to activate keyboard reorder mode.
|
|
243
271
|
if (event.target === this.handleElement || event.target === this.element) {
|
|
244
272
|
this.sortableGroup.activateKeyDown(this);
|
|
@@ -260,7 +288,9 @@ export default class SortableItemModifier extends Modifier {
|
|
|
260
288
|
*/
|
|
261
289
|
freeze() {
|
|
262
290
|
let el = this.element;
|
|
263
|
-
if (!el) {
|
|
291
|
+
if (!el) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
264
294
|
|
|
265
295
|
el.style.transition = 'none';
|
|
266
296
|
}
|
|
@@ -270,7 +300,9 @@ export default class SortableItemModifier extends Modifier {
|
|
|
270
300
|
*/
|
|
271
301
|
reset() {
|
|
272
302
|
let el = this.element;
|
|
273
|
-
if (!el) {
|
|
303
|
+
if (!el) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
274
306
|
|
|
275
307
|
delete this._y;
|
|
276
308
|
delete this._x;
|
|
@@ -283,7 +315,9 @@ export default class SortableItemModifier extends Modifier {
|
|
|
283
315
|
*/
|
|
284
316
|
thaw() {
|
|
285
317
|
let el = this.element;
|
|
286
|
-
if (!el) {
|
|
318
|
+
if (!el) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
287
321
|
|
|
288
322
|
el.style.transition = '';
|
|
289
323
|
}
|
|
@@ -296,8 +330,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
296
330
|
* @private
|
|
297
331
|
*/
|
|
298
332
|
_primeDrag(startEvent) {
|
|
299
|
-
|
|
300
|
-
if (this.isDraggingDisabled) {
|
|
333
|
+
if (this.isDisabled) {
|
|
301
334
|
return;
|
|
302
335
|
}
|
|
303
336
|
|
|
@@ -308,20 +341,20 @@ export default class SortableItemModifier extends Modifier {
|
|
|
308
341
|
startEvent.preventDefault();
|
|
309
342
|
startEvent.stopPropagation();
|
|
310
343
|
|
|
311
|
-
this._prepareDragListener =
|
|
344
|
+
this._prepareDragListener = bind(this, this._prepareDrag, startEvent);
|
|
312
345
|
|
|
313
|
-
DRAG_ACTIONS.forEach(event => window.addEventListener(event, this._prepareDragListener));
|
|
346
|
+
DRAG_ACTIONS.forEach((event) => window.addEventListener(event, this._prepareDragListener));
|
|
314
347
|
|
|
315
348
|
this._cancelStartDragListener = () => {
|
|
316
|
-
DRAG_ACTIONS.forEach(event => window.removeEventListener(event, this._prepareDragListener));
|
|
349
|
+
DRAG_ACTIONS.forEach((event) => window.removeEventListener(event, this._prepareDragListener));
|
|
317
350
|
};
|
|
318
351
|
|
|
319
352
|
const selfCancellingCallback = () => {
|
|
320
|
-
END_ACTIONS.forEach(event => window.removeEventListener(event, selfCancellingCallback));
|
|
353
|
+
END_ACTIONS.forEach((event) => window.removeEventListener(event, selfCancellingCallback));
|
|
321
354
|
this._cancelStartDragListener();
|
|
322
355
|
};
|
|
323
356
|
|
|
324
|
-
END_ACTIONS.forEach(event => window.addEventListener(event, selfCancellingCallback));
|
|
357
|
+
END_ACTIONS.forEach((event) => window.addEventListener(event, selfCancellingCallback));
|
|
325
358
|
}
|
|
326
359
|
|
|
327
360
|
/**
|
|
@@ -338,7 +371,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
338
371
|
let dy = Math.abs(getY(startEvent) - getY(event));
|
|
339
372
|
|
|
340
373
|
if (distance <= dx || distance <= dy) {
|
|
341
|
-
DRAG_ACTIONS.forEach(event => window.removeEventListener(event, this._prepareDragListener));
|
|
374
|
+
DRAG_ACTIONS.forEach((event) => window.removeEventListener(event, this._prepareDragListener));
|
|
342
375
|
this._startDrag(startEvent);
|
|
343
376
|
}
|
|
344
377
|
}
|
|
@@ -351,25 +384,27 @@ export default class SortableItemModifier extends Modifier {
|
|
|
351
384
|
* @private
|
|
352
385
|
*/
|
|
353
386
|
_startDrag(event) {
|
|
354
|
-
if (this.isBusy) {
|
|
387
|
+
if (this.isBusy) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
355
390
|
|
|
356
391
|
let drag = this._makeDragHandler(event);
|
|
357
|
-
let dragThrottled = ev => throttle(this, drag, ev, 16, false);
|
|
392
|
+
let dragThrottled = (ev) => throttle(this, drag, ev, 16, false);
|
|
358
393
|
|
|
359
394
|
let drop = () => {
|
|
360
|
-
DRAG_ACTIONS.forEach(event => window.removeEventListener(event, dragThrottled));
|
|
361
|
-
END_ACTIONS.forEach(event => window.removeEventListener(event, drop));
|
|
395
|
+
DRAG_ACTIONS.forEach((event) => window.removeEventListener(event, dragThrottled));
|
|
396
|
+
END_ACTIONS.forEach((event) => window.removeEventListener(event, drop));
|
|
362
397
|
|
|
363
398
|
run(() => {
|
|
364
399
|
this._drop();
|
|
365
400
|
});
|
|
366
401
|
};
|
|
367
402
|
|
|
368
|
-
DRAG_ACTIONS.forEach(event => window.addEventListener(event, dragThrottled));
|
|
369
|
-
END_ACTIONS.forEach(event => window.addEventListener(event, drop));
|
|
403
|
+
DRAG_ACTIONS.forEach((event) => window.addEventListener(event, dragThrottled));
|
|
404
|
+
END_ACTIONS.forEach((event) => window.addEventListener(event, drop));
|
|
370
405
|
|
|
371
406
|
this.sortableGroup.prepare();
|
|
372
|
-
set(this,
|
|
407
|
+
set(this, 'isDragging', true);
|
|
373
408
|
this.onDragStart(this.model);
|
|
374
409
|
this._scrollOnEdges(drag);
|
|
375
410
|
}
|
|
@@ -401,7 +436,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
401
436
|
},
|
|
402
437
|
get bottom() {
|
|
403
438
|
return this.top + this.height;
|
|
404
|
-
}
|
|
439
|
+
},
|
|
405
440
|
};
|
|
406
441
|
|
|
407
442
|
let leadingEdgeKey, trailingEdgeKey, scrollKey, pageKey;
|
|
@@ -418,12 +453,14 @@ export default class SortableItemModifier extends Modifier {
|
|
|
418
453
|
}
|
|
419
454
|
|
|
420
455
|
let createFakeEvent = () => {
|
|
421
|
-
if (this._pageX == null && this._pageY == null) {
|
|
456
|
+
if (this._pageX == null && this._pageY == null) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
422
459
|
return {
|
|
423
460
|
pageX: this._pageX,
|
|
424
461
|
pageY: this._pageY,
|
|
425
462
|
clientX: this._pageX,
|
|
426
|
-
clientY: this._pageY
|
|
463
|
+
clientY: this._pageY,
|
|
427
464
|
};
|
|
428
465
|
};
|
|
429
466
|
|
|
@@ -484,7 +521,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
484
521
|
elementOrigin = this.x;
|
|
485
522
|
scrollOrigin = parentElement.getBoundingClientRect().left;
|
|
486
523
|
|
|
487
|
-
return event => {
|
|
524
|
+
return (event) => {
|
|
488
525
|
this._pageX = getX(event);
|
|
489
526
|
let dx = this._pageX - dragOrigin;
|
|
490
527
|
let scrollX = parentElement.getBoundingClientRect().left;
|
|
@@ -499,7 +536,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
499
536
|
elementOrigin = this.y;
|
|
500
537
|
scrollOrigin = parentElement.getBoundingClientRect().top;
|
|
501
538
|
|
|
502
|
-
return event => {
|
|
539
|
+
return (event) => {
|
|
503
540
|
this._pageY = getY(event);
|
|
504
541
|
let dy = this._pageY - dragOrigin;
|
|
505
542
|
let scrollY = parentElement.getBoundingClientRect().top;
|
|
@@ -515,7 +552,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
515
552
|
@private
|
|
516
553
|
*/
|
|
517
554
|
_scheduleApplyPosition() {
|
|
518
|
-
|
|
555
|
+
scheduleOnce('render', this, '_applyPosition');
|
|
519
556
|
}
|
|
520
557
|
|
|
521
558
|
/**
|
|
@@ -523,7 +560,9 @@ export default class SortableItemModifier extends Modifier {
|
|
|
523
560
|
@private
|
|
524
561
|
*/
|
|
525
562
|
_applyPosition() {
|
|
526
|
-
if (!this.element || !this.element) {
|
|
563
|
+
if (!this.element || !this.element) {
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
527
566
|
|
|
528
567
|
const groupDirection = this.direction;
|
|
529
568
|
|
|
@@ -531,7 +570,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
531
570
|
let x = this.x;
|
|
532
571
|
let dx = x - this.element.offsetLeft + parseFloat(getComputedStyle(this.element).marginLeft);
|
|
533
572
|
|
|
534
|
-
this.element.style.transform = `translateX(${dx}px)`;
|
|
573
|
+
this.element.style.transform = `translateX(${Math.max(0, dx)}px)`;
|
|
535
574
|
}
|
|
536
575
|
if (groupDirection === 'y') {
|
|
537
576
|
let y = this.y;
|
|
@@ -546,7 +585,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
546
585
|
@private
|
|
547
586
|
*/
|
|
548
587
|
_drag(dimension) {
|
|
549
|
-
if(!this.isDragging) {
|
|
588
|
+
if (!this.isDragging) {
|
|
550
589
|
return;
|
|
551
590
|
}
|
|
552
591
|
let updateInterval = this.updateInterval;
|
|
@@ -567,14 +606,16 @@ export default class SortableItemModifier extends Modifier {
|
|
|
567
606
|
@private
|
|
568
607
|
*/
|
|
569
608
|
_drop() {
|
|
570
|
-
if (!this.element) {
|
|
609
|
+
if (!this.element) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
571
612
|
|
|
572
613
|
let transitionPromise = this._waitForTransition();
|
|
573
614
|
|
|
574
615
|
this._preventClick();
|
|
575
616
|
|
|
576
|
-
set(this,
|
|
577
|
-
set(this,
|
|
617
|
+
set(this, 'isDragging', false);
|
|
618
|
+
set(this, 'isDropping', true);
|
|
578
619
|
|
|
579
620
|
this.sortableGroup.update();
|
|
580
621
|
transitionPromise.then(() => this._complete());
|
|
@@ -625,7 +666,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
625
666
|
});
|
|
626
667
|
} else {
|
|
627
668
|
const duration = this.isAnimated ? this.transitionDuration : 200;
|
|
628
|
-
transitionPromise = new Promise((resolve) =>
|
|
669
|
+
transitionPromise = new Promise((resolve) => later(resolve, duration));
|
|
629
670
|
}
|
|
630
671
|
|
|
631
672
|
if (DEBUG) {
|
|
@@ -643,14 +684,14 @@ export default class SortableItemModifier extends Modifier {
|
|
|
643
684
|
*/
|
|
644
685
|
_complete() {
|
|
645
686
|
this.onDragStop(this.model);
|
|
646
|
-
set(this,
|
|
647
|
-
set(this,
|
|
687
|
+
set(this, 'isDropping', false);
|
|
688
|
+
set(this, 'wasDropped', true);
|
|
648
689
|
this.sortableGroup.commit();
|
|
649
690
|
}
|
|
650
691
|
|
|
651
692
|
get isAnimated() {
|
|
652
693
|
if (!this.element) {
|
|
653
|
-
return;
|
|
694
|
+
return undefined;
|
|
654
695
|
}
|
|
655
696
|
|
|
656
697
|
let el = this.element;
|
|
@@ -664,7 +705,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
664
705
|
@property transitionDuration
|
|
665
706
|
@type Number
|
|
666
707
|
*/
|
|
667
|
-
|
|
708
|
+
get transitionDuration() {
|
|
668
709
|
let el = this.element;
|
|
669
710
|
let rule = getComputedStyle(el).transitionDuration;
|
|
670
711
|
let match = rule.match(/([\d.]+)([ms]*)/);
|
|
@@ -758,15 +799,15 @@ export default class SortableItemModifier extends Modifier {
|
|
|
758
799
|
}
|
|
759
800
|
|
|
760
801
|
addEventListener() {
|
|
761
|
-
this.element.addEventListener(
|
|
762
|
-
this.element.addEventListener(
|
|
763
|
-
this.element.addEventListener(
|
|
802
|
+
this.element.addEventListener('keydown', this.keyDown);
|
|
803
|
+
this.element.addEventListener('mousedown', this.mouseDown);
|
|
804
|
+
this.element.addEventListener('touchstart', this.touchStart);
|
|
764
805
|
}
|
|
765
806
|
|
|
766
807
|
removeEventListener() {
|
|
767
|
-
this.element.removeEventListener(
|
|
768
|
-
this.element.removeEventListener(
|
|
769
|
-
this.element.removeEventListener(
|
|
808
|
+
this.element.removeEventListener('keydown', this.keyDown);
|
|
809
|
+
this.element.removeEventListener('mousedown', this.mouseDown);
|
|
810
|
+
this.element.removeEventListener('touchstart', this.touchStart);
|
|
770
811
|
}
|
|
771
812
|
|
|
772
813
|
didReceiveArguments() {
|
|
@@ -784,7 +825,7 @@ export default class SortableItemModifier extends Modifier {
|
|
|
784
825
|
|
|
785
826
|
didInstall() {
|
|
786
827
|
this.addEventListener();
|
|
787
|
-
this.element.dataset.sortableItem=true;
|
|
828
|
+
this.element.dataset.sortableItem = true;
|
|
788
829
|
this.sortableService.registerItem(this.groupName, this);
|
|
789
830
|
}
|
|
790
831
|
|
|
@@ -792,5 +833,4 @@ export default class SortableItemModifier extends Modifier {
|
|
|
792
833
|
this.removeEventListener();
|
|
793
834
|
this.sortableService.deregisterItem(this.groupName, this);
|
|
794
835
|
}
|
|
795
|
-
|
|
796
836
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Service from '@ember/service';
|
|
2
2
|
|
|
3
3
|
export default class EmberSortableService extends Service {
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
5
|
* Internal State for any groups currently in DOM
|
|
7
6
|
*
|
|
@@ -13,9 +12,7 @@ export default class EmberSortableService extends Service {
|
|
|
13
12
|
* }
|
|
14
13
|
* @type {{}}
|
|
15
14
|
*/
|
|
16
|
-
groups = {
|
|
17
|
-
|
|
18
|
-
};
|
|
15
|
+
groups = {};
|
|
19
16
|
|
|
20
17
|
/**
|
|
21
18
|
* Register a new group with the service
|
|
@@ -27,8 +24,8 @@ export default class EmberSortableService extends Service {
|
|
|
27
24
|
if (this.groups[groupName] === undefined) {
|
|
28
25
|
this.groups[groupName] = {
|
|
29
26
|
groupModifier: groupModifier,
|
|
30
|
-
items: []
|
|
31
|
-
}
|
|
27
|
+
items: [],
|
|
28
|
+
};
|
|
32
29
|
} else {
|
|
33
30
|
this.groups[groupName].groupModifier = groupModifier;
|
|
34
31
|
}
|
|
@@ -17,7 +17,7 @@ function getParentElements(element) {
|
|
|
17
17
|
export default function (element) {
|
|
18
18
|
let position = getComputedStyle(element).position;
|
|
19
19
|
let excludeStaticParent = position === 'absolute';
|
|
20
|
-
let scrollParent = getParentElements(element).filter(function(parent) {
|
|
20
|
+
let scrollParent = getParentElements(element).filter(function (parent) {
|
|
21
21
|
let parentElemStyles = getComputedStyle(parent);
|
|
22
22
|
if (excludeStaticParent && parentElemStyles.position === 'static') {
|
|
23
23
|
return false;
|
package/addon/utils/defaults.js
CHANGED
|
@@ -4,8 +4,7 @@ export const defaultA11yAnnouncementConfig = {
|
|
|
4
4
|
|
|
5
5
|
if (direction === 'y') {
|
|
6
6
|
message += 'Press up and down keys to change position,';
|
|
7
|
-
}
|
|
8
|
-
else {
|
|
7
|
+
} else {
|
|
9
8
|
message += 'Press left and right keys to change position,';
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -14,7 +13,9 @@ export const defaultA11yAnnouncementConfig = {
|
|
|
14
13
|
return message;
|
|
15
14
|
},
|
|
16
15
|
MOVE({ a11yItemName, index, maxLength, delta }) {
|
|
17
|
-
return `${a11yItemName} is moved to position, ${
|
|
16
|
+
return `${a11yItemName} is moved to position, ${
|
|
17
|
+
index + 1 + delta
|
|
18
|
+
} of ${maxLength}. Press Space to confirm new position, Escape to cancel.`;
|
|
18
19
|
},
|
|
19
20
|
CONFIRM({ a11yItemName }) {
|
|
20
21
|
return `${a11yItemName} is successfully repositioned.`;
|
package/addon/utils/keyboard.js
CHANGED
|
@@ -26,16 +26,7 @@ function createKeyTest(key, keyCode) {
|
|
|
26
26
|
export const isEnterKey = createKeyTest(ENTER_KEY, ENTER_KEY_CODE);
|
|
27
27
|
export const isEscapeKey = createKeyTest(ESCAPE_KEY, ESCAPE_KEY_CODE);
|
|
28
28
|
export const isSpaceKey = createKeyTest(SPACE_KEY, SPACE_KEY_CODE);
|
|
29
|
-
export const isLeftArrowKey = createKeyTest(
|
|
30
|
-
ARROW_KEYS.LEFT,
|
|
31
|
-
ARROW_KEY_CODES.LEFT
|
|
32
|
-
);
|
|
29
|
+
export const isLeftArrowKey = createKeyTest(ARROW_KEYS.LEFT, ARROW_KEY_CODES.LEFT);
|
|
33
30
|
export const isUpArrowKey = createKeyTest(ARROW_KEYS.UP, ARROW_KEY_CODES.UP);
|
|
34
|
-
export const isRightArrowKey = createKeyTest(
|
|
35
|
-
|
|
36
|
-
ARROW_KEY_CODES.RIGHT
|
|
37
|
-
);
|
|
38
|
-
export const isDownArrowKey = createKeyTest(
|
|
39
|
-
ARROW_KEYS.DOWN,
|
|
40
|
-
ARROW_KEY_CODES.DOWN
|
|
41
|
-
);
|
|
31
|
+
export const isRightArrowKey = createKeyTest(ARROW_KEYS.RIGHT, ARROW_KEY_CODES.RIGHT);
|
|
32
|
+
export const isDownArrowKey = createKeyTest(ARROW_KEYS.DOWN, ARROW_KEY_CODES.DOWN);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { triggerEvent, find, settled
|
|
1
|
+
import { triggerEvent, find, settled } from '@ember/test-helpers';
|
|
2
2
|
import { getOffset } from '../utils/offset';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -26,12 +26,7 @@ import { getOffset } from '../utils/offset';
|
|
|
26
26
|
@return {Promise}
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
export async function drag(
|
|
30
|
-
mode,
|
|
31
|
-
itemSelector,
|
|
32
|
-
offsetFn,
|
|
33
|
-
callbacks = {}
|
|
34
|
-
) {
|
|
29
|
+
export async function drag(mode, itemSelector, offsetFn, callbacks = {}) {
|
|
35
30
|
let start;
|
|
36
31
|
let move;
|
|
37
32
|
let end;
|
|
@@ -62,10 +57,7 @@ export async function drag(
|
|
|
62
57
|
// https://stackoverflow.com/a/5042051
|
|
63
58
|
const dx = offset.dx || 0;
|
|
64
59
|
const dy = offset.dy || 0;
|
|
65
|
-
const clientHeight =
|
|
66
|
-
itemElement.clientHeight ||
|
|
67
|
-
itemElement.offsetHeight ||
|
|
68
|
-
itemElement.parentNode.offsetHeight;
|
|
60
|
+
const clientHeight = itemElement.clientHeight || itemElement.offsetHeight || itemElement.parentNode.offsetHeight;
|
|
69
61
|
const scale = clientHeight / (rect.bottom - rect.top);
|
|
70
62
|
const halfwayX = itemOffset.left + (dx * scale) / 2;
|
|
71
63
|
const halfwayY = itemOffset.top + (dy * scale) / 2;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { find, findAll } from '@ember/test-helpers';
|
|
2
2
|
import { drag } from './drag';
|
|
3
3
|
import { getOffset } from '../utils/offset';
|
|
4
|
-
|
|
5
|
-
In tests, the dummy app is rendered at half size.
|
|
6
|
-
To avoid rounding errors, we must therefore double
|
|
7
|
-
the overshoot.
|
|
8
|
-
*/
|
|
4
|
+
|
|
9
5
|
const OVERSHOOT = 2;
|
|
10
6
|
|
|
11
7
|
/**
|
|
@@ -38,6 +34,8 @@ export async function reorder(mode, itemSelector, ...resultSelectors) {
|
|
|
38
34
|
const dx = getOffset(targetElement).left - OVERSHOOT - getOffset(sourceElement).left;
|
|
39
35
|
const dy = getOffset(targetElement).top - OVERSHOOT - getOffset(sourceElement).top;
|
|
40
36
|
|
|
41
|
-
await drag(mode, sourceElement, () => {
|
|
37
|
+
await drag(mode, sourceElement, () => {
|
|
38
|
+
return { dx: dx, dy: dy };
|
|
39
|
+
});
|
|
42
40
|
}
|
|
43
41
|
}
|