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.
- package/declarations/modifiers/sortable-group.d.ts +16 -12
- package/declarations/modifiers/sortable-item.d.ts +3 -3
- package/dist/{_rollupPluginBabelHelpers-a7bede49.js → _rollupPluginBabelHelpers-060f9720.js} +6 -6
- package/dist/_rollupPluginBabelHelpers-060f9720.js.map +1 -0
- package/dist/modifiers/sortable-group.js +221 -222
- package/dist/modifiers/sortable-group.js.map +1 -1
- package/dist/modifiers/sortable-handle.js +1 -1
- package/dist/modifiers/sortable-item.js +37 -37
- package/dist/modifiers/sortable-item.js.map +1 -1
- package/dist/services/ember-sortable-internal-state.js +1 -1
- package/package.json +1 -1
- package/dist/_rollupPluginBabelHelpers-a7bede49.js.map +0 -1
|
@@ -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()
|
|
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)
|
|
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()
|
|
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>)
|
|
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()
|
|
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>)
|
|
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>)
|
|
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()
|
|
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>[])
|
|
302
|
+
update: (sortedItems: SortableItemModifier<T>[]) => void;
|
|
299
303
|
/**
|
|
300
304
|
@method _commit
|
|
301
305
|
*/
|
|
302
|
-
commit()
|
|
303
|
-
_onChange(itemModels: T[], draggedModel: T | undefined)
|
|
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()
|
|
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)
|
|
195
|
-
keyDown(event: Event)
|
|
194
|
+
mouseDown: (event: MouseEvent) => void;
|
|
195
|
+
keyDown: (event: Event) => void;
|
|
196
196
|
/**
|
|
197
197
|
@method touchStart
|
|
198
198
|
*/
|
|
199
|
-
touchStart(event: TouchEvent)
|
|
199
|
+
touchStart: (event: TouchEvent) => void;
|
|
200
200
|
/**
|
|
201
201
|
@method freeze
|
|
202
202
|
*/
|
package/dist/{_rollupPluginBabelHelpers-a7bede49.js → _rollupPluginBabelHelpers-060f9720.js}
RENAMED
|
@@ -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,
|
|
25
|
+
function _toPrimitive(t, e) {
|
|
26
26
|
if ("object" != typeof t || !t) return t;
|
|
27
|
-
var
|
|
28
|
-
if (void 0 !==
|
|
29
|
-
var i =
|
|
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" ===
|
|
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-
|
|
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-
|
|
1
|
+
import { _ as _applyDecoratedDescriptor, a as _defineProperty, b as _initializerDefineProperty } from '../_rollupPluginBabelHelpers-060f9720.js';
|
|
2
2
|
import Modifier from 'ember-modifier';
|
|
3
|
-
import {
|
|
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,
|
|
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,
|
|
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'),
|
|
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
|
-
|
|
178
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
},
|
|
850
|
+
}, _descriptor = _applyDecoratedDescriptor(_class.prototype, "sortableService", [_dec], {
|
|
852
851
|
configurable: true,
|
|
853
852
|
enumerable: true,
|
|
854
853
|
writable: true,
|
|
855
854
|
initializer: null
|
|
856
|
-
}),
|
|
855
|
+
}), _class);
|
|
857
856
|
/**
|
|
858
857
|
*
|
|
859
858
|
* @param {SortableGroupModifier} instance
|
|
860
859
|
*/
|
|
861
860
|
function cleanup(instance) {
|
|
862
|
-
|
|
861
|
+
clearTimeout(instance._announcerResetTimer);
|
|
863
862
|
if (instance.announcer?.parentNode) {
|
|
864
863
|
instance.announcer.parentNode.removeChild(instance.announcer);
|
|
865
864
|
}
|