@ship-ui/core 0.22.15 → 0.22.17
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/assets/mcp/components.json +213 -47
- package/bin/src/subset.ts +6 -6
- package/bin/src/utilities.ts +14 -14
- package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs +12 -86
- package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-accordion.mjs +4 -3
- package/fesm2022/ship-ui-core-ship-accordion.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-alert.mjs +1 -4
- package/fesm2022/ship-ui-core-ship-alert.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-blueprint.mjs +17 -11
- package/fesm2022/ship-ui-core-ship-blueprint.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-checkbox.mjs +3 -2
- package/fesm2022/ship-ui-core-ship-checkbox.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-color-picker.mjs +66 -62
- package/fesm2022/ship-ui-core-ship-color-picker.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-datepicker.mjs +24 -16
- package/fesm2022/ship-ui-core-ship-datepicker.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-dialog.mjs +4 -0
- package/fesm2022/ship-ui-core-ship-dialog.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-editor.mjs +0 -42
- package/fesm2022/ship-ui-core-ship-editor.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-form-field.mjs +0 -1
- package/fesm2022/ship-ui-core-ship-form-field.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-kbd.mjs +0 -6
- package/fesm2022/ship-ui-core-ship-kbd.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-list-item-swipe.mjs +241 -0
- package/fesm2022/ship-ui-core-ship-list-item-swipe.mjs.map +1 -0
- package/fesm2022/ship-ui-core-ship-menu.mjs +7 -10
- package/fesm2022/ship-ui-core-ship-menu.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-popover.mjs +5 -20
- package/fesm2022/ship-ui-core-ship-popover.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-radio.mjs +3 -2
- package/fesm2022/ship-ui-core-ship-radio.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-range-slider.mjs +7 -9
- package/fesm2022/ship-ui-core-ship-range-slider.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-select.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-sidenav.mjs +2 -2
- package/fesm2022/ship-ui-core-ship-sidenav.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-sortable.mjs +262 -68
- package/fesm2022/ship-ui-core-ship-sortable.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-spotlight.mjs +0 -11
- package/fesm2022/ship-ui-core-ship-spotlight.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-stepper.mjs +1 -1
- package/fesm2022/ship-ui-core-ship-stepper.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-table.mjs +426 -23
- package/fesm2022/ship-ui-core-ship-table.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-toggle.mjs +3 -2
- package/fesm2022/ship-ui-core-ship-toggle.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-tree.mjs +1 -9
- package/fesm2022/ship-ui-core-ship-tree.mjs.map +1 -1
- package/fesm2022/ship-ui-core.mjs +37 -53
- package/fesm2022/ship-ui-core.mjs.map +1 -1
- package/package.json +5 -1
- package/types/ship-ui-core-ship-a11y-keybindings.d.ts +0 -55
- package/types/ship-ui-core-ship-accordion.d.ts +7 -7
- package/types/ship-ui-core-ship-blueprint.d.ts +2 -1
- package/types/ship-ui-core-ship-checkbox.d.ts +2 -3
- package/types/ship-ui-core-ship-color-picker.d.ts +1 -25
- package/types/ship-ui-core-ship-datepicker.d.ts +2 -3
- package/types/ship-ui-core-ship-editor.d.ts +10 -10
- package/types/ship-ui-core-ship-list-item-swipe.d.ts +25 -0
- package/types/ship-ui-core-ship-menu.d.ts +1 -2
- package/types/ship-ui-core-ship-radio.d.ts +2 -3
- package/types/ship-ui-core-ship-range-slider.d.ts +6 -6
- package/types/ship-ui-core-ship-sortable.d.ts +31 -9
- package/types/ship-ui-core-ship-table.d.ts +12 -1
- package/types/ship-ui-core-ship-toggle.d.ts +2 -3
- package/types/ship-ui-core-ship-tree.d.ts +20 -25
- package/types/ship-ui-core.d.ts +17 -24
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, DOCUMENT, ElementRef, Renderer2, signal, input, model, output, effect, HostListener, Directive, computed } from '@angular/core';
|
|
2
|
+
import { Injectable, inject, DOCUMENT, ElementRef, Renderer2, signal, input, model, output, effect, HostListener, Directive, computed } from '@angular/core';
|
|
3
3
|
import { isObservable, firstValueFrom } from 'rxjs';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
class ShipSortableService {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.activeSource = null;
|
|
8
|
+
this.activeDraggedElement = null;
|
|
9
|
+
this.activeTarget = null;
|
|
10
|
+
this.activeInstances = new Set();
|
|
11
|
+
}
|
|
12
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipSortableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
13
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipSortableService, providedIn: 'root' }); }
|
|
14
|
+
}
|
|
15
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipSortableService, decorators: [{
|
|
16
|
+
type: Injectable,
|
|
17
|
+
args: [{
|
|
18
|
+
providedIn: 'root',
|
|
19
|
+
}]
|
|
20
|
+
}] });
|
|
6
21
|
function createSortableManager(signals, config) {
|
|
7
22
|
const isSingle = typeof signals === 'function';
|
|
8
23
|
return {
|
|
9
24
|
async drop(event) {
|
|
10
|
-
// 1. Await API Authorization (RxJS or Promises)
|
|
11
25
|
if (config?.onBeforeDrop) {
|
|
12
26
|
const result = config.onBeforeDrop(event);
|
|
13
27
|
let accept = false;
|
|
@@ -21,12 +35,10 @@ function createSortableManager(signals, config) {
|
|
|
21
35
|
accept = result;
|
|
22
36
|
}
|
|
23
37
|
if (!accept)
|
|
24
|
-
return;
|
|
38
|
+
return;
|
|
25
39
|
}
|
|
26
|
-
// 2. Perform UI Signal Update
|
|
27
40
|
const isCrossDrop = event.previousContainer !== event.container;
|
|
28
41
|
if (!isCrossDrop) {
|
|
29
|
-
// Internal Reorder (moveIndex)
|
|
30
42
|
let targetSignal;
|
|
31
43
|
if (isSingle) {
|
|
32
44
|
targetSignal = signals;
|
|
@@ -40,7 +52,6 @@ function createSortableManager(signals, config) {
|
|
|
40
52
|
}
|
|
41
53
|
}
|
|
42
54
|
else {
|
|
43
|
-
// Cross DropTransfer
|
|
44
55
|
if (isSingle) {
|
|
45
56
|
console.warn('Cross drops require a dictionary of signals in createSortableManager');
|
|
46
57
|
return;
|
|
@@ -66,6 +77,7 @@ function createSortableManager(signals, config) {
|
|
|
66
77
|
}
|
|
67
78
|
class ShipSortable {
|
|
68
79
|
constructor() {
|
|
80
|
+
this.#sortableService = inject(ShipSortableService);
|
|
69
81
|
this.#document = inject(DOCUMENT);
|
|
70
82
|
this.#selfEl = inject((ElementRef));
|
|
71
83
|
this.#renderer = inject(Renderer2);
|
|
@@ -79,6 +91,10 @@ class ShipSortable {
|
|
|
79
91
|
...(ngDevMode ? [{ debugName: "sortingMode" }] : /* istanbul ignore next */ []));
|
|
80
92
|
this.treeItems = model([], /* @ts-ignore */
|
|
81
93
|
...(ngDevMode ? [{ debugName: "treeItems" }] : /* istanbul ignore next */ []));
|
|
94
|
+
this.touchEnabled = input(false, /* @ts-ignore */
|
|
95
|
+
...(ngDevMode ? [{ debugName: "touchEnabled" }] : /* istanbul ignore next */ []));
|
|
96
|
+
this.touchActivation = input('longpress', /* @ts-ignore */
|
|
97
|
+
...(ngDevMode ? [{ debugName: "touchActivation" }] : /* istanbul ignore next */ []));
|
|
82
98
|
this.sortDrop = output();
|
|
83
99
|
this.afterDrop = output();
|
|
84
100
|
this.crossDrop = output();
|
|
@@ -98,6 +114,13 @@ class ShipSortable {
|
|
|
98
114
|
this.abortController = null;
|
|
99
115
|
this.isDropping = false;
|
|
100
116
|
this.isCrossTarget = false;
|
|
117
|
+
this.touchDragTimer = null;
|
|
118
|
+
this.touchStartCoordinates = null;
|
|
119
|
+
this.isTouchDragging = false;
|
|
120
|
+
this.touchGhostEl = null;
|
|
121
|
+
this.touchOffset = { x: 0, y: 0 };
|
|
122
|
+
this.#boundTouchMove = this.onTouchMove.bind(this);
|
|
123
|
+
this.#boundTouchEnd = this.onTouchEnd.bind(this);
|
|
101
124
|
this.draggingEffect = effect(() => {
|
|
102
125
|
if (this.sortingMode() === 'tree') {
|
|
103
126
|
return;
|
|
@@ -159,6 +182,12 @@ class ShipSortable {
|
|
|
159
182
|
for (const el of els) {
|
|
160
183
|
el.addEventListener('dragstart', (e) => this.dragStart(e), { signal: this.abortController.signal });
|
|
161
184
|
el.addEventListener('dragend', () => this.dragEnd(), { signal: this.abortController.signal });
|
|
185
|
+
if (this.touchEnabled()) {
|
|
186
|
+
el.addEventListener('touchstart', (e) => this.onTouchStart(e, el), {
|
|
187
|
+
signal: this.abortController.signal,
|
|
188
|
+
passive: false,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
162
191
|
}
|
|
163
192
|
}, /* @ts-ignore */
|
|
164
193
|
...(ngDevMode ? [{ debugName: "draggablesEffect" }] : /* istanbul ignore next */ []));
|
|
@@ -171,11 +200,11 @@ class ShipSortable {
|
|
|
171
200
|
if (this.isDropping) {
|
|
172
201
|
this.isDropping = false;
|
|
173
202
|
this.#cleanupDragState();
|
|
174
|
-
if (
|
|
175
|
-
|
|
203
|
+
if (this.#sortableService.activeTarget === this) {
|
|
204
|
+
this.#sortableService.activeTarget = null;
|
|
176
205
|
}
|
|
177
|
-
if (
|
|
178
|
-
|
|
206
|
+
if (this.#sortableService.activeSource === this) {
|
|
207
|
+
this.#sortableService.activeSource = null;
|
|
179
208
|
}
|
|
180
209
|
}
|
|
181
210
|
}
|
|
@@ -183,13 +212,13 @@ class ShipSortable {
|
|
|
183
212
|
})
|
|
184
213
|
: undefined;
|
|
185
214
|
}
|
|
215
|
+
#sortableService;
|
|
186
216
|
#document;
|
|
187
217
|
#selfEl;
|
|
188
218
|
#renderer;
|
|
189
219
|
#crossSpacerEl;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
static { this.activeTarget = null; }
|
|
220
|
+
#boundTouchMove;
|
|
221
|
+
#boundTouchEnd;
|
|
193
222
|
getIndexOfElement(element) {
|
|
194
223
|
return this.dragables().findIndex((el) => el === element);
|
|
195
224
|
}
|
|
@@ -210,9 +239,9 @@ class ShipSortable {
|
|
|
210
239
|
}
|
|
211
240
|
}
|
|
212
241
|
e.dataTransfer.effectAllowed = 'move';
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
242
|
+
this.#sortableService.activeSource = this;
|
|
243
|
+
this.#sortableService.activeDraggedElement = draggedElement;
|
|
244
|
+
this.#sortableService.activeTarget = this;
|
|
216
245
|
this.isCrossTarget = false;
|
|
217
246
|
const containerRect = this.#selfEl.nativeElement.getBoundingClientRect();
|
|
218
247
|
const container = this.#selfEl.nativeElement;
|
|
@@ -255,28 +284,35 @@ class ShipSortable {
|
|
|
255
284
|
}
|
|
256
285
|
}
|
|
257
286
|
ngOnInit() {
|
|
287
|
+
this.#sortableService.activeInstances.add(this);
|
|
258
288
|
if (typeof MutationObserver !== 'undefined') {
|
|
259
289
|
this.#dragableObserver.observe(this.#selfEl.nativeElement, { childList: true });
|
|
260
290
|
}
|
|
261
291
|
}
|
|
262
292
|
dragEnter(e) {
|
|
263
|
-
|
|
293
|
+
this.processDragEnter();
|
|
294
|
+
}
|
|
295
|
+
processDragEnter() {
|
|
296
|
+
if (!this.#sortableService.activeSource || this.#sortableService.activeSource === this)
|
|
264
297
|
return;
|
|
265
|
-
const sourceGroup =
|
|
298
|
+
const sourceGroup = this.#sortableService.activeSource.sortableGroup();
|
|
266
299
|
const currentGroup = this.sortableGroup();
|
|
267
|
-
const sourceManager =
|
|
300
|
+
const sourceManager = this.#sortableService.activeSource.shSortable();
|
|
268
301
|
const currentManager = this.shSortable();
|
|
269
302
|
const isSameGroup = !!(sourceGroup && currentGroup && sourceGroup === currentGroup);
|
|
270
303
|
const isSameManager = !!(sourceManager?.drop && currentManager?.drop && sourceManager === currentManager);
|
|
271
304
|
if (isSameGroup || isSameManager) {
|
|
272
|
-
|
|
273
|
-
|
|
305
|
+
if (this.#sortableService.activeTarget && this.#sortableService.activeTarget !== this && this.#sortableService.activeTarget !== this.#sortableService.activeSource) {
|
|
306
|
+
this.#sortableService.activeTarget.processDragLeave(0, 0, null, true);
|
|
307
|
+
}
|
|
308
|
+
this.#sortableService.activeTarget = this;
|
|
309
|
+
this.#sortableService.activeSource.dragToIndex.set(-1);
|
|
274
310
|
// Setup Target Placeholder if we are just entering
|
|
275
311
|
if (!this.isCrossTarget) {
|
|
276
312
|
this.isCrossTarget = true;
|
|
277
313
|
this.#renderer.addClass(this.#selfEl.nativeElement, 'dragging');
|
|
278
314
|
// Compute cross-target positions by temporarily appending the active ghost to measure layout flow
|
|
279
|
-
const sourceElement =
|
|
315
|
+
const sourceElement = this.#sortableService.activeDraggedElement;
|
|
280
316
|
const tempElement = sourceElement.cloneNode(true);
|
|
281
317
|
this.#renderer.setStyle(tempElement, 'transform', '');
|
|
282
318
|
// Ensure it doesn't have the original ghost state yet to measure flow without its potential transition scaling
|
|
@@ -307,39 +343,47 @@ class ShipSortable {
|
|
|
307
343
|
}
|
|
308
344
|
}
|
|
309
345
|
dragLeave(e) {
|
|
310
|
-
|
|
346
|
+
this.processDragLeave(e.clientX, e.clientY, e.relatedTarget);
|
|
347
|
+
}
|
|
348
|
+
processDragLeave(clientX, clientY, relatedTarget, force = false) {
|
|
349
|
+
if (!this.#sortableService.activeSource || this.#sortableService.activeSource === this)
|
|
311
350
|
return;
|
|
312
|
-
if (
|
|
313
|
-
if (
|
|
314
|
-
|
|
351
|
+
if (!force) {
|
|
352
|
+
if (relatedTarget) {
|
|
353
|
+
if (this.#selfEl.nativeElement.contains(relatedTarget)) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
const rect = this.#selfEl.nativeElement.getBoundingClientRect();
|
|
359
|
+
const isOutside = clientX < rect.left || clientX > rect.right || clientY < rect.top || clientY > rect.bottom;
|
|
360
|
+
if (!isOutside)
|
|
361
|
+
return;
|
|
315
362
|
}
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
const rect = this.#selfEl.nativeElement.getBoundingClientRect();
|
|
319
|
-
const isOutside = e.clientX < rect.left || e.clientX > rect.right || e.clientY < rect.top || e.clientY > rect.bottom;
|
|
320
|
-
if (!isOutside)
|
|
321
|
-
return;
|
|
322
363
|
}
|
|
323
364
|
if (this.isCrossTarget) {
|
|
324
365
|
this.#cleanupDragState();
|
|
325
|
-
if (
|
|
326
|
-
|
|
366
|
+
if (this.#sortableService.activeTarget === this) {
|
|
367
|
+
this.#sortableService.activeTarget = this.#sortableService.activeSource;
|
|
327
368
|
}
|
|
328
369
|
}
|
|
329
370
|
}
|
|
330
371
|
dragOver(e) {
|
|
331
372
|
e.preventDefault();
|
|
332
373
|
e.dataTransfer.dropEffect = 'move';
|
|
333
|
-
|
|
374
|
+
this.processDragOver(e.clientX, e.clientY, e.target);
|
|
375
|
+
}
|
|
376
|
+
processDragOver(clientX, clientY, targetElementUnderTouch) {
|
|
377
|
+
if (this.#sortableService.activeTarget !== this)
|
|
334
378
|
return;
|
|
335
379
|
if (this.sortingMode() === 'tree') {
|
|
336
|
-
const targetElement =
|
|
337
|
-
const hoveredDraggable = targetElement
|
|
380
|
+
const targetElement = targetElementUnderTouch || this.#document.elementFromPoint(clientX, clientY);
|
|
381
|
+
const hoveredDraggable = targetElement?.closest('[draggable]');
|
|
338
382
|
if (hoveredDraggable && this.#selfEl.nativeElement.contains(hoveredDraggable)) {
|
|
339
383
|
const targetIdx = this.getIndexOfElement(hoveredDraggable);
|
|
340
384
|
if (targetIdx !== -1) {
|
|
341
385
|
const rect = hoveredDraggable.getBoundingClientRect();
|
|
342
|
-
const relativeY = (
|
|
386
|
+
const relativeY = (clientY - rect.top) / rect.height;
|
|
343
387
|
const isFolder = hoveredDraggable.hasAttribute('sortable-folder') ||
|
|
344
388
|
hoveredDraggable.getAttribute('sortable-folder') === 'true' ||
|
|
345
389
|
hoveredDraggable.hasAttribute('sortable-dir') ||
|
|
@@ -385,8 +429,8 @@ class ShipSortable {
|
|
|
385
429
|
const container = this.#selfEl.nativeElement;
|
|
386
430
|
const containerRect = container.getBoundingClientRect();
|
|
387
431
|
// Convert viewport coordinates to container-relative coordinate space
|
|
388
|
-
const mouseX =
|
|
389
|
-
const mouseY =
|
|
432
|
+
const mouseX = clientX - containerRect.left - container.clientLeft + container.scrollLeft;
|
|
433
|
+
const mouseY = clientY - containerRect.top - container.clientTop + container.scrollTop;
|
|
390
434
|
let closestSlotIndex = -1;
|
|
391
435
|
let minDistance = Infinity;
|
|
392
436
|
const positions = this.initialPositions();
|
|
@@ -404,6 +448,156 @@ class ShipSortable {
|
|
|
404
448
|
this.dragToIndex.set(closestSlotIndex);
|
|
405
449
|
}
|
|
406
450
|
}
|
|
451
|
+
onTouchStart(e, el) {
|
|
452
|
+
if (!this.touchEnabled() || this.touchActivation() === 'none') {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const touch = e.touches[0];
|
|
456
|
+
const targetEl = touch.target;
|
|
457
|
+
const isSortingHandle = targetEl.hasAttribute('sort-handle') || targetEl.closest('[sort-handle]') !== null;
|
|
458
|
+
const hasHandle = el.querySelector('[sort-handle]') !== null;
|
|
459
|
+
if (hasHandle && !isSortingHandle) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (this.touchActivation() === 'handle') {
|
|
463
|
+
if (!isSortingHandle) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
e.preventDefault();
|
|
467
|
+
this.startTouchDrag(touch, el);
|
|
468
|
+
}
|
|
469
|
+
else if (this.touchActivation() === 'longpress') {
|
|
470
|
+
this.touchStartCoordinates = { x: touch.clientX, y: touch.clientY };
|
|
471
|
+
this.#document.addEventListener('touchmove', this.#boundTouchMove, { passive: false });
|
|
472
|
+
this.#document.addEventListener('touchend', this.#boundTouchEnd, { passive: false });
|
|
473
|
+
this.#document.addEventListener('touchcancel', this.#boundTouchEnd, { passive: false });
|
|
474
|
+
this.touchDragTimer = setTimeout(() => {
|
|
475
|
+
this.startTouchDrag(touch, el);
|
|
476
|
+
}, 300);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
startTouchDrag(touch, el) {
|
|
480
|
+
this.isTouchDragging = true;
|
|
481
|
+
this.#sortableService.activeSource = this;
|
|
482
|
+
this.#sortableService.activeDraggedElement = el;
|
|
483
|
+
this.#sortableService.activeTarget = this;
|
|
484
|
+
this.isCrossTarget = false;
|
|
485
|
+
const containerRect = this.#selfEl.nativeElement.getBoundingClientRect();
|
|
486
|
+
const container = this.#selfEl.nativeElement;
|
|
487
|
+
const positions = Array.from(this.dragables()).map((item) => {
|
|
488
|
+
const rect = item.getBoundingClientRect();
|
|
489
|
+
return {
|
|
490
|
+
x: rect.left - containerRect.left - container.clientLeft + container.scrollLeft,
|
|
491
|
+
y: rect.top - containerRect.top - container.clientTop + container.scrollTop,
|
|
492
|
+
width: rect.width,
|
|
493
|
+
height: rect.height,
|
|
494
|
+
};
|
|
495
|
+
});
|
|
496
|
+
this.initialPositions.set(positions);
|
|
497
|
+
const rect = el.getBoundingClientRect();
|
|
498
|
+
this.touchOffset = {
|
|
499
|
+
x: touch.clientX - rect.left,
|
|
500
|
+
y: touch.clientY - rect.top,
|
|
501
|
+
};
|
|
502
|
+
const ghost = el.cloneNode(true);
|
|
503
|
+
ghost.style.position = 'fixed';
|
|
504
|
+
ghost.style.width = `${rect.width}px`;
|
|
505
|
+
ghost.style.height = `${rect.height}px`;
|
|
506
|
+
ghost.style.left = `${rect.left}px`;
|
|
507
|
+
ghost.style.top = `${rect.top}px`;
|
|
508
|
+
ghost.style.pointerEvents = 'none';
|
|
509
|
+
ghost.style.zIndex = '9999';
|
|
510
|
+
ghost.style.opacity = '0.8';
|
|
511
|
+
ghost.style.boxShadow = '0 5px 15px rgba(0,0,0,0.3)';
|
|
512
|
+
ghost.style.margin = '0';
|
|
513
|
+
ghost.style.transform = '';
|
|
514
|
+
ghost.classList.add('sortable-ghost-touch');
|
|
515
|
+
this.#document.body.appendChild(ghost);
|
|
516
|
+
this.touchGhostEl = ghost;
|
|
517
|
+
const draggedElementIndex = this.getIndexOfElement(el);
|
|
518
|
+
this.dragStartIndex.set(draggedElementIndex);
|
|
519
|
+
this.dragToIndex.set(draggedElementIndex);
|
|
520
|
+
this.#renderer.addClass(el, 'sortable-ghost');
|
|
521
|
+
this.#renderer.addClass(this.#selfEl.nativeElement, 'dragging');
|
|
522
|
+
if (this.touchActivation() === 'handle') {
|
|
523
|
+
this.touchStartCoordinates = { x: touch.clientX, y: touch.clientY };
|
|
524
|
+
this.#document.addEventListener('touchmove', this.#boundTouchMove, { passive: false });
|
|
525
|
+
this.#document.addEventListener('touchend', this.#boundTouchEnd, { passive: false });
|
|
526
|
+
this.#document.addEventListener('touchcancel', this.#boundTouchEnd, { passive: false });
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
onTouchMove(e) {
|
|
530
|
+
const touch = e.touches[0];
|
|
531
|
+
const clientX = touch.clientX;
|
|
532
|
+
const clientY = touch.clientY;
|
|
533
|
+
if (!this.isTouchDragging) {
|
|
534
|
+
if (this.touchStartCoordinates) {
|
|
535
|
+
const dx = clientX - this.touchStartCoordinates.x;
|
|
536
|
+
const dy = clientY - this.touchStartCoordinates.y;
|
|
537
|
+
if (Math.hypot(dx, dy) > 8) {
|
|
538
|
+
this.cancelTouchDrag();
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
e.preventDefault();
|
|
544
|
+
if (this.touchGhostEl) {
|
|
545
|
+
const x = clientX - this.touchOffset.x;
|
|
546
|
+
const y = clientY - this.touchOffset.y;
|
|
547
|
+
this.touchGhostEl.style.left = `${x}px`;
|
|
548
|
+
this.touchGhostEl.style.top = `${y}px`;
|
|
549
|
+
}
|
|
550
|
+
const elementUnderTouch = this.#document.elementFromPoint(clientX, clientY);
|
|
551
|
+
let targetInstance = null;
|
|
552
|
+
if (elementUnderTouch) {
|
|
553
|
+
for (const instance of this.#sortableService.activeInstances) {
|
|
554
|
+
if (instance.#selfEl.nativeElement === elementUnderTouch || instance.#selfEl.nativeElement.contains(elementUnderTouch)) {
|
|
555
|
+
targetInstance = instance;
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (targetInstance) {
|
|
561
|
+
if (this.#sortableService.activeTarget !== targetInstance) {
|
|
562
|
+
if (this.#sortableService.activeTarget) {
|
|
563
|
+
this.#sortableService.activeTarget.processDragLeave(clientX, clientY, null, true);
|
|
564
|
+
}
|
|
565
|
+
this.#sortableService.activeTarget = targetInstance;
|
|
566
|
+
targetInstance.processDragEnter();
|
|
567
|
+
}
|
|
568
|
+
this.#sortableService.activeTarget.processDragOver(clientX, clientY, elementUnderTouch);
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
if (this.#sortableService.activeTarget && this.#sortableService.activeTarget !== this.#sortableService.activeSource) {
|
|
572
|
+
this.#sortableService.activeTarget.processDragLeave(clientX, clientY, null, true);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
onTouchEnd(e) {
|
|
577
|
+
const wasDragging = this.isTouchDragging;
|
|
578
|
+
this.cancelTouchDrag();
|
|
579
|
+
if (wasDragging) {
|
|
580
|
+
this.isTouchDragging = false;
|
|
581
|
+
if (this.#sortableService.activeTarget) {
|
|
582
|
+
this.#sortableService.activeTarget.drop();
|
|
583
|
+
}
|
|
584
|
+
if (this.touchGhostEl) {
|
|
585
|
+
this.touchGhostEl.remove();
|
|
586
|
+
this.touchGhostEl = null;
|
|
587
|
+
}
|
|
588
|
+
this.dragEnd();
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
cancelTouchDrag() {
|
|
592
|
+
if (this.touchDragTimer) {
|
|
593
|
+
clearTimeout(this.touchDragTimer);
|
|
594
|
+
this.touchDragTimer = null;
|
|
595
|
+
}
|
|
596
|
+
this.touchStartCoordinates = null;
|
|
597
|
+
this.#document.removeEventListener('touchmove', this.#boundTouchMove);
|
|
598
|
+
this.#document.removeEventListener('touchend', this.#boundTouchEnd);
|
|
599
|
+
this.#document.removeEventListener('touchcancel', this.#boundTouchEnd);
|
|
600
|
+
}
|
|
407
601
|
#clearTreeHoverClasses() {
|
|
408
602
|
const dragables = this.dragables();
|
|
409
603
|
for (const el of dragables) {
|
|
@@ -432,17 +626,17 @@ class ShipSortable {
|
|
|
432
626
|
return targetVisualIndex;
|
|
433
627
|
}
|
|
434
628
|
drop() {
|
|
435
|
-
if (!
|
|
629
|
+
if (!this.#sortableService.activeSource)
|
|
436
630
|
return;
|
|
437
631
|
// Immediately kill drag transitions before any signal updates
|
|
438
|
-
this.#renderer.removeClass(
|
|
632
|
+
this.#renderer.removeClass(this.#sortableService.activeSource.#selfEl.nativeElement, 'dragging');
|
|
439
633
|
this.#renderer.removeClass(this.#selfEl.nativeElement, 'dragging');
|
|
440
634
|
if (this.sortingMode() === 'tree') {
|
|
441
635
|
this.isDropping = true;
|
|
442
|
-
if (
|
|
443
|
-
|
|
636
|
+
if (this.#sortableService.activeSource !== this) {
|
|
637
|
+
this.#sortableService.activeSource.isDropping = true;
|
|
444
638
|
}
|
|
445
|
-
const prevIdx =
|
|
639
|
+
const prevIdx = this.#sortableService.activeSource.dragStartIndex();
|
|
446
640
|
const currIdx = this.dragToIndex();
|
|
447
641
|
const pos = this.treeHoverPosition();
|
|
448
642
|
if (prevIdx !== -1 && currIdx !== -1 && pos) {
|
|
@@ -460,12 +654,12 @@ class ShipSortable {
|
|
|
460
654
|
}
|
|
461
655
|
}
|
|
462
656
|
this.#cleanupDragState();
|
|
463
|
-
if (
|
|
464
|
-
|
|
657
|
+
if (this.#sortableService.activeSource !== this) {
|
|
658
|
+
this.#sortableService.activeSource.#cleanupDragState();
|
|
465
659
|
}
|
|
466
660
|
return;
|
|
467
661
|
}
|
|
468
|
-
if (
|
|
662
|
+
if (this.#sortableService.activeSource === this) {
|
|
469
663
|
// Internal Drop
|
|
470
664
|
if (this.dragStartIndex() !== -1 && this.dragToIndex() !== -1 && this.dragStartIndex() !== this.dragToIndex()) {
|
|
471
665
|
this.isDropping = true;
|
|
@@ -484,14 +678,14 @@ class ShipSortable {
|
|
|
484
678
|
}
|
|
485
679
|
}
|
|
486
680
|
}
|
|
487
|
-
else if (
|
|
681
|
+
else if (this.#sortableService.activeTarget === this && this.isCrossTarget) {
|
|
488
682
|
// Cross Drop
|
|
489
683
|
this.isDropping = true;
|
|
490
|
-
|
|
684
|
+
this.#sortableService.activeSource.isDropping = true;
|
|
491
685
|
const event = {
|
|
492
|
-
previousContainer:
|
|
686
|
+
previousContainer: this.#sortableService.activeSource,
|
|
493
687
|
container: this,
|
|
494
|
-
previousIndex:
|
|
688
|
+
previousIndex: this.#sortableService.activeSource.dragStartIndex(),
|
|
495
689
|
currentIndex: this.dragToIndex(),
|
|
496
690
|
};
|
|
497
691
|
if (this.shSortable()?.drop) {
|
|
@@ -500,26 +694,26 @@ class ShipSortable {
|
|
|
500
694
|
else {
|
|
501
695
|
this.sortDrop.emit(event);
|
|
502
696
|
this.crossDrop.emit({
|
|
503
|
-
previousContainer:
|
|
697
|
+
previousContainer: this.#sortableService.activeSource,
|
|
504
698
|
currentContainer: this,
|
|
505
|
-
previousIndex:
|
|
699
|
+
previousIndex: this.#sortableService.activeSource.dragStartIndex(),
|
|
506
700
|
currentIndex: this.dragToIndex(),
|
|
507
701
|
});
|
|
508
702
|
}
|
|
509
703
|
}
|
|
510
704
|
}
|
|
511
705
|
dragEnd() {
|
|
512
|
-
if (
|
|
513
|
-
|
|
514
|
-
|
|
706
|
+
if (this.#sortableService.activeSource) {
|
|
707
|
+
this.#sortableService.activeSource.#renderer.removeClass(this.#sortableService.activeSource.#selfEl.nativeElement, 'dragging');
|
|
708
|
+
this.#sortableService.activeSource.#cleanupDragState();
|
|
515
709
|
}
|
|
516
|
-
if (
|
|
517
|
-
|
|
518
|
-
|
|
710
|
+
if (this.#sortableService.activeTarget && this.#sortableService.activeTarget !== this.#sortableService.activeSource) {
|
|
711
|
+
this.#sortableService.activeTarget.#renderer.removeClass(this.#sortableService.activeTarget.#selfEl.nativeElement, 'dragging');
|
|
712
|
+
this.#sortableService.activeTarget.#cleanupDragState();
|
|
519
713
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
714
|
+
this.#sortableService.activeSource = null;
|
|
715
|
+
this.#sortableService.activeTarget = null;
|
|
716
|
+
this.#sortableService.activeDraggedElement = null;
|
|
523
717
|
}
|
|
524
718
|
#cleanupDragState() {
|
|
525
719
|
this.#renderer.removeClass(this.#selfEl.nativeElement, 'dragging');
|
|
@@ -549,13 +743,13 @@ class ShipSortable {
|
|
|
549
743
|
}
|
|
550
744
|
#dragableObserver;
|
|
551
745
|
ngOnDestroy() {
|
|
746
|
+
this.#sortableService.activeInstances.delete(this);
|
|
552
747
|
this.#dragableObserver?.disconnect();
|
|
553
748
|
this.abortController?.abort();
|
|
554
749
|
}
|
|
555
750
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipSortable, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
556
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: ShipSortable, isStandalone: true, selector: "[shSortable]", inputs: { shSortable: { classPropertyName: "shSortable", publicName: "shSortable", isSignal: true, isRequired: false, transformFunction: null }, sortableGroup: { classPropertyName: "sortableGroup", publicName: "sortableGroup", isSignal: true, isRequired: false, transformFunction: null }, sortingMode: { classPropertyName: "sortingMode", publicName: "sortingMode", isSignal: true, isRequired: false, transformFunction: null }, treeItems: { classPropertyName: "treeItems", publicName: "treeItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { treeItems: "treeItemsChange", sortDrop: "sortDrop", afterDrop: "afterDrop", crossDrop: "crossDrop", treeDrop: "treeDrop" }, host: { listeners: { "dragenter": "dragEnter($event)", "dragleave": "dragLeave($event)", "dragover": "dragOver($event)", "drop": "drop()" }, properties: { "class.sh-sortable-tree": "sortingMode() === 'tree'" }, classAttribute: "sh-sortable" }, ngImport: i0 }); }
|
|
751
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: ShipSortable, isStandalone: true, selector: "[shSortable]", inputs: { shSortable: { classPropertyName: "shSortable", publicName: "shSortable", isSignal: true, isRequired: false, transformFunction: null }, sortableGroup: { classPropertyName: "sortableGroup", publicName: "sortableGroup", isSignal: true, isRequired: false, transformFunction: null }, sortingMode: { classPropertyName: "sortingMode", publicName: "sortingMode", isSignal: true, isRequired: false, transformFunction: null }, treeItems: { classPropertyName: "treeItems", publicName: "treeItems", isSignal: true, isRequired: false, transformFunction: null }, touchEnabled: { classPropertyName: "touchEnabled", publicName: "touchEnabled", isSignal: true, isRequired: false, transformFunction: null }, touchActivation: { classPropertyName: "touchActivation", publicName: "touchActivation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { treeItems: "treeItemsChange", sortDrop: "sortDrop", afterDrop: "afterDrop", crossDrop: "crossDrop", treeDrop: "treeDrop" }, host: { listeners: { "dragenter": "dragEnter($event)", "dragleave": "dragLeave($event)", "dragover": "dragOver($event)", "drop": "drop()" }, properties: { "class.sh-sortable-tree": "sortingMode() === 'tree'" }, classAttribute: "sh-sortable" }, ngImport: i0 }); }
|
|
557
752
|
}
|
|
558
|
-
_a = ShipSortable;
|
|
559
753
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipSortable, decorators: [{
|
|
560
754
|
type: Directive,
|
|
561
755
|
args: [{
|
|
@@ -566,7 +760,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
566
760
|
'[class.sh-sortable-tree]': "sortingMode() === 'tree'",
|
|
567
761
|
},
|
|
568
762
|
}]
|
|
569
|
-
}], propDecorators: { shSortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "shSortable", required: false }] }], sortableGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortableGroup", required: false }] }], sortingMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortingMode", required: false }] }], treeItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeItems", required: false }] }, { type: i0.Output, args: ["treeItemsChange"] }], sortDrop: [{ type: i0.Output, args: ["sortDrop"] }], afterDrop: [{ type: i0.Output, args: ["afterDrop"] }], crossDrop: [{ type: i0.Output, args: ["crossDrop"] }], treeDrop: [{ type: i0.Output, args: ["treeDrop"] }], dragEnter: [{
|
|
763
|
+
}], propDecorators: { shSortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "shSortable", required: false }] }], sortableGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortableGroup", required: false }] }], sortingMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortingMode", required: false }] }], treeItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "treeItems", required: false }] }, { type: i0.Output, args: ["treeItemsChange"] }], touchEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "touchEnabled", required: false }] }], touchActivation: [{ type: i0.Input, args: [{ isSignal: true, alias: "touchActivation", required: false }] }], sortDrop: [{ type: i0.Output, args: ["sortDrop"] }], afterDrop: [{ type: i0.Output, args: ["afterDrop"] }], crossDrop: [{ type: i0.Output, args: ["crossDrop"] }], treeDrop: [{ type: i0.Output, args: ["treeDrop"] }], dragEnter: [{
|
|
570
764
|
type: HostListener,
|
|
571
765
|
args: ['dragenter', ['$event']]
|
|
572
766
|
}], dragLeave: [{
|
|
@@ -714,5 +908,5 @@ function createTreeSortableManager(nodesSignal, config) {
|
|
|
714
908
|
* Generated bundle index. Do not edit.
|
|
715
909
|
*/
|
|
716
910
|
|
|
717
|
-
export { ShipSortable, createSortableManager, createTreeSortableManager, moveIndex, transferArrayItem };
|
|
911
|
+
export { ShipSortable, ShipSortableService, createSortableManager, createTreeSortableManager, moveIndex, transferArrayItem };
|
|
718
912
|
//# sourceMappingURL=ship-ui-core-ship-sortable.mjs.map
|