ember-sortable 5.4.0 → 5.5.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.
@@ -102,7 +102,7 @@ export default class SortableGroupModifier<T> extends Modifier<SortableGroupModi
102
102
  *
103
103
  * @param {Event} event a DOM event.
104
104
  */
105
- focusOut(): void;
105
+ focusOut: () => void;
106
106
  /**
107
107
  * Explanation
108
108
  * 1. `KeyboardReorderMode` is disabled: users can activate it via ENTER or SPACE.
@@ -112,7 +112,7 @@ export default class SortableGroupModifier<T> extends Modifier<SortableGroupModi
112
112
  *
113
113
  * @param {Event} event a DOM event
114
114
  */
115
- keyDown(event: KeyboardEvent): void;
115
+ keyDown: (event: KeyboardEvent) => void;
116
116
  /**
117
117
  * Checks if the given element is a child of a handle.
118
118
  *
@@ -150,7 +150,7 @@ export default class SortableGroupModifier<T> extends Modifier<SortableGroupModi
150
150
  * 3. Tears down the application container, so we are not focus locked within the application.
151
151
  * 4. Resets the current selected item.
152
152
  */
153
- cancelKeyboardSelection(): void;
153
+ cancelKeyboardSelection: () => void;
154
154
  /**
155
155
  * Handles all th necessary operations needed for confirming the current keyboard selection.
156
156
  * 1. Disables keyboard reorder mode.
@@ -247,6 +247,10 @@ export default class SortableGroupModifier<T> extends Modifier<SortableGroupModi
247
247
  * @type {Element}
248
248
  */
249
249
  announcer: Element | null;
250
+ /**
251
+ * Pending timer that resets the announcer message
252
+ */
253
+ _announcerResetTimer?: ReturnType<typeof setTimeout>;
250
254
  /**
251
255
  Position for the first item.
252
256
  If spacing is present, first item's position will have to change as well.
@@ -263,50 +267,50 @@ export default class SortableGroupModifier<T> extends Modifier<SortableGroupModi
263
267
  /**
264
268
  * Enables keyboard navigation
265
269
  */
266
- activateKeyDown(selectedItem: SortableItemModifier<T>): void;
270
+ activateKeyDown: (selectedItem: SortableItemModifier<T>) => void;
267
271
  /**
268
272
  * Disables keyboard navigation
269
273
  * Currently used to handle keydown events bubbling up from
270
274
  * elements that aren't meant to invoke keyboard navigation
271
275
  * by ignoring them.
272
276
  */
273
- deactivateKeyDown(): void;
277
+ deactivateKeyDown: () => void;
274
278
  /**
275
279
  Register the group with this Sortable.
276
280
  @method registerGroup
277
281
  @param {SortableGroupModifier} group
278
282
  */
279
- registerGroup(group: SortableGroupModifier<T>): void;
283
+ registerGroup: (group: SortableGroupModifier<T>) => void;
280
284
  /**
281
285
  De-register the group with this Sortable.
282
286
  @method deregisterGroup
283
287
  @param {SortableGroupModifier} group
284
288
  */
285
- deregisterGroup(group: SortableGroupModifier<T>): void;
289
+ deregisterGroup: (group: SortableGroupModifier<T>) => void;
286
290
  /**
287
291
  Prepare for sorting.
288
292
  Main purpose is to stash the current firstItemPosition so
289
293
  we don’t incur expensive re-layouts.
290
294
  @method _prepare
291
295
  */
292
- prepare(): void;
296
+ prepare: () => void;
293
297
  /**
294
298
  Update item positions (relatively to the first element position).
295
299
  @method update
296
300
  @param {SortableItemModifier[]} sortedItems
297
301
  */
298
- update(sortedItems: SortableItemModifier<T>[]): void;
302
+ update: (sortedItems: SortableItemModifier<T>[]) => void;
299
303
  /**
300
304
  @method _commit
301
305
  */
302
- commit(): void;
303
- _onChange(itemModels: T[], draggedModel: T | undefined): void;
306
+ commit: () => void;
307
+ _onChange: (itemModels: T[], draggedModel: T | undefined) => void;
304
308
  /**
305
309
  * Keeps the UI in sync with actual changes.
306
310
  * Needed for drag and keyboard operations.
307
311
  */
308
312
  _updateItems(): void;
