-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathcreate-droppable.ts
More file actions
85 lines (75 loc) · 2.09 KB
/
create-droppable.ts
File metadata and controls
85 lines (75 loc) · 2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import {
createEffect,
createMemo,
createSignal,
onCleanup,
onMount,
Setter,
} from "solid-js";
import { Id, useDragDropContext } from "./drag-drop-context";
import {
elementLayout,
noopTransform,
Transform,
transformsAreEqual,
} from "./layout";
import { transformStyle } from "./style";
interface Droppable {
(element: HTMLElement, accessor?: () => { skipTransform?: boolean }): void;
ref: Setter<HTMLElement | null>;
get isActiveDroppable(): boolean;
get transform(): Transform;
}
const createDroppable = (id: Id, data: Record<string, any> = {}): Droppable => {
const [state, { addDroppable, removeDroppable }] = useDragDropContext()!;
const [node, setNode] = createSignal<HTMLElement | null>(null);
onMount(() => {
const resolvedNode = node();
if (resolvedNode) {
addDroppable({
id,
node: resolvedNode,
layout: elementLayout(resolvedNode),
data,
});
}
});
onCleanup(() => removeDroppable(id));
const isActiveDroppable = createMemo(() => state.active.droppableId === id);
const transform = createMemo(() => {
return state.droppables[id]?.transform || noopTransform();
});
const droppable = Object.defineProperties(
(element: HTMLElement, accessor?: () => { skipTransform?: boolean }) => {
const config = accessor ? accessor() : {};
setNode(element);
if (!config.skipTransform) {
createEffect(() => {
const resolvedTransform = transform();
if (!transformsAreEqual(resolvedTransform, noopTransform())) {
const style = transformStyle(transform());
element.style.setProperty("transform", style.transform ?? null);
} else {
element.style.removeProperty("transform");
}
});
}
},
{
ref: {
enumerable: true,
value: setNode,
},
isActiveDroppable: {
enumerable: true,
get: isActiveDroppable,
},
transform: {
enumerable: true,
get: transform,
},
}
) as Droppable;
return droppable;
};
export { createDroppable };