Skip to content

Commit d111206

Browse files
committed
refactor: introduce droppable parent and make path abstract
1 parent bd0c918 commit d111206

File tree

2 files changed

+58
-32
lines changed

2 files changed

+58
-32
lines changed

packages/abstract/src/core/entities/droppable/droppable.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,24 @@ export class Droppable<
9696
return this.manager?.dragOperation.target?.id === this.id;
9797
}
9898

99-
public path: UniqueIdentifier[] = [];
99+
@reactive
100+
public accessor parent: UniqueIdentifier | undefined;
101+
102+
@derived
103+
public get path() {
104+
const path = [];
105+
106+
if (this.manager && this.parent) {
107+
const {droppables} = this.manager.registry;
108+
109+
let parent = droppables.get(this.parent);
110+
111+
while (parent) {
112+
path.unshift(parent.id);
113+
parent = droppables.get(parent.parent);
114+
}
115+
}
116+
117+
return path;
118+
}
100119
}

packages/dom/src/core/entities/droppable/droppable.ts

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
} from '@dnd-kit/abstract';
77
import {defaultCollisionDetection} from '@dnd-kit/collision';
88
import type {CollisionDetector} from '@dnd-kit/collision';
9-
import {reactive, untracked} from '@dnd-kit/state';
9+
import {derived, reactive, untracked} from '@dnd-kit/state';
1010
import type {BoundingRectangle, Shape} from '@dnd-kit/geometry';
1111
import {DOMRectangle, PositionObserver} from '@dnd-kit/dom/utilities';
1212

@@ -20,32 +20,6 @@ export interface Input<T extends Data = Data>
2020
element?: Element;
2121
}
2222

23-
function getPathArray(
24-
droppables: DragDropManager['registry']['droppables'],
25-
target: Element
26-
): UniqueIdentifier[] {
27-
// Create a map from element to id for easy lookup
28-
const elementMap = new Map<Element, UniqueIdentifier>();
29-
Array.from(droppables.value).forEach((item) => {
30-
if (item?.element) {
31-
elementMap.set(item.element, item.id);
32-
}
33-
});
34-
35-
const path: UniqueIdentifier[] = [];
36-
let currentElement = target.parentElement;
37-
38-
while (currentElement) {
39-
const parentId = elementMap.get(currentElement);
40-
if (parentId) {
41-
path.unshift(parentId);
42-
}
43-
currentElement = currentElement.parentElement;
44-
}
45-
46-
return path;
47-
}
48-
4923
export class Droppable<T extends Data = Data> extends AbstractDroppable<
5024
T,
5125
DragDropManager
@@ -96,10 +70,6 @@ export class Droppable<T extends Data = Data> extends AbstractDroppable<
9670
!this.disabled &&
9771
this.accepts(source);
9872

99-
this.path = element
100-
? getPathArray(manager.registry.droppables, element)
101-
: [];
102-
10373
if (observePosition) {
10474
const positionObserver = new PositionObserver(
10575
element,
@@ -143,4 +113,41 @@ export class Droppable<T extends Data = Data> extends AbstractDroppable<
143113
}
144114

145115
public refreshShape: () => Shape | undefined;
116+
117+
@derived
118+
private get elementMap() {
119+
const {manager} = this;
120+
if (!manager) return;
121+
122+
// Create a map from element to id for easy lookup
123+
const elementMap = new Map<Element, UniqueIdentifier>();
124+
Array.from(manager.registry.droppables.value).forEach((item) => {
125+
if (item?.element) {
126+
elementMap.set(item.element, item.id);
127+
}
128+
});
129+
130+
return elementMap;
131+
}
132+
133+
public get parent() {
134+
if (super.parent) {
135+
return super.parent;
136+
}
137+
138+
const {element} = this;
139+
if (!element || !this.elementMap) return;
140+
141+
let currentElement = element.parentElement;
142+
143+
while (currentElement) {
144+
const parentId = this.elementMap.get(currentElement);
145+
146+
if (parentId) {
147+
return parentId;
148+
}
149+
150+
currentElement = currentElement.parentElement;
151+
}
152+
}
146153
}

0 commit comments

Comments
 (0)