ngx-kit 8.0.0 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-kit",
3
- "version": "8.0.0",
3
+ "version": "8.0.1",
4
4
  "description": "Angular input components",
5
5
  "author": "Mohammadreza Samani <mr.samani1368@gmail.com>",
6
6
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { TemplateRef, EventEmitter, InjectionToken, OnInit, OnDestroy, ElementRef, Renderer2, AfterContentInit, Injector } from '@angular/core';
2
+ import { TemplateRef, ApplicationRef, EventEmitter, InjectionToken, OnInit, OnDestroy, Renderer2, ElementRef, AfterContentInit } from '@angular/core';
3
3
 
4
4
  interface IPosition {
5
5
  x: number;
@@ -12,7 +12,6 @@ interface IPosition {
12
12
  * Lists register themselves automatically when `NgxDropListGroup` wraps them.
13
13
  */
14
14
  declare class DropListGroupRef {
15
- el?: HTMLElement;
16
15
  readonly lists: Set<DropListRef<any>>;
17
16
  add(list: DropListRef<any>): void;
18
17
  remove(list: DropListRef<any>): void;
@@ -20,19 +19,38 @@ declare class DropListGroupRef {
20
19
  }
21
20
 
22
21
  declare class PlaceHolderRef {
22
+ /**
23
+ * Custom placeholder content, from `*ngxPlaceholder` inside the `ngxDropList`. When unset,
24
+ * `attach()` falls back to a shallow clone of the dragged element (previous behaviour).
25
+ *
26
+ * Example:
27
+ *
28
+ * <div ngxDropList>
29
+ * <span class="my-placeholder" *ngxPlaceholder></span>
30
+ * ...
31
+ * </div>
32
+ */
23
33
  tpl?: TemplateRef<unknown>;
34
+ /** Set by `NgxPlaceholder` so the embedded view can join Angular's change-detection tree. */
35
+ appRef?: ApplicationRef;
24
36
  dropList?: DropListRef;
25
37
  element?: HTMLElement;
26
38
  private _visible;
27
- /**
28
- * Angular embedded view created from `tpl`.
29
- */
30
39
  private _view?;
40
+ /** True once `this.element` was built from `tpl` (as opposed to the fallback clone). */
41
+ private isCustom;
31
42
  attach(container: HTMLElement, source: HTMLElement, reference?: Node | null): HTMLElement;
43
+ /** True while the currently attached element came from a custom `*ngxPlaceholder` template. */
44
+ get custom(): boolean;
32
45
  detach(): void;
33
46
  get visible(): boolean;
34
47
  }
35
48
 
49
+ interface Point {
50
+ x: number;
51
+ y: number;
52
+ }
53
+
36
54
  /**
37
55
  * A drop list.
38
56
  *
@@ -55,6 +73,16 @@ declare class DropListRef<T = any> {
55
73
  sortAnimationDuration: number;
56
74
  readonly _draggables: Set<DragRef<T>>;
57
75
  readonly onDrop: EventEmitter<IDropEvent<T>>;
76
+ /**
77
+ * Nesting: the nearest ENCLOSING drop list (null for a top-level list), and this list's own
78
+ * direct nested lists — i.e. lists whose nearest enclosing list is this one, not a list at any
79
+ * depth. Set by `NgxDropList` at init from a `skipSelf` DI lookup. Used for two things: (1)
80
+ * `depth` for "innermost wins" in `DragRef`'s target resolution, without any DOM `.contains()`
81
+ * calls on the hot path, and (2) cascading `_setAncestorOffset` (below) to every list nested
82
+ * inside an item that gets displaced by sorting, at any depth.
83
+ */
84
+ parentList: DropListRef<any> | null;
85
+ readonly childLists: Set<DropListRef<any>>;
58
86
  private session;
59
87
  private placeholder?;
60
88
  customPlaceholder?: PlaceHolderRef;
@@ -65,10 +93,50 @@ declare class DropListRef<T = any> {
65
93
  /** Pre-insertion geometry of a foreign list, restored when the drag leaves it. */
66
94
  private naturalHit;
67
95
  private hitCached;
96
+ /**
97
+ * Screen-space offset contributed by displaced ANCESTOR item(s) (see `parentList` above).
98
+ * `{0,0}` outside of that (the overwhelmingly common case). Kept as a SUM of independent
99
+ * per-source contributions, not a single overwritten value: while the pointer hovers a
100
+ * FOREIGN (non-origin) list nested inside the origin's own displaced item, up to two ancestor
101
+ * sessions can be displacing this list at once — the origin's (frozen, still active further
102
+ * up) and that foreign list's own — and one clearing its contribution on release must not
103
+ * wipe out the other's, still-active, contribution.
104
+ */
105
+ private readonly ancestorContributions;
106
+ private ancestorOffset;
107
+ /** Entries this list itself pushed via a one-time placeholder-insertion reflow (see below). */
108
+ private readonly reflowContributions;
109
+ /** How many enclosing drop lists this one is nested inside. Root lists are depth 0. */
110
+ get depth(): number;
111
+ _registerChild(child: DropListRef<any>): void;
112
+ _unregisterChild(child: DropListRef<any>): void;
113
+ /**
114
+ * One ancestor SESSION's contribution to this list's total displacement just changed (or
115
+ * cleared, `{0,0}`). `source` identifies WHICH session — the list whose own item is doing the
116
+ * displacing — so that this list's own recomputed total is a SUM across every currently-active
117
+ * source, and cascades the SAME (source, offset) pair on to every nested list at any depth
118
+ * unchanged, so a list several levels down stays hit-testable at its true on-screen position
119
+ * regardless of which ancestor(s) are currently sorting.
120
+ */
121
+ _setAncestorOffset(source: DropListRef<any>, offset: Point): void;
122
+ /** Which of this list's DIRECT nested lists live inside `el`, notified of its new offset. */
123
+ private propagateOffset;
124
+ /** Rects, right now, of every `other` entry that contains one of this list's nested lists. */
125
+ private trackedEntryRects;
126
+ /** Turns the real reflow a fresh placeholder insertion just caused into ordinary offsets. */
127
+ private propagateReflow;
68
128
  addItem(item: DragRef<T>): void;
69
129
  removeItem(item: DragRef<T>): void;
70
130
  isConnectedTo(other: DropListRef<any>): boolean;
71
- /** Measure the list and its clipping ancestors once, at drag start. */
131
+ /**
132
+ * Measure the list and its clipping ancestors once, at drag start (or the moment a nested
133
+ * list becomes a candidate mid-drag). `measureHit` reads live `getBoundingClientRect()`s,
134
+ * which already include any `translate3d` an ancestor item's displacement has applied — so if
135
+ * this list is currently offset (nested inside a sibling that sorting is displacing right
136
+ * now), the measurement is normalized back to the zero-offset frame `_containsPoint` expects,
137
+ * by subtracting that offset straight back out. Without this, entering a nested list while
138
+ * its ancestor is mid-displacement would double-count the offset on every check afterwards.
139
+ */
72
140
  _cacheGeometry(): void;
73
141
  /**
74
142
  * Is the point over the *visible* part of this list? Scroll-aware without re-measuring.
@@ -89,7 +157,20 @@ declare class DropListRef<T = any> {
89
157
  /** Re-evaluate the insertion index for the pointer. Returns the new index, or null if unchanged. */
90
158
  sortItem(drag: DragRef<T>, position: IPosition): number | null;
91
159
  /** The pointer left this list. */
160
+ /**
161
+ * The pointer truly left this list (as opposed to moving deeper into one of its own nested
162
+ * lists — see `DragRef`'s chain tracking, which never calls `exit()` for a list that remains
163
+ * an ancestor of the new target, so this always means "left this list's territory").
164
+ */
92
165
  exit(drag: DragRef<T>): void;
166
+ /**
167
+ * The pointer dove into one of this list's own nested lists: this list is no longer the
168
+ * innermost target, but it isn't being left either — its placeholder and sibling displacement
169
+ * stay exactly as they are (avoids a snap-back-then-forward flicker), only the "currently
170
+ * hovered" bookkeeping (and its visual highlight) is cleared. `DragRef`'s chain tracking calls
171
+ * this instead of `exit()` for every list that remains an ancestor of the new target.
172
+ */
173
+ _freeze(): void;
93
174
  /**
94
175
  * Ends the drag for this list. Returns the drop event when the pointer was released over this
95
176
  * list, `null` otherwise (nothing to emit). All transient state is disposed either way.
@@ -119,10 +200,31 @@ declare class DragDropService {
119
200
  readonly drags: _angular_core.WritableSignal<readonly DragRef<unknown>[]>;
120
201
  readonly dropLists: _angular_core.WritableSignal<readonly DropListRef<any>[]>;
121
202
  readonly activeDrag: _angular_core.WritableSignal<DragRef<unknown> | null>;
203
+ /**
204
+ * DOM-position registries, used to find the nearest enclosing list/group by walking real
205
+ * ancestor elements instead of Angular's element-injector tree.
206
+ *
207
+ * This matters for `ngTemplateOutlet`-based recursive trees (a list of items whose own
208
+ * children are rendered by re-invoking the SAME `<ng-template>`, as in a tree/outliner UI):
209
+ * each invocation gets a FRESH embedded view whose injector context is wherever the outlet
210
+ * was written in the template, not wherever its content ends up in the DOM. So `inject(TOKEN,
211
+ * {skipSelf})` from one recursion level can never see a provider from another level — the
212
+ * only fix within Angular's own DI is to manually thread `ngTemplateOutletInjector` through
213
+ * every recursive call, which isn't reasonable to require of every consumer of this library.
214
+ * A plain DOM walk has no such limitation: it only cares where elements actually ended up.
215
+ */
216
+ private readonly listsByEl;
217
+ private readonly groupsByEl;
122
218
  registerDragItem(ref: DragRef<any>): void;
123
219
  removeDragItem(ref: DragRef<any>): void;
124
220
  registerDropList(ref: DropListRef): void;
125
221
  removeDropList(ref: DropListRef<any>): void;
222
+ registerGroup(el: HTMLElement, ref: DropListGroupRef): void;
223
+ removeGroup(el: HTMLElement): void;
224
+ /** Nearest registered drop list starting at (and including) `start`, walking up the DOM. */
225
+ findAncestorDropList(start: HTMLElement | null): DropListRef | null;
226
+ /** Nearest registered drop-list group starting at (and including) `start`, walking up the DOM. */
227
+ findAncestorGroup(start: HTMLElement | null): DropListGroupRef | null;
126
228
  begin(ref: DragRef<any>): void;
127
229
  end(ref: DragRef<any>): void;
128
230
  cancelActive(): void;
@@ -184,6 +286,14 @@ declare class DragRef<T = unknown> {
184
286
  /** True while a drop-list drag (body preview + placeholder) is in progress. Free drag: always false. */
185
287
  private listDrag;
186
288
  private cachedLists;
289
+ /**
290
+ * Candidate lists for hit-testing, filtered (connected to the origin; not inside the dragged
291
+ * element) and sorted deepest-first — both computed ONCE, not on every pointer move, since
292
+ * neither ever changes mid-drag. Kept in sync with the live registry (see `dropListsSnapshot`)
293
+ * so a list that appears or disappears mid-drag (e.g. behind an `@if`) is still picked up.
294
+ */
295
+ private dropCandidates;
296
+ private dropListsSnapshot;
187
297
  private lastEffective;
188
298
  private scrollListener?;
189
299
  private resizeListener?;
@@ -215,8 +325,35 @@ declare class DragRef<T = unknown> {
215
325
  notifyScroll(dx: number, dy: number): void;
216
326
  private applyTransform;
217
327
  private beginListDrag;
218
- /** Decide which list is under the pointer, switch if needed, then re-sort in the active one. */
328
+ /**
329
+ * Recomputes which registered lists are valid targets for this drag — connected to the
330
+ * origin, and not nested inside the element being dragged — plus each one's nesting depth.
331
+ *
332
+ * `DragDropService.dropLists()` is an Angular signal: its array is a NEW reference only when a
333
+ * list actually registers or unregisters, so the check below is a single reference comparison
334
+ * on every pointer move and the (heavier) connectivity/containment/depth work below it only
335
+ * runs on the rare event a list appears or disappears mid-drag — never on every pointer move.
336
+ */
337
+ private refreshDropCandidates;
338
+ /**
339
+ * Decide which list is under the pointer, switch if needed, then re-sort in the active one.
340
+ *
341
+ * The origin list is the one exception to "exiting a list resets/releases it": while the
342
+ * pointer dives into one of the origin's OWN nested lists (at any depth), the origin's
343
+ * placeholder and sibling displacement are left exactly as they are — frozen, not reset —
344
+ * so returning to the origin's own level doesn't snap items back and then forward again.
345
+ * Every OTHER (foreign) list still fully releases the moment the pointer leaves it, exactly
346
+ * as before; nesting multiple foreign sessions alive at once would let their own internal
347
+ * sibling displacement compound in ways a single flat `ancestorOffset` cannot represent.
348
+ */
219
349
  private updateDropTarget;
350
+ /**
351
+ * Innermost connected list under the pointer, from the precomputed candidates: deeper always
352
+ * beats shallower; among lists at the same depth (unrelated, visually overlapping lists) the
353
+ * currently active one is kept to avoid flicker, otherwise the smaller one wins. No DOM
354
+ * reads and no `.contains()` calls happen here — everything needed was precomputed above.
355
+ */
356
+ private resolveDropList;
220
357
  /**
221
358
  * Single teardown path for every way a drop-list drag can end (drop on a list, drop outside,
222
359
  * Escape, pointercancel, destroy). Everything transient is removed here, so nothing can leak
@@ -256,7 +393,6 @@ interface IResizableOutput {
256
393
  declare const NGX_DRAGGABLE: InjectionToken<NgxDraggable<unknown>>;
257
394
  declare class NgxDraggable<T = unknown> implements OnInit, OnDestroy {
258
395
  private readonly host;
259
- private readonly renderer;
260
396
  readonly disabled: _angular_core.ModelSignal<boolean>;
261
397
  /** Element whose rect constrains the drag. Now actually enforced. */
262
398
  readonly boundary: _angular_core.InputSignal<HTMLElement | undefined>;
@@ -279,8 +415,6 @@ declare class NgxDraggable<T = unknown> implements OnInit, OnDestroy {
279
415
  readonly dragging: _angular_core.WritableSignal<boolean>;
280
416
  private readonly doc;
281
417
  private readonly service;
282
- private readonly list;
283
- private readonly group;
284
418
  private readonly scroller;
285
419
  private down;
286
420
  private start;
@@ -298,7 +432,8 @@ declare class NgxDraggable<T = unknown> implements OnInit, OnDestroy {
298
432
  private lastWindowScroll;
299
433
  private removeContainerScroll?;
300
434
  private removeWindowScroll?;
301
- constructor(host: ElementRef<HTMLElement>, renderer: Renderer2);
435
+ protected readonly renderer: Renderer2;
436
+ constructor(host: ElementRef<HTMLElement>);
302
437
  ngOnInit(): void;
303
438
  ngOnDestroy(): void;
304
439
  private pointerDown;
@@ -377,7 +512,6 @@ declare class NgxDropList<T = any> implements OnInit, OnDestroy, AfterContentIni
377
512
  private readonly customPlaceholder?;
378
513
  private sub?;
379
514
  private readonly service;
380
- private readonly group;
381
515
  constructor(el: ElementRef<HTMLElement>);
382
516
  ngOnInit(): void;
383
517
  ngAfterContentInit(): void;
@@ -388,14 +522,14 @@ declare class NgxDropList<T = any> implements OnInit, OnDestroy, AfterContentIni
388
522
 
389
523
  declare const NGX_DROPLIST_GROUP: InjectionToken<NgxDropListGroup>;
390
524
  /** Wrap several `ngxDropList`s to let items move freely between them. */
391
- declare class NgxDropListGroup implements OnDestroy {
525
+ declare class NgxDropListGroup implements OnInit, OnDestroy {
392
526
  readonly _ref: DropListGroupRef;
393
- protected readonly el: ElementRef<any>;
394
- injector: Injector;
395
- constructor();
527
+ private readonly el;
528
+ private readonly service;
529
+ ngOnInit(): void;
396
530
  ngOnDestroy(): void;
397
531
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxDropListGroup, never>;
398
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgxDropListGroup, "[NgxDropListGroup],[ngxDropListGroup]", ["ngxDropListGroup"], {}, {}, never, never, true, never>;
532
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgxDropListGroup, "[NgxDropListGroup],[ngxDropListGroup]", never, {}, {}, never, never, true, never>;
399
533
  }
400
534
 
401
535
  declare const NGX_PLACEHOLDER: InjectionToken<PlaceHolderRef>;