309
- _createAnnouncer(): HTMLSpanElement;
313
+ _createAnnouncer: () => HTMLSpanElement;
310
314
  _calculateGridPosition(a: SortableItemModifier<T>, b: SortableItemModifier<T>, groupWidth: number): {
311
315
  ax: number;
312
316
  ay: number;
@@ -191,12 +191,12 @@ export default class SortableItemModifier<T> extends Modifier<SortableItemModifi
191
191
  /**
192
192
  @method mouseDown
193
193
  */
194
- mouseDown(event: MouseEvent): void;
195
- keyDown(event: Event): void;
194
+ mouseDown: (event: MouseEvent) => void;
195
+ keyDown: (event: Event) => void;
196
196
  /**
197
197
  @method touchStart
198
198
  */
199
- touchStart(event: TouchEvent): void;
199
+ touchStart: (event: TouchEvent) => void;
200
200
  /**
201
201
  @method freeze
202
202
  */
@@ -22,15 +22,15 @@ function _initializerDefineProperty(e, i, r, l) {
22
22
  value: r.initializer ? r.initializer.call(l) : void 0
23
23
  });
24
24
  }
25
- function _toPrimitive(t, r) {
25
+ function _toPrimitive(t, e) {
26
26
  if ("object" != typeof t || !t) return t;
27
- var e = t[Symbol.toPrimitive];
28
- if (void 0 !== e) {
29
- var i = e.call(t, r || "default");
27
+ var r;
28
+ if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) {
29
+ var i = r.call(t, e || "default");
30
30
  if ("object" != typeof i) return i;
31
31
  throw new TypeError("@@toPrimitive must return a primitive value.");
32
32
  }
33
- return ("string" === r ? String : Number)(t);
33
+ return ("string" === e ? String : Number)(t);
34
34
  }
35
35
  function _toPropertyKey(t) {
36
36
  var i = _toPrimitive(t, "string");
@@ -38,4 +38,4 @@ function _toPropertyKey(t) {
38
38
  }
39
39
 
40
40
  export { _applyDecoratedDescriptor as _, _defineProperty as a, _initializerDefineProperty as b };
41
- //# sourceMappingURL=_rollupPluginBabelHelpers-a7bede49.js.map
41
+ //# sourceMappingURL=_rollupPluginBabelHelpers-060f9720.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_rollupPluginBabelHelpers-060f9720.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,15 +1,14 @@
1
- import { _ as _applyDecoratedDescriptor, a as _defineProperty, b as _initializerDefineProperty } from '../_rollupPluginBabelHelpers-a7bede49.js';
1
+ import { _ as _applyDecoratedDescriptor, a as _defineProperty, b as _initializerDefineProperty } from '../_rollupPluginBabelHelpers-060f9720.js';
2
2
  import Modifier from 'ember-modifier';
3
- import { computed, action, set } from '@ember/object';
4
- import { isEnterKey, isSpaceKey, isDownArrowKey, isUpArrowKey, isLeftArrowKey, isRightArrowKey, isEscapeKey } from '../utils/keyboard.js';
3
+ import { isDownArrowKey, isUpArrowKey, isLeftArrowKey, isRightArrowKey, isEnterKey, isSpaceKey, isEscapeKey } from '../utils/keyboard.js';
5
4
  import { ANNOUNCEMENT_ACTION_TYPES } from '../utils/constant.js';
6
5
  import { getGap } from '../utils/css-calculation.js';
7
6
  import { defaultA11yAnnouncementConfig } from '../utils/defaults.js';
8
- import { scheduleOnce, later, schedule, next } from '@ember/runloop';
7
+ import { scheduleOnce, schedule, next } from '@ember/runloop';
9
8
  import * as s from '@ember/service';
10
9
  import { isDestroyed, registerDestructor } from '@ember/destroyable';
11
10
 
12
- var _dec, _dec2, _class, _descriptor;
11
+ var _dec, _class, _descriptor;
13
12
  const service = s.service ?? s.inject;
14
13
 
15
14
  // Tolerance for the grid direction's wrap check, absorbing residual
@@ -36,7 +35,7 @@ const NO_MODEL = {};
36
35
  * {{/each}}
37
36
  * </ol>
38
37
  */
39
- let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _dec2 = computed('direction', 'sortedItems'), _class = class SortableGroupModifier extends Modifier {
38
+ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _class = class SortableGroupModifier extends Modifier {
40
39
  /** End of keyboard utils */
41
40
 
42
41
  get disabled() {
@@ -89,52 +88,6 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
89
88
  *
90
89
  * @param {Event} event a DOM event.
91
90
  */
92
- focusOut() {
93
- if (!this.isRetainingFocus && !this._isElementWithinHandle(document.activeElement)) {
94
- this.cancelKeyboardSelection();
95
- }
96
- }
97
-
98
- /**
99
- * Explanation
100
- * 1. `KeyboardReorderMode` is disabled: users can activate it via ENTER or SPACE.
101
- * 2. `KeyboardReorderMode` is enabled: users can reorder via UP or DOWN arrow keys. TODO: Expand to more keys, e.g LEFT, RIGHT
102
- * 3. `KeyboardReorderMode` is enabled: users can finalize/save the reordering via ENTER or SPACE.
103
- * 4. `KeyboardReorderMode` is enabled: users can discard the reordering via ESC.
104
- *
105
- * @param {Event} event a DOM event
106
- */
107
- keyDown(event) {
108
- if (!this.isKeyDownEnabled) {
109
- return;
110
- }
111
-
112
- // Note: If handle is specified, we need to target the keyDown on the handle
113
- const isKeyboardReorderModeEnabled = this.isKeyboardReorderModeEnabled;
114
- if (!isKeyboardReorderModeEnabled && (isEnterKey(event) || isSpaceKey(event))) {
115
- const _selectedItem = this._selectedItem;
116
- if (!_selectedItem) {
117
- return;
118
- }
119
- this._prepareKeyboardReorderMode();
120
- this._announceAction(ANNOUNCEMENT_ACTION_TYPES.ACTIVATE);
121
- this._updateItemVisualIndicators(_selectedItem, true);
122
- this._updateHandleVisualIndicators(_selectedItem, true);
123
- this.isRetainingFocus = true;
124
- scheduleOnce('render', this, () => {
125
- this.element.focus();
126
- this.isRetainingFocus = false;
127
- });
128
-
129
- // Prevent the default scroll
130
- event.preventDefault();
131
- return;
132
- }
133
- if (isKeyboardReorderModeEnabled) {
134
- this._handleKeyboardReorder(event);
135
- event.preventDefault();
136
- }
137
- }
138
91
 
139
92
  /**
140
93
  * Checks if the given element is a child of a handle.
@@ -174,8 +127,8 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
174
127
  nextItem.y = valueY;
175
128
  } else {
176
129
  value = item[direction];
177
- set(item, direction, nextItem[direction] + (nextItem[dimension] - item[dimension]));
178
- set(nextItem, direction, value);
130
+ item[direction] = nextItem[direction] + (nextItem[dimension] - item[dimension]);
131
+ nextItem[direction] = value;
179
132
  }
180
133
  // UP or LEFT
181
134
  } else {
@@ -188,8 +141,8 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
188
141
  item.y = valueY;
189
142
  } else {
190
143
  value = nextItem[direction];
191
- set(nextItem, direction, item[direction] + (item[dimension] - nextItem[dimension]));
192
- set(item, direction, value);
144
+ nextItem[direction] = item[direction] + (item[dimension] - nextItem[dimension]);
145
+ item[direction] = value;
193
146
  }
194
147
  }
195
148
  }
@@ -279,25 +232,6 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
279
232
  * 3. Tears down the application container, so we are not focus locked within the application.
280
233
  * 4. Resets the current selected item.
281
234
  */
282
- cancelKeyboardSelection() {
283
- const _selectedItem = this._selectedItem;
284
- if (!_selectedItem) {
285
- return;
286
- }
287
- this._disableKeyboardReorderMode();
288
- // Revert the process by reversing the move.
289
- const moves = this.moves;
290
- while (moves.length > 0) {
291
- const move = moves.pop();
292
- const fromIndex = move ? move[1] : 0;
293
- const toIndex = move ? move[0] : 0;
294
- this._move(fromIndex, toIndex);
295
- }
296
- this._tearDownA11yApplicationContainer();
297
- this._updateItemVisualIndicators(_selectedItem, false);
298
- this._updateHandleVisualIndicators(_selectedItem, false);
299
- this._resetItemSelection();
300
- }
301
235
 
302
236
  /**
303
237
  * Handles all th necessary operations needed for confirming the current keyboard selection.
@@ -315,7 +249,7 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
315
249
  this.moves = [];
316
250
  this._disableKeyboardReorderMode();
317
251
  this._tearDownA11yApplicationContainer();
318
- set(_selectedItem, 'wasDropped', true);
252
+ _selectedItem.wasDropped = true;
319
253
  this.commit();
320
254
  this._updateItemVisualIndicators(_selectedItem, false);
321
255
  this._updateHandleVisualIndicators(_selectedItem, false);
@@ -352,10 +286,13 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
352
286
  delta
353
287
  };
354
288
  const message = a11yAnnouncementConfig[type](config);
289
+ // Cancel the reset of a previous message so it can't clear this one early.
290
+ clearTimeout(this._announcerResetTimer);
355
291
  announcer.textContent = message;
356
292
 
357
- // Reset the message after the message is announced.
358
- later(() => {
293
+ // Reset the message after the message is announced. A native timer is used
294
+ // so the reset doesn't hold up `settled()` in tests.
295
+ this._announcerResetTimer = setTimeout(() => {
359
296
  announcer.textContent = '';
360
297
  }, 1000);
361
298
  }
@@ -565,141 +502,6 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
565
502
  /**
566
503
  * Enables keyboard navigation
567
504
  */
568
- activateKeyDown(selectedItem) {
569
- this._selectedItem = selectedItem;
570
- this.isKeyDownEnabled = true;
571
- }
572
-
573
- /**
574
- * Disables keyboard navigation
575
- * Currently used to handle keydown events bubbling up from
576
- * elements that aren't meant to invoke keyboard navigation
577
- * by ignoring them.
578
- */
579
- deactivateKeyDown() {
580
- this.isKeyDownEnabled = false;
581
- }
582
-
583
- /**
584
- Register the group with this Sortable.
585
- @method registerGroup
586
- @param {SortableGroupModifier} group
587
- */
588
- registerGroup(group) {
589
- this._group = group;
590
- }
591
-
592
- /**
593
- De-register the group with this Sortable.
594
- @method deregisterGroup
595
- @param {SortableGroupModifier} group
596
- */
597
- deregisterGroup(group) {
598
- if (this._group === group) {
599
- this._group = null;
600
- }
601
- }
602
-
603
- /**
604
- Prepare for sorting.
605
- Main purpose is to stash the current firstItemPosition so
606
- we don’t incur expensive re-layouts.
607
- @method _prepare
608
- */
609
- prepare() {
610
- this._firstItemPosition = this.firstItemPosition;
611
- }
612
-
613
- /**
614
- Update item positions (relatively to the first element position).
615
- @method update
616
- @param {SortableItemModifier[]} sortedItems
617
- */
618
- update(sortedItems) {
619
- if (!sortedItems) {
620
- sortedItems = this.sortedItems;
621
- }
622
-
623
- // Position of the first element
624
- let axis = this._firstItemPosition;
625
-
626
- // Just in case we haven’t called prepare first.
627
- if (axis === undefined) {
628
- axis = this.firstItemPosition;
629
- }
630
- const direction = this.direction;
631
- const gap = getGap(this.element);
632
- let position = 0;
633
- let groupPositionRight = 0;
634
- let lastTopOffset = 0;
635
- let maxPrevHeight = 0;
636
- if (direction === 'grid') {
637
- position = axis.x;
638
- lastTopOffset = axis.y;
639
-
640
- // `getBoundingClientRect` instead of `getComputedStyle(...).width`,
641
- // which serializes to only 3 decimal places and can itself introduce
642
- // rounding drift against item widths.
643
- groupPositionRight = position + this.element.getBoundingClientRect().width;
644
- } else {
645
- position = axis[direction];
646
- }
647
- sortedItems.forEach(item => {
648
- if (direction === 'grid' && position + item.width > groupPositionRight + GRID_WRAP_EPSILON) {
649
- lastTopOffset = lastTopOffset + maxPrevHeight;
650
- position = axis.x;
651
- maxPrevHeight = 0;
652
- }
653
- if (!isDestroyed(item) && !item.isDragging) {
654
- // Round only at assignment to match offsetLeft/offsetTop's integer
655
- // rounding, so undragged items don't jitter by a fractional pixel.
656
- if (direction === 'grid') {
657
- item.x = Math.round(position);
658
- item.y = Math.round(lastTopOffset);
659
- } else {
660
- set(item, direction, Math.round(position));
661
- }
662
- }
663
-
664
- // add additional spacing around active element
665
- if (item.isBusy) {
666
- position += item.spacing * 2;
667
- }
668
- if (direction === 'grid') {
669
- if (item.height > maxPrevHeight) {
670
- maxPrevHeight = item.height + gap.vertical;
671
- }
672
- position += item.width + gap.horizontal;
673
- }
674
- if (direction === 'x') {
675
- position += item.width + gap.horizontal;
676
- }
677
- if (direction === 'y') {
678
- position += item.height + gap.vertical;
679
- }
680
- });
681
- }
682
-
683
- /**
684
- @method _commit
685
- */
686
- commit() {
687
- const items = this.sortedItems;
688
- const itemModels = items.map(item => item.model);
689
- const draggedItem = items.find(item => item.wasDropped);
690
- let draggedModel;
691
- if (draggedItem) {
692
- draggedItem.wasDropped = false; // Reset
693
- draggedModel = draggedItem.model;
694
- }
695
- this._updateItems();
696
- this._onChange(itemModels, draggedModel);
697
- }
698
- _onChange(itemModels, draggedModel) {
699
- if (this.onChange) {
700
- this.onChange(itemModels, draggedModel);
701
- }
702
- }
703
505
 
704
506
  /**
705
507
  * Keeps the UI in sync with actual changes.
@@ -720,12 +522,6 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
720
522
  });
721
523
  });
722
524
  }
723
- _createAnnouncer() {
724
- const announcer = document.createElement('span');
725
- announcer.setAttribute('aria-live', 'polite');
726
- announcer.classList.add('visually-hidden');
727
- return announcer;
728
- }
729
525
  _calculateGridPosition(a, b, groupWidth) {
730
526
  const groupTopPos = a.element.parentNode?.offsetTop ?? 0;
731
527
  const groupLeftPos = a.element.parentNode?.offsetLeft ?? 0;
@@ -825,8 +621,211 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
825
621
  _defineProperty(this, "isKeyDownEnabled", false);
826
622
  // Tracks if we're still performing a programmatic focus.
827
623
  _defineProperty(this, "isRetainingFocus", false);
624
+ _defineProperty(this, "focusOut", () => {
625
+ if (!this.isRetainingFocus && !this._isElementWithinHandle(document.activeElement)) {
626
+ this.cancelKeyboardSelection();
627
+ }
628
+ });
629
+ /**
630
+ * Explanation
631
+ * 1. `KeyboardReorderMode` is disabled: users can activate it via ENTER or SPACE.
632
+ * 2. `KeyboardReorderMode` is enabled: users can reorder via UP or DOWN arrow keys. TODO: Expand to more keys, e.g LEFT, RIGHT
633
+ * 3. `KeyboardReorderMode` is enabled: users can finalize/save the reordering via ENTER or SPACE.
634
+ * 4. `KeyboardReorderMode` is enabled: users can discard the reordering via ESC.
635
+ *
636
+ * @param {Event} event a DOM event
637
+ */
638
+ _defineProperty(this, "keyDown", event => {
639
+ if (!this.isKeyDownEnabled) {
640
+ return;
641
+ }
642
+
643
+ // Note: If handle is specified, we need to target the keyDown on the handle
644
+ const isKeyboardReorderModeEnabled = this.isKeyboardReorderModeEnabled;
645
+ if (!isKeyboardReorderModeEnabled && (isEnterKey(event) || isSpaceKey(event))) {
646
+ const _selectedItem = this._selectedItem;
647
+ if (!_selectedItem) {
648
+ return;
649
+ }
650
+ this._prepareKeyboardReorderMode();
651
+ this._announceAction(ANNOUNCEMENT_ACTION_TYPES.ACTIVATE);
652
+ this._updateItemVisualIndicators(_selectedItem, true);
653
+ this._updateHandleVisualIndicators(_selectedItem, true);
654
+ this.isRetainingFocus = true;
655
+ scheduleOnce('render', this, () => {
656
+ this.element.focus();
657
+ this.isRetainingFocus = false;
658
+ });
659
+
660
+ // Prevent the default scroll
661
+ event.preventDefault();
662
+ return;
663
+ }
664
+ if (isKeyboardReorderModeEnabled) {
665
+ this._handleKeyboardReorder(event);
666
+ event.preventDefault();
667
+ }
668
+ });
669
+ _defineProperty(this, "cancelKeyboardSelection", () => {
670
+ const _selectedItem = this._selectedItem;
671
+ if (!_selectedItem) {
672
+ return;
673
+ }
674
+ this._disableKeyboardReorderMode();
675
+ // Revert the process by reversing the move.
676
+ const moves = this.moves;
677
+ while (moves.length > 0) {
678
+ const move = moves.pop();
679
+ const fromIndex = move ? move[1] : 0;
680
+ const toIndex = move ? move[0] : 0;
681
+ this._move(fromIndex, toIndex);
682
+ }
683
+ this._tearDownA11yApplicationContainer();
684
+ this._updateItemVisualIndicators(_selectedItem, false);
685
+ this._updateHandleVisualIndicators(_selectedItem, false);
686
+ this._resetItemSelection();
687
+ });
828
688
  _initializerDefineProperty(this, "sortableService", _descriptor, this);
829
689
  _defineProperty(this, "announcer", null);
690
+ /**
691
+ * Pending timer that resets the announcer message
692
+ */
693
+ _defineProperty(this, "_announcerResetTimer", void 0);
694
+ _defineProperty(this, "activateKeyDown", selectedItem => {
695
+ this._selectedItem = selectedItem;
696
+ this.isKeyDownEnabled = true;
697
+ });
698
+ /**
699
+ * Disables keyboard navigation
700
+ * Currently used to handle keydown events bubbling up from
701
+ * elements that aren't meant to invoke keyboard navigation
702
+ * by ignoring them.
703
+ */
704
+ _defineProperty(this, "deactivateKeyDown", () => {
705
+ this.isKeyDownEnabled = false;
706
+ });
707
+ /**
708
+ Register the group with this Sortable.
709
+ @method registerGroup
710
+ @param {SortableGroupModifier} group
711
+ */
712
+ _defineProperty(this, "registerGroup", group => {
713
+ this._group = group;
714
+ });
715
+ /**
716
+ De-register the group with this Sortable.
717
+ @method deregisterGroup
718
+ @param {SortableGroupModifier} group
719
+ */
720
+ _defineProperty(this, "deregisterGroup", group => {
721
+ if (this._group === group) {
722
+ this._group = null;
723
+ }
724
+ });
725
+ /**
726
+ Prepare for sorting.
727
+ Main purpose is to stash the current firstItemPosition so
728
+ we don’t incur expensive re-layouts.
729
+ @method _prepare
730
+ */
731
+ _defineProperty(this, "prepare", () => {
732
+ this._firstItemPosition = this.firstItemPosition;
733
+ });
734
+ /**
735
+ Update item positions (relatively to the first element position).
736
+ @method update
737
+ @param {SortableItemModifier[]} sortedItems
738
+ */
739
+ _defineProperty(this, "update", sortedItems => {
740
+ if (!sortedItems) {
741
+ sortedItems = this.sortedItems;
742
+ }
743
+
744
+ // Position of the first element
745
+ let axis = this._firstItemPosition;
746
+
747
+ // Just in case we haven’t called prepare first.
748
+ if (axis === undefined) {
749
+ axis = this.firstItemPosition;
750
+ }
751
+ const direction = this.direction;
752
+ const gap = getGap(this.element);
753
+ let position = 0;
754
+ let groupPositionRight = 0;
755
+ let lastTopOffset = 0;
756
+ let maxPrevHeight = 0;
757
+ if (direction === 'grid') {
758
+ position = axis.x;
759
+ lastTopOffset = axis.y;
760
+
761
+ // `getBoundingClientRect` instead of `getComputedStyle(...).width`,
762
+ // which serializes to only 3 decimal places and can itself introduce
763
+ // rounding drift against item widths.
764
+ groupPositionRight = position + this.element.getBoundingClientRect().width;
765
+ } else {
766
+ position = axis[direction];
767
+ }
768
+ sortedItems.forEach(item => {
769
+ if (direction === 'grid' && position + item.width > groupPositionRight + GRID_WRAP_EPSILON) {
770
+ lastTopOffset = lastTopOffset + maxPrevHeight;
771
+ position = axis.x;
772
+ maxPrevHeight = 0;
773
+ }
774
+ if (!isDestroyed(item) && !item.isDragging) {
775
+ // Round only at assignment to match offsetLeft/offsetTop's integer
776
+ // rounding, so undragged items don't jitter by a fractional pixel.
777
+ if (direction === 'grid') {
778
+ item.x = Math.round(position);
779
+ item.y = Math.round(lastTopOffset);
780
+ } else {
781
+ item[direction] = Math.round(position);
782
+ }
783
+ }
784
+
785
+ // add additional spacing around active element
786
+ if (item.isBusy) {
787
+ position += item.spacing * 2;
788
+ }
789
+ if (direction === 'grid') {
790
+ if (item.height > maxPrevHeight) {
791
+ maxPrevHeight = item.height + gap.vertical;
792
+ }
793
+ position += item.width + gap.horizontal;
794
+ }
795
+ if (direction === 'x') {
796
+ position += item.width + gap.horizontal;
797
+ }
798
+ if (direction === 'y') {
799
+ position += item.height + gap.vertical;
800
+ }
801
+ });
802
+ });
803
+ /**
804
+ @method _commit
805
+ */
806
+ _defineProperty(this, "commit", () => {
807
+ const items = this.sortedItems;
808
+ const itemModels = items.map(item => item.model);
809
+ const draggedItem = items.find(item => item.wasDropped);
810
+ let draggedModel;
811
+ if (draggedItem) {
812
+ draggedItem.wasDropped = false; // Reset
813
+ draggedModel = draggedItem.model;
814
+ }
815
+ this._updateItems();
816
+ this._onChange(itemModels, draggedModel);
817
+ });
818
+ _defineProperty(this, "_onChange", (itemModels, draggedModel) => {
819
+ if (this.onChange) {
820
+ this.onChange(itemModels, draggedModel);
821
+ }
822
+ });
823
+ _defineProperty(this, "_createAnnouncer", () => {
824
+ const announcer = document.createElement('span');
825
+ announcer.setAttribute('aria-live', 'polite');
826
+ announcer.classList.add('visually-hidden');
827
+ return announcer;
828
+ });
830
829
  _defineProperty(this, "element", void 0);
831
830
  _defineProperty(this, "didSetup", false);
832
831
  _defineProperty(this, "named", void 0);
@@ -848,18 +847,18 @@ let SortableGroupModifier = (_dec = service('ember-sortable-internal-state'), _d
848
847
  }
849
848
  this.addEventListener();
850
849
  }
851
- }, _applyDecoratedDescriptor(_class.prototype, "focusOut", [action], Object.getOwnPropertyDescriptor(_class.prototype, "focusOut"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "keyDown", [action], Object.getOwnPropertyDescriptor(_class.prototype, "keyDown"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "cancelKeyboardSelection", [action], Object.getOwnPropertyDescriptor(_class.prototype, "cancelKeyboardSelection"), _class.prototype), _descriptor = _applyDecoratedDescriptor(_class.prototype, "sortableService", [_dec], {
850
+ }, _descriptor = _applyDecoratedDescriptor(_class.prototype, "sortableService", [_dec], {
852
851
  configurable: true,
853
852
  enumerable: true,
854
853
  writable: true,
855
854
  initializer: null
856
- }), _applyDecoratedDescriptor(_class.prototype, "firstItemPosition", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "firstItemPosition"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "activateKeyDown", [action], Object.getOwnPropertyDescriptor(_class.prototype, "activateKeyDown"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "deactivateKeyDown", [action], Object.getOwnPropertyDescriptor(_class.prototype, "deactivateKeyDown"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "registerGroup", [action], Object.getOwnPropertyDescriptor(_class.prototype, "registerGroup"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "deregisterGroup", [action], Object.getOwnPropertyDescriptor(_class.prototype, "deregisterGroup"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "prepare", [action], Object.getOwnPropertyDescriptor(_class.prototype, "prepare"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "update", [action], Object.getOwnPropertyDescriptor(_class.prototype, "update"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "commit", [action], Object.getOwnPropertyDescriptor(_class.prototype, "commit"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "_onChange", [action], Object.getOwnPropertyDescriptor(_class.prototype, "_onChange"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "_createAnnouncer", [action], Object.getOwnPropertyDescriptor(_class.prototype, "_createAnnouncer"), _class.prototype), _class);
855
+ }), _class);
857
856
  /**
858
857
  *
859
858
  * @param {SortableGroupModifier} instance
860
859
  */
861
860
  function cleanup(instance) {
862
- // todo cleanup the announcer
861
+ clearTimeout(instance._announcerResetTimer);
863
862
  if (instance.announcer?.parentNode) {
864
863
  instance.announcer.parentNode.removeChild(instance.announcer);
865
864
  }