ember-sortable 2.3.0 → 3.0.1

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.
Files changed (36) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +2 -2
  2. package/.github/workflows/github_ci.yml +15 -13
  3. package/CHANGELOG.md +229 -107
  4. package/MIGRATION_GUIDE_MODIFIERS.md +20 -13
  5. package/MIGRATION_GUIDE_V2.md +20 -8
  6. package/README.md +75 -152
  7. package/V2_MIGRATION_RFC.md +188 -222
  8. package/addon/modifiers/sortable-group.js +48 -50
  9. package/addon/modifiers/sortable-handle.js +16 -18
  10. package/addon/modifiers/sortable-item.js +104 -77
  11. package/addon/services/ember-sortable.js +3 -6
  12. package/addon/system/scroll-parent.js +1 -1
  13. package/addon/utils/coordinate.js +1 -1
  14. package/addon/utils/css-calculation.js +2 -2
  15. package/addon/utils/defaults.js +4 -3
  16. package/addon/utils/keyboard.js +3 -12
  17. package/addon-test-support/helpers/drag.js +3 -11
  18. package/addon-test-support/helpers/index.js +1 -4
  19. package/addon-test-support/helpers/reorder.js +4 -6
  20. package/addon-test-support/utils/keyboard.js +3 -12
  21. package/addon-test-support/utils/offset.js +6 -6
  22. package/config/environment.js +2 -2
  23. package/index.js +0 -20
  24. package/package.json +34 -20
  25. package/addon/components/sortable-group.js +0 -741
  26. package/addon/components/sortable-handle.js +0 -30
  27. package/addon/components/sortable-item.js +0 -770
  28. package/addon/styles/components/sortable-group.css +0 -9
  29. package/addon/templates/components/sortable-group.hbs +0 -16
  30. package/addon/templates/components/sortable-handle.hbs +0 -1
  31. package/addon/templates/components/sortable-item.hbs +0 -2
  32. package/addon/utils/transitionend.js +0 -22
  33. package/app/components/sortable-group.js +0 -3
  34. package/app/components/sortable-handle.js +0 -4
  35. package/app/components/sortable-item.js +0 -3
  36. package/vendor/polyfills/closest.js +0 -21
@@ -1,5 +1,7 @@
1
+ /* eslint-disable ember/no-computed-properties-in-native-classes */
2
+ /* eslint-disable ember/no-incorrect-calls-with-inline-anonymous-functions */
1
3
  import Modifier from 'ember-modifier';
2
- import {action, computed, set} from '@ember/object';
4
+ import { action, computed, set } from '@ember/object';
3
5
  import {
4
6
  isDownArrowKey,
5
7
  isEnterKey,
@@ -7,12 +9,12 @@ import {
7
9
  isLeftArrowKey,
8
10
  isRightArrowKey,
9
11
  isSpaceKey,
10
- isUpArrowKey
11
- } from "../utils/keyboard";
12
- import {ANNOUNCEMENT_ACTION_TYPES} from "../utils/constant";
13
- import { defaultA11yAnnouncementConfig } from "../utils/defaults";
14
- import { run } from '@ember/runloop';
15
- import {inject as service} from '@ember/service';
12
+ isUpArrowKey,
13
+ } from '../utils/keyboard';
14
+ import { ANNOUNCEMENT_ACTION_TYPES } from '../utils/constant';
15
+ import { defaultA11yAnnouncementConfig } from '../utils/defaults';
16
+ import { next, schedule, scheduleOnce, later } from '@ember/runloop';
17
+ import { inject as service } from '@ember/service';
16
18
 
17
19
  const NO_MODEL = {};
18
20
 
@@ -37,7 +39,6 @@ const NO_MODEL = {};
37
39
  * </ol>
38
40
  */
