forty-cdk 0.3.0 → 0.4.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/fesm2022/forty-cdk-core.mjs +34 -1
- package/fesm2022/forty-cdk-core.mjs.map +1 -1
- package/fesm2022/forty-cdk-drag-drop.mjs +49 -41
- package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -1
- package/fesm2022/forty-cdk-listbox.mjs +15 -26
- package/fesm2022/forty-cdk-listbox.mjs.map +1 -1
- package/fesm2022/forty-cdk-table.mjs +10 -2
- package/fesm2022/forty-cdk-table.mjs.map +1 -1
- package/fesm2022/forty-cdk-tree.mjs +26 -34
- package/fesm2022/forty-cdk-tree.mjs.map +1 -1
- package/listbox/README.md +24 -0
- package/package.json +1 -1
- package/tree/README.md +27 -0
- package/types/forty-cdk-checkbox.d.ts +1 -1
- package/types/forty-cdk-combobox.d.ts +1 -1
- package/types/forty-cdk-core.d.ts +28 -2
- package/types/forty-cdk-listbox.d.ts +20 -0
- package/types/forty-cdk-table.d.ts +8 -1
- package/types/forty-cdk-tree.d.ts +28 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, inject, signal, Directive, afterNextRender, ElementRef, DOCUMENT, PLATFORM_ID, DestroyRef, Injector, input, booleanAttribute, output, computed, TemplateRef, ViewContainerRef, contentChild, model, effect } from '@angular/core';
|
|
3
3
|
import { isPlatformBrowser } from '@angular/common';
|
|
4
|
-
import { createDefaults, fencePlaceholderIndex, placeholderInsertion, playFlip, LiveAnnouncer, injectPrefersReducedMotion, injectTextDirection, RovingTabindex, Collection, reconcileRovingActive, registerHandle, createAutoScroller, firstEnabledHost, moveIndex, buildDragSlots, indexOfSlot, PreviewController, resolveDropTarget, stepSlot, createPointerDragSession, createTemplatePreview, resolveListNavigation, clampPreviewPosition } from 'forty-cdk/core';
|
|
4
|
+
import { createDefaults, fencePlaceholderIndex, placeholderInsertion, playFlip, LiveAnnouncer, injectPrefersReducedMotion, injectTextDirection, RovingTabindex, Collection, reconcileRovingActive, registerHandle, createAutoScroller, firstEnabledHost, moveIndex, buildDragSlots, indexOfSlot, PreviewController, resolveDropTarget, stepSlot, createPointerHandleGuard, createPointerDragSession, createTemplatePreview, resolveListNavigation, clampPreviewPosition } from 'forty-cdk/core';
|
|
5
5
|
|
|
6
6
|
const FOR_DRAG_DROP_CONTEXT = new InjectionToken('FOR_DRAG_DROP_CONTEXT');
|
|
7
7
|
function injectDropListContext(piece) {
|
|
@@ -325,6 +325,7 @@ class ForDropList {
|
|
|
325
325
|
#sorter = null;
|
|
326
326
|
#autoScroller = null;
|
|
327
327
|
#lastPoint = null;
|
|
328
|
+
#resolveRaf = null;
|
|
328
329
|
/** Insertion index this list is the current drop target at, else `null`. */
|
|
329
330
|
dragOverIndex = this.#dragOver.asReadonly();
|
|
330
331
|
/** `true` while a drag originating from this list is in progress. */
|
|
@@ -344,7 +345,13 @@ class ForDropList {
|
|
|
344
345
|
maxSpeed: this.#defaults.autoScrollMaxSpeed,
|
|
345
346
|
onFrame: () => this.#onAutoScrollFrame(),
|
|
346
347
|
});
|
|
347
|
-
this.#destroyRef.onDestroy(() =>
|
|
348
|
+
this.#destroyRef.onDestroy(() => {
|
|
349
|
+
this.#autoScroller?.stop();
|
|
350
|
+
if (this.#resolveRaf !== null) {
|
|
351
|
+
this.#document.defaultView?.cancelAnimationFrame(this.#resolveRaf);
|
|
352
|
+
this.#resolveRaf = null;
|
|
353
|
+
}
|
|
354
|
+
});
|
|
348
355
|
}
|
|
349
356
|
}
|
|
350
357
|
registerItem(handle) {
|
|
@@ -442,13 +449,27 @@ class ForDropList {
|
|
|
442
449
|
return;
|
|
443
450
|
}
|
|
444
451
|
this.#lastPoint = point;
|
|
445
|
-
this.#resolveDrop(point, lifted);
|
|
446
452
|
if (this.autoScroll()) {
|
|
447
453
|
this.#autoScroller?.update(point);
|
|
448
454
|
}
|
|
449
455
|
else {
|
|
450
456
|
this.#autoScroller?.stop();
|
|
451
457
|
}
|
|
458
|
+
if (this.#resolveRaf !== null) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
this.#resolveDrop(point, lifted);
|
|
462
|
+
const win = this.#document.defaultView;
|
|
463
|
+
if (win) {
|
|
464
|
+
this.#resolveRaf = win.requestAnimationFrame(() => {
|
|
465
|
+
this.#resolveRaf = null;
|
|
466
|
+
const currentLifted = this.#liftedHost();
|
|
467
|
+
const currentPoint = this.#lastPoint;
|
|
468
|
+
if (currentLifted !== null && currentPoint !== null) {
|
|
469
|
+
this.#resolveDrop(currentPoint, currentLifted);
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
}
|
|
452
473
|
}
|
|
453
474
|
#resolveDrop(point, lifted) {
|
|
454
475
|
const connected = this.#effectiveConnected();
|
|
@@ -480,6 +501,16 @@ class ForDropList {
|
|
|
480
501
|
this.#announcer.announce(this.#defaults.announceMove(label, target.index + 1, targetCtx.items().length), 'polite');
|
|
481
502
|
}
|
|
482
503
|
}
|
|
504
|
+
#flushResolve(lifted) {
|
|
505
|
+
if (this.#resolveRaf === null) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
this.#document.defaultView?.cancelAnimationFrame(this.#resolveRaf);
|
|
509
|
+
this.#resolveRaf = null;
|
|
510
|
+
if (this.#lastPoint !== null) {
|
|
511
|
+
this.#resolveDrop(this.#lastPoint, lifted);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
483
514
|
#resolveBoundary() {
|
|
484
515
|
const boundary = this.boundary();
|
|
485
516
|
if (boundary === null) {
|
|
@@ -536,6 +567,7 @@ class ForDropList {
|
|
|
536
567
|
if (liftedHost === null) {
|
|
537
568
|
return;
|
|
538
569
|
}
|
|
570
|
+
this.#flushResolve(liftedHost);
|
|
539
571
|
const connected = this.#effectiveConnected();
|
|
540
572
|
const items = this.#items.items();
|
|
541
573
|
const slots = buildDragSlots(items.length, connected.map((c) => c.items().length));
|
|
@@ -609,6 +641,10 @@ class ForDropList {
|
|
|
609
641
|
}, /* @ts-ignore */
|
|
610
642
|
...(ngDevMode ? [{ debugName: "#effectiveConnected" }] : /* istanbul ignore next */ []));
|
|
611
643
|
#teardown(connected, keepPreview = false) {
|
|
644
|
+
if (this.#resolveRaf !== null) {
|
|
645
|
+
this.#document.defaultView?.cancelAnimationFrame(this.#resolveRaf);
|
|
646
|
+
this.#resolveRaf = null;
|
|
647
|
+
}
|
|
612
648
|
this.#autoScroller?.stop();
|
|
613
649
|
this.#lastPoint = null;
|
|
614
650
|
this.#dragOver.set(null);
|
|
@@ -708,7 +744,6 @@ class ForDraggable {
|
|
|
708
744
|
/** `true` while a pointer-drag placeholder template occupies this item's slot (host hidden). */
|
|
709
745
|
placeholderActive = signal(false, /* @ts-ignore */
|
|
710
746
|
...(ngDevMode ? [{ debugName: "placeholderActive" }] : /* istanbul ignore next */ []));
|
|
711
|
-
#handles = new Set();
|
|
712
747
|
#pointerDragging = false;
|
|
713
748
|
#pointerSession = null;
|
|
714
749
|
/** Data payload handed back in the `dragDrop` event when this item is dropped. */
|
|
@@ -726,6 +761,7 @@ class ForDraggable {
|
|
|
726
761
|
dragEnd = output();
|
|
727
762
|
effectiveDisabled = computed(() => this.dragDisabled() || this.#list.disabled(), /* @ts-ignore */
|
|
728
763
|
...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
764
|
+
#handleGuard = createPointerHandleGuard(this.effectiveDisabled);
|
|
729
765
|
/** `true` when this item is the currently lifted draggable. Reflected as `data-dragging`. */
|
|
730
766
|
lifted = computed(() => this.#list.isLifted(this.#host.nativeElement), /* @ts-ignore */
|
|
731
767
|
...(ngDevMode ? [{ debugName: "lifted" }] : /* istanbul ignore next */ []));
|
|
@@ -746,8 +782,7 @@ class ForDraggable {
|
|
|
746
782
|
return this.#list.isFirstFocusableItem(this.#host.nativeElement) ? 0 : -1;
|
|
747
783
|
}, /* @ts-ignore */
|
|
748
784
|
...(ngDevMode ? [{ debugName: "tabindex" }] : /* istanbul ignore next */ []));
|
|
749
|
-
touchAction =
|
|
750
|
-
...(ngDevMode ? [{ debugName: "touchAction" }] : /* istanbul ignore next */ []));
|
|
785
|
+
touchAction = this.#handleGuard.touchAction;
|
|
751
786
|
constructor() {
|
|
752
787
|
const handle = {
|
|
753
788
|
host: this.#host.nativeElement,
|
|
@@ -762,7 +797,7 @@ class ForDraggable {
|
|
|
762
797
|
armThreshold: POINTER_ARM_THRESHOLD_PX$1,
|
|
763
798
|
cancelOnEscape: true,
|
|
764
799
|
capturePointer: true,
|
|
765
|
-
canStart: (event) => this.#
|
|
800
|
+
canStart: (event) => this.#handleGuard.canStart(event),
|
|
766
801
|
onLift: (event) => this.#onPointerLift(event),
|
|
767
802
|
onMove: (event) => this.#onPointerMove(event),
|
|
768
803
|
onCommit: () => this.#onPointerCommit(),
|
|
@@ -773,23 +808,10 @@ class ForDraggable {
|
|
|
773
808
|
}
|
|
774
809
|
}
|
|
775
810
|
registerHandle(el) {
|
|
776
|
-
this.#
|
|
811
|
+
this.#handleGuard.register(el);
|
|
777
812
|
}
|
|
778
813
|
unregisterHandle(el) {
|
|
779
|
-
this.#
|
|
780
|
-
}
|
|
781
|
-
#canStartPointer(event) {
|
|
782
|
-
if (this.effectiveDisabled()) {
|
|
783
|
-
return false;
|
|
784
|
-
}
|
|
785
|
-
if (event.pointerType === 'mouse' && event.button !== 0) {
|
|
786
|
-
return false;
|
|
787
|
-
}
|
|
788
|
-
if (this.#handles.size === 0) {
|
|
789
|
-
return true;
|
|
790
|
-
}
|
|
791
|
-
const target = event.target;
|
|
792
|
-
return target !== null && [...this.#handles].some((h) => h.contains(target));
|
|
814
|
+
this.#handleGuard.unregister(el);
|
|
793
815
|
}
|
|
794
816
|
#onPointerLift(event) {
|
|
795
817
|
const preview = this.#buildPreview();
|
|
@@ -951,12 +973,12 @@ class ForFreeDrag {
|
|
|
951
973
|
#document = inject(DOCUMENT);
|
|
952
974
|
#destroyRef = inject(DestroyRef);
|
|
953
975
|
#isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
954
|
-
#handles = new Set();
|
|
955
976
|
#lift = signal(null, /* @ts-ignore */
|
|
956
977
|
...(ngDevMode ? [{ debugName: "#lift" }] : /* istanbul ignore next */ []));
|
|
957
978
|
#pointerSession = null;
|
|
958
979
|
/** When true, the element can't be dragged (it stays focusable; the transform doesn't change). */
|
|
959
980
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
981
|
+
#handleGuard = createPointerHandleGuard(this.disabled);
|
|
960
982
|
/**
|
|
961
983
|
* The element actually moved: an `HTMLElement`, or a selector resolved via `closest()` from the
|
|
962
984
|
* host. `null` (the default) moves the host itself. Mirrors CDK's `cdkDragRootElement` — drag a
|
|
@@ -992,8 +1014,7 @@ class ForFreeDrag {
|
|
|
992
1014
|
/** True while a pointer drag is armed. Reflected as `data-dragging`. */
|
|
993
1015
|
dragging = computed(() => this.#lift() !== null, /* @ts-ignore */
|
|
994
1016
|
...(ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []));
|
|
995
|
-
touchAction =
|
|
996
|
-
...(ngDevMode ? [{ debugName: "touchAction" }] : /* istanbul ignore next */ []));
|
|
1017
|
+
touchAction = this.#handleGuard.touchAction;
|
|
997
1018
|
constructor() {
|
|
998
1019
|
if (this.#isBrowser) {
|
|
999
1020
|
effect(() => {
|
|
@@ -1007,7 +1028,7 @@ class ForFreeDrag {
|
|
|
1007
1028
|
armThreshold: POINTER_ARM_THRESHOLD_PX,
|
|
1008
1029
|
cancelOnEscape: true,
|
|
1009
1030
|
capturePointer: true,
|
|
1010
|
-
canStart: (event) => this.#
|
|
1031
|
+
canStart: (event) => this.#handleGuard.canStart(event),
|
|
1011
1032
|
onLift: (event) => this.#onLift(event),
|
|
1012
1033
|
onMove: (event) => this.#onMove(event),
|
|
1013
1034
|
onCommit: () => this.#onCommit(),
|
|
@@ -1017,10 +1038,10 @@ class ForFreeDrag {
|
|
|
1017
1038
|
}
|
|
1018
1039
|
}
|
|
1019
1040
|
registerHandle(el) {
|
|
1020
|
-
this.#
|
|
1041
|
+
this.#handleGuard.register(el);
|
|
1021
1042
|
}
|
|
1022
1043
|
unregisterHandle(el) {
|
|
1023
|
-
this.#
|
|
1044
|
+
this.#handleGuard.unregister(el);
|
|
1024
1045
|
}
|
|
1025
1046
|
#resolvedRoot = computed(() => {
|
|
1026
1047
|
const root = this.rootElement();
|
|
@@ -1040,19 +1061,6 @@ class ForFreeDrag {
|
|
|
1040
1061
|
? this.#host.nativeElement.closest(boundary)
|
|
1041
1062
|
: boundary;
|
|
1042
1063
|
}
|
|
1043
|
-
#canStartPointer(event) {
|
|
1044
|
-
if (this.disabled()) {
|
|
1045
|
-
return false;
|
|
1046
|
-
}
|
|
1047
|
-
if (event.pointerType === 'mouse' && event.button !== 0) {
|
|
1048
|
-
return false;
|
|
1049
|
-
}
|
|
1050
|
-
if (this.#handles.size === 0) {
|
|
1051
|
-
return true;
|
|
1052
|
-
}
|
|
1053
|
-
const target = event.target;
|
|
1054
|
-
return target !== null && [...this.#handles].some((h) => h.contains(target));
|
|
1055
|
-
}
|
|
1056
1064
|
#onLift(event) {
|
|
1057
1065
|
const rect = this.#resolvedRoot().getBoundingClientRect();
|
|
1058
1066
|
const position = this.position();
|