39
41
  export default class SortableGroupModifier extends Modifier {
40
-
41
42
  /** Primary keyboard utils */
42
43
  // Tracks the currently selected item
43
44
  _selectedItem = null;
@@ -91,7 +92,7 @@ export default class SortableGroupModifier extends Modifier {
91
92
  }
92
93
 
93
94
  get itemVisualClass() {
94
- return this.args.named.itemVisualClass || "is-activated";
95
+ return this.args.named.itemVisualClass || 'is-activated';
95
96
  }
96
97
 
97
98
  get a11yItemName() {
@@ -140,7 +141,7 @@ export default class SortableGroupModifier extends Modifier {
140
141
 
141
142
  this.isRetainingFocus = true;
142
143
 
143
- run.scheduleOnce('render', () => {
144
+ scheduleOnce('render', () => {
144
145
  this.element.focus();
145
146
  this.isRetainingFocus = false;
146
147
  });
@@ -179,7 +180,7 @@ export default class SortableGroupModifier extends Modifier {
179
180
 
180
181
  // switch direction values to notify sortedItems to update, so it sorts by direction.
181
182
  let value;
182
- const dimension = direction === "y" ? "height" : "width";
183
+ const dimension = direction === 'y' ? 'height' : 'width';
183
184
  // DOWN or RIGHT
184
185
  if (toIndex > fromIndex) {
185
186
  value = item[direction];
@@ -206,13 +207,13 @@ export default class SortableGroupModifier extends Modifier {
206
207
  const direction = this.direction;
207
208
  const selectedItem = this._selectedItem;
208
209
 
209
- if (direction === "y" && isDownArrowKey(event)) {
210
+ if (direction === 'y' && isDownArrowKey(event)) {
210
211
  this.moveItem(selectedItem, 1);
211
- } else if (direction === "y" && isUpArrowKey(event)) {
212
+ } else if (direction === 'y' && isUpArrowKey(event)) {
212
213
  this.moveItem(selectedItem, -1);
213
- } else if (direction === "x" && isLeftArrowKey(event)) {
214
+ } else if (direction === 'x' && isLeftArrowKey(event)) {
214
215
  this.moveItem(selectedItem, -1);
215
- } else if (direction === "x" && isRightArrowKey(event)) {
216
+ } else if (direction === 'x' && isRightArrowKey(event)) {
216
217
  this.moveItem(selectedItem, 1);
217
218
  } else if (isEnterKey(event) || isSpaceKey(event)) {
218
219
  // confirm will reset the selectedItem, so caching it here before we remove it.
@@ -221,7 +222,7 @@ export default class SortableGroupModifier extends Modifier {
221
222
  this.confirmKeyboardSelection();
222
223
 
223
224
  this.isRetainingFocus = true;
224
- run.scheduleOnce('render', () => this._focusItem(itemElement));
225
+ scheduleOnce('render', () => this._focusItem(itemElement));
225
226
  } else if (isEscapeKey(event)) {
226
227
  // cancel will reset the selectedItem, so caching it here before we remove it.
227
228
  const _selectedItemElement = selectedItem.element;
@@ -229,11 +230,11 @@ export default class SortableGroupModifier extends Modifier {
229
230
  this.cancelKeyboardSelection();
230
231
 
231
232
  this.isRetainingFocus = true;
232
- run.scheduleOnce('render', () => {
233
+ scheduleOnce('render', () => {
233
234
  const moves = this.moves;
234
235
  if (moves && moves.length > 0) {
235
236
  const sortedItems = this.sortedItems;
236
- const itemElement = sortedItems[moves[0].fromIndex].element
237
+ const itemElement = sortedItems[moves[0].fromIndex].element;
237
238
  this._focusItem(itemElement);
238
239
  } else {
239
240
  this._focusItem(_selectedItemElement);
@@ -262,7 +263,7 @@ export default class SortableGroupModifier extends Modifier {
262
263
  }
263
264
  this._announceAction(ANNOUNCEMENT_ACTION_TYPES.MOVE, delta);
264
265
  // Guarantees that the before the UI is fully rendered before we move again.
265
- run.scheduleOnce('render', () => {
266
+ scheduleOnce('render', () => {
266
267
  this._move(sortedIndex, newSortedIndex);
267
268
  this._updateHandleVisualIndicators(item, true);
268
269
 
@@ -285,7 +286,7 @@ export default class SortableGroupModifier extends Modifier {
285
286
  const moves = this.moves;
286
287
  while (moves.length > 0) {
287
288
  const move = moves.pop();
288
- this._move(move[1], move[0])
289
+ this._move(move[1], move[0]);
289
290
  }
290
291
  this._tearDownA11yApplicationContainer();
291
292
  this._updateItemVisualIndicators(_selectedItem, false);
@@ -306,7 +307,7 @@ export default class SortableGroupModifier extends Modifier {
306
307
  this.moves = [];
307
308
  this._disableKeyboardReorderMode();
308
309
  this._tearDownA11yApplicationContainer();
309
- set(_selectedItem, "wasDropped", true);
310
+ set(_selectedItem, 'wasDropped', true);
310
311
  this.commit();
311
312
  this._updateItemVisualIndicators(_selectedItem, false);
312
313
  this._updateHandleVisualIndicators(_selectedItem, false);
@@ -335,7 +336,7 @@ export default class SortableGroupModifier extends Modifier {
335
336
  const config = {
336
337
  a11yItemName,
337
338
  index: index,
338
- maxLength : sortedItems.length,
339
+ maxLength: sortedItems.length,
339
340
  direction: this.direction,
340
341
  delta,
341
342
  };
@@ -344,7 +345,7 @@ export default class SortableGroupModifier extends Modifier {
344
345
  announcer.textContent = message;
345
346
 
346
347
  // Reset the message after the message is announced.
347
- run.later(() => {
348
+ later(() => {
348
349
  announcer.textContent = '';
349
350
  }, 1000);
350
351
  }
@@ -363,7 +364,6 @@ export default class SortableGroupModifier extends Modifier {
363
364
  * @param {Boolean} isActive to activate or deactivate the class.
364
365
  */
365
366
  _updateItemVisualIndicators(item, isActive) {
366
-
367
367
  const itemVisualClass = this.itemVisualClass;
368
368
 
369
369
  if (!itemVisualClass || !item) {
@@ -397,7 +397,7 @@ export default class SortableGroupModifier extends Modifier {
397
397
  const visualHandle = handle ? handle : item.element;
398
398
  const visualKeys = direction === 'y' ? ['UP', 'DOWN'] : ['LEFT', 'RIGHT'];
399
399
 
400
- visualKeys.forEach(visualKey => {
400
+ visualKeys.forEach((visualKey) => {
401
401
  visualHandle.classList.remove(handleVisualClass[visualKey]);
402
402
  });
403
403
 
@@ -447,7 +447,7 @@ export default class SortableGroupModifier extends Modifier {
447
447
  * Sets up the group as an application and make it programmatically focusable.
448
448
  */
449
449
  _setupA11yApplicationContainer() {
450
- this.element.setAttribute("role", "application");
450
+ this.element.setAttribute('role', 'application');
451
451
  this.element.tabIndex = -1;
452
452
  }
453
453
 
@@ -455,8 +455,8 @@ export default class SortableGroupModifier extends Modifier {
455
455
  * Tears down the `role=application` container.
456
456
  */
457
457
  _tearDownA11yApplicationContainer() {
458
- this.element.removeAttribute("role");
459
- this.element.removeAttribute("tabIndex");
458
+ this.element.removeAttribute('role');
459
+ this.element.removeAttribute('tabIndex');
460
460
  }
461
461
 
462
462
  _prepareKeyboardReorderMode() {
@@ -472,7 +472,7 @@ export default class SortableGroupModifier extends Modifier {
472
472
  @default y
473
473
  */
474
474
  get direction() {
475
- return this.args.named.direction || "y";
475
+ return this.args.named.direction || 'y';
476
476
  }
477
477
 
478
478
  /**
@@ -499,7 +499,7 @@ export default class SortableGroupModifier extends Modifier {
499
499
  * @returns {*|string}
500
500
  */
501
501
  get groupName() {
502
- return this.args.named.groupName || "_EmberSortableGroup";
502
+ return this.args.named.groupName || '_EmberSortableGroup';
503
503
  }
504
504
 
505
505
  _groupDef = this.sortableService.fetchGroup(this.groupName);
@@ -530,7 +530,7 @@ export default class SortableGroupModifier extends Modifier {
530
530
  @property firstItemPosition
531
531
  @type Number
532
532
  */
533
- @computed("direction", "sortedItems")
533
+ @computed('direction', 'sortedItems')
534
534
  get firstItemPosition() {
535
535
  const direction = this.direction;
536
536
  const sortedItems = this.sortedItems;
@@ -552,7 +552,7 @@ export default class SortableGroupModifier extends Modifier {
552
552
  * Enables keyboard navigation
553
553
  */
554
554
  @action
555
- activateKeyDown(selectedItem){
555
+ activateKeyDown(selectedItem) {
556
556
  this._selectedItem = selectedItem;
557
557
  this.isKeyDownEnabled = true;
558
558
  }
@@ -616,7 +616,7 @@ export default class SortableGroupModifier extends Modifier {
616
616
  position = this.firstItemPosition;
617
617
  }
618
618
 
619
- sortedItems.forEach(item => {
619
+ sortedItems.forEach((item) => {
620
620
  let dimension;
621
621
  let direction = this.direction;
622
622
 
@@ -646,8 +646,8 @@ export default class SortableGroupModifier extends Modifier {
646
646
  @action
647
647
  commit() {
648
648
  const items = this.sortedItems;
649
- const itemModels = items.map(item => item.model);
650
- const draggedItem = items.find(item => item.wasDropped);
649
+ const itemModels = items.map((item) => item.model);
650
+ const draggedItem = items.find((item) => item.wasDropped);
651
651
  let draggedModel;
652
652
 
653
653
  if (draggedItem) {
@@ -675,17 +675,17 @@ export default class SortableGroupModifier extends Modifier {
675
675
 
676
676
  delete this._firstItemPosition;
677
677
 
678
- run.schedule('render', () => {
679
- items.forEach(item => item.freeze());
678
+ schedule('render', () => {
679
+ items.forEach((item) => item.freeze());
680
680
  });
681
681
 
682
- run.schedule('afterRender', () => {
683
- items.forEach(item => item.reset());
682
+ schedule('afterRender', () => {
683
+ items.forEach((item) => item.reset());
684
684
  });
685
685
 
686
- run.next(() => {
687
- run.schedule('render', () => {
688
- items.forEach(item => item.thaw());
686
+ next(() => {
687
+ schedule('render', () => {
688
+ items.forEach((item) => item.thaw());
689
689
  });
690
690
  });
691
691
  }
@@ -701,13 +701,13 @@ export default class SortableGroupModifier extends Modifier {
701
701
  // end of API
702
702
 
703
703
  addEventListener() {
704
- this.element.addEventListener("keydown", this.keyDown);
705
- this.element.addEventListener("focusout", this.focusOut);
704
+ this.element.addEventListener('keydown', this.keyDown);
705
+ this.element.addEventListener('focusout', this.focusOut);
706
706
  }
707
707
 
708
708
  removeEventListener() {
709
- this.element.removeEventListener("keydown", this.keyDown);
710
- this.element.removeEventListener("focusout", this.focusOut);
709
+ this.element.removeEventListener('keydown', this.keyDown);
710
+ this.element.removeEventListener('focusout', this.focusOut);
711
711
  }
712
712
 
713
713
  didReceiveArguments() {
@@ -720,8 +720,7 @@ export default class SortableGroupModifier extends Modifier {
720
720
  this.addEventListener();
721
721
  }
722
722
 
723
- didUpdateArguments() {
724
- }
723
+ didUpdateArguments() {}
725
724
 
726
725
  didInstall() {
727
726
  this.announcer = this._createAnnouncer();
@@ -732,12 +731,11 @@ export default class SortableGroupModifier extends Modifier {
732
731
 
733
732
  willRemove() {
734
733
  // todo cleanup the announcer
735
- if(this.announcer.parentNode) {
734
+ if (this.announcer.parentNode) {
736
735
  this.announcer.parentNode.removeChild(this.announcer);
737
736
  }
738
737
  this.removeEventListener();
739
738
 
740
739
  this.sortableService.deregisterGroup(this.groupName, this);
741
740
  }
742
-
743
741
  }
@@ -1,26 +1,24 @@
1
1
  import Modifier from 'ember-modifier';
2
2
 
3
3
  /**
4
- * Modifier to to mark the handle of an item. If this is not supplied the item will be the handle
5
- *
6
- * @module drag-drop/draggable-group
7
- * @example*
8
- * <ol {{sortable-group onChange=this.update a11yAnnouncementConfig=this.myA11yConfig}}>
9
- * {{#each model.items as |item|}}
10
- * <li {{sortable-item model=item}}>
11
- * {{item.name}}
12
- * <span class="handle" {{sortable-handle}}>&varr;</span>
13
- * </li>
14
- * {{/each}}
15
- * </ol>
16
- */
4
+ * Modifier to to mark the handle of an item. If this is not supplied the item will be the handle
5
+ *
6
+ * @module drag-drop/draggable-group
7
+ * @example*
8
+ * <ol {{sortable-group onChange=this.update a11yAnnouncementConfig=this.myA11yConfig}}>
9
+ * {{#each model.items as |item|}}
10
+ * <li {{sortable-item model=item}}>
11
+ * {{item.name}}
12
+ * <span class="handle" {{sortable-handle}}>&varr;</span>
13
+ * </li>
14
+ * {{/each}}
15
+ * </ol>
16
+ */
17
17
  export default class SortableHandleModifier extends Modifier {
18
-
19
18
  didInstall() {
20
19
  // take the model and look up the registered element, the tell that element you are the handle
21
- this.element.dataset.sortableHandle=true;
22
- this.element.tabIndex = "0";
23
- this.element.setAttribute("role", "button");
20
+ this.element.dataset.sortableHandle = true;
21
+ this.element.tabIndex = '0';
22
+ this.element.setAttribute('role', 'button');
24
23
  }
25
-
26
24
  }