@dnd-kit/solid 0.2.3

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/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @dnd-kit/solid
2
+
3
+ [![Stable release](https://img.shields.io/npm/v/@dnd-kit/solid.svg)](https://npm.im/@dnd-kit/solid)
4
+
5
+ The SolidJS layer for @dnd-kit, built on top of @dnd-kit/dom.
6
+
7
+ ## Installation
8
+
9
+ To get started, install the `@dnd-kit/solid` package via npm or yarn:
10
+
11
+ ```
12
+ npm install @dnd-kit/solid
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ Visit [docs.dndkit.com](https://docs.dndkit.com) to learn how to get started with @dnd-kit.
package/hooks.cjs ADDED
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ var state = require('@dnd-kit/state');
4
+ var solidJs = require('solid-js');
5
+
6
+ // src/hooks/useDeepSignal.ts
7
+ function useDeepSignal(target) {
8
+ const tracked = /* @__PURE__ */ new Map();
9
+ const [dirty, setDirty] = solidJs.createSignal(0);
10
+ solidJs.createEffect(() => {
11
+ const _target = target();
12
+ if (!_target) {
13
+ tracked.clear();
14
+ return;
15
+ }
16
+ const dispose = state.effect(() => {
17
+ let stale = false;
18
+ for (const entry of tracked) {
19
+ const [key] = entry;
20
+ const value = state.untracked(() => entry[1]);
21
+ const latestValue = _target[key];
22
+ if (value !== latestValue) {
23
+ stale = true;
24
+ tracked.set(key, latestValue);
25
+ }
26
+ }
27
+ if (stale) {
28
+ setDirty((v) => v + 1);
29
+ }
30
+ });
31
+ solidJs.onCleanup(dispose);
32
+ });
33
+ return () => {
34
+ const _target = target();
35
+ void dirty();
36
+ return _target ? new Proxy(_target, {
37
+ get(target2, key) {
38
+ const value = target2[key];
39
+ tracked.set(key, value);
40
+ return value;
41
+ }
42
+ }) : _target;
43
+ };
44
+ }
45
+
46
+ exports.useDeepSignal = useDeepSignal;
47
+ //# sourceMappingURL=hooks.cjs.map
48
+ //# sourceMappingURL=hooks.cjs.map
package/hooks.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Accessor } from 'solid-js';
2
+
3
+ /** Trigger a re-render when reading signal properties of an object. */
4
+ declare function useDeepSignal<T extends object | null | undefined>(target: Accessor<T>): Accessor<T>;
5
+
6
+ export { useDeepSignal };
package/hooks.js ADDED
@@ -0,0 +1,46 @@
1
+ import { effect, untracked } from '@dnd-kit/state';
2
+ import { createSignal, createEffect, onCleanup } from 'solid-js';
3
+
4
+ // src/hooks/useDeepSignal.ts
5
+ function useDeepSignal(target) {
6
+ const tracked = /* @__PURE__ */ new Map();
7
+ const [dirty, setDirty] = createSignal(0);
8
+ createEffect(() => {
9
+ const _target = target();
10
+ if (!_target) {
11
+ tracked.clear();
12
+ return;
13
+ }
14
+ const dispose = effect(() => {
15
+ let stale = false;
16
+ for (const entry of tracked) {
17
+ const [key] = entry;
18
+ const value = untracked(() => entry[1]);
19
+ const latestValue = _target[key];
20
+ if (value !== latestValue) {
21
+ stale = true;
22
+ tracked.set(key, latestValue);
23
+ }
24
+ }
25
+ if (stale) {
26
+ setDirty((v) => v + 1);
27
+ }
28
+ });
29
+ onCleanup(dispose);
30
+ });
31
+ return () => {
32
+ const _target = target();
33
+ void dirty();
34
+ return _target ? new Proxy(_target, {
35
+ get(target2, key) {
36
+ const value = target2[key];
37
+ tracked.set(key, value);
38
+ return value;
39
+ }
40
+ }) : _target;
41
+ };
42
+ }
43
+
44
+ export { useDeepSignal };
45
+ //# sourceMappingURL=hooks.js.map
46
+ //# sourceMappingURL=hooks.js.map
package/index.cjs ADDED
@@ -0,0 +1,433 @@
1
+ 'use strict';
2
+
3
+ var web = require('solid-js/web');
4
+ var solidJs = require('solid-js');
5
+ var dom = require('@dnd-kit/dom');
6
+ var sortable = require('@dnd-kit/dom/sortable');
7
+ var state = require('@dnd-kit/state');
8
+
9
+ // src/core/context/DragDropProvider.tsx
10
+ var DragDropContext = solidJs.createContext(null);
11
+ function useRenderer() {
12
+ const [transitionCount, setTransitionCount] = solidJs.createSignal(0);
13
+ let rendering = null;
14
+ let resolver = null;
15
+ solidJs.createEffect(
16
+ solidJs.on(transitionCount, () => {
17
+ resolver?.();
18
+ rendering = null;
19
+ })
20
+ );
21
+ return {
22
+ renderer: {
23
+ get rendering() {
24
+ return rendering ?? Promise.resolve();
25
+ }
26
+ },
27
+ trackRendering(callback) {
28
+ if (!rendering) {
29
+ rendering = new Promise((resolve) => {
30
+ resolver = resolve;
31
+ });
32
+ }
33
+ solidJs.batch(() => {
34
+ callback();
35
+ setTransitionCount((c) => c + 1);
36
+ });
37
+ }
38
+ };
39
+ }
40
+
41
+ // src/utilities/saveElementPosition.ts
42
+ function createSaveElementPosition() {
43
+ let savedPosition = null;
44
+ const savePosition = (source) => {
45
+ const element = source.element;
46
+ const id = source.id;
47
+ const prevElement = element.previousElementSibling;
48
+ const nextElement = element.nextElementSibling;
49
+ const parentElement = element.parentElement;
50
+ savedPosition = {
51
+ id,
52
+ element,
53
+ prevElement: prevElement === element ? null : prevElement,
54
+ nextElement: nextElement === element ? null : nextElement,
55
+ parentElement
56
+ };
57
+ };
58
+ const restorePosition = (element) => {
59
+ if (!savedPosition) return;
60
+ const { prevElement, nextElement, parentElement } = savedPosition;
61
+ if (prevElement && element.previousElementSibling !== prevElement) {
62
+ prevElement.insertAdjacentElement("afterend", element);
63
+ } else if (nextElement && element.nextElementSibling !== nextElement) {
64
+ nextElement.insertAdjacentElement("beforebegin", element);
65
+ } else if (!prevElement && !nextElement && parentElement) {
66
+ parentElement.appendChild(element);
67
+ }
68
+ };
69
+ const clearPosition = () => {
70
+ savedPosition = null;
71
+ };
72
+ return {
73
+ savePosition,
74
+ clearPosition,
75
+ restorePosition
76
+ };
77
+ }
78
+
79
+ // src/core/context/DragDropProvider.tsx
80
+ function DragDropProvider(props) {
81
+ const {
82
+ savePosition,
83
+ restorePosition,
84
+ clearPosition
85
+ } = createSaveElementPosition();
86
+ const {
87
+ renderer,
88
+ trackRendering
89
+ } = useRenderer();
90
+ const manager = solidJs.createMemo(() => props.manager ?? new dom.DragDropManager(props));
91
+ solidJs.onCleanup(() => {
92
+ if (!props.manager) {
93
+ manager().destroy();
94
+ }
95
+ });
96
+ solidJs.createEffect(() => {
97
+ const _manager = manager();
98
+ _manager.renderer = renderer;
99
+ _manager.plugins = props.plugins ?? dom.defaultPreset.plugins;
100
+ _manager.sensors = props.sensors ?? dom.defaultPreset.sensors;
101
+ _manager.modifiers = props.modifiers ?? dom.defaultPreset.modifiers;
102
+ });
103
+ solidJs.createEffect(() => {
104
+ const disposers = [];
105
+ const monitor = manager().monitor;
106
+ disposers.push(monitor.addEventListener("beforedragstart", (event, manager2) => {
107
+ if (sortable.isSortable(event.operation.source)) {
108
+ savePosition(event.operation.source);
109
+ }
110
+ const callback = props.onBeforeDragStart;
111
+ if (callback) {
112
+ trackRendering(() => callback(event, manager2));
113
+ }
114
+ }), monitor.addEventListener("dragstart", (event, manager2) => {
115
+ props.onDragStart?.(event, manager2);
116
+ }), monitor.addEventListener("dragover", (event, manager2) => {
117
+ const callback = props.onDragOver;
118
+ if (callback) {
119
+ trackRendering(() => callback(event, manager2));
120
+ if (sortable.isSortable(event.operation.source)) {
121
+ const source = event.operation.source;
122
+ queueMicrotask(() => savePosition(source));
123
+ }
124
+ }
125
+ }), monitor.addEventListener("dragmove", (event, manager2) => {
126
+ const callback = props.onDragMove;
127
+ if (callback) {
128
+ trackRendering(() => callback(event, manager2));
129
+ }
130
+ }), monitor.addEventListener("dragend", (event, manager2) => {
131
+ if (sortable.isSortable(event.operation.source)) {
132
+ restorePosition(event.operation.source.element);
133
+ }
134
+ const callback = props.onDragEnd;
135
+ if (callback) {
136
+ trackRendering(() => callback(event, manager2));
137
+ }
138
+ clearPosition();
139
+ }), monitor.addEventListener("collision", (event, manager2) => {
140
+ props.onCollision?.(event, manager2);
141
+ }));
142
+ solidJs.onCleanup(() => {
143
+ disposers.forEach((cleanup) => cleanup());
144
+ });
145
+ });
146
+ return web.createComponent(DragDropContext.Provider, {
147
+ get value() {
148
+ return manager();
149
+ },
150
+ get children() {
151
+ return props.children;
152
+ }
153
+ });
154
+ }
155
+ function useDeepSignal(target) {
156
+ const tracked = /* @__PURE__ */ new Map();
157
+ const [dirty, setDirty] = solidJs.createSignal(0);
158
+ solidJs.createEffect(() => {
159
+ const _target = target();
160
+ if (!_target) {
161
+ tracked.clear();
162
+ return;
163
+ }
164
+ const dispose = state.effect(() => {
165
+ let stale = false;
166
+ for (const entry of tracked) {
167
+ const [key] = entry;
168
+ const value = state.untracked(() => entry[1]);
169
+ const latestValue = _target[key];
170
+ if (value !== latestValue) {
171
+ stale = true;
172
+ tracked.set(key, latestValue);
173
+ }
174
+ }
175
+ if (stale) {
176
+ setDirty((v) => v + 1);
177
+ }
178
+ });
179
+ solidJs.onCleanup(dispose);
180
+ });
181
+ return () => {
182
+ const _target = target();
183
+ void dirty();
184
+ return _target ? new Proxy(_target, {
185
+ get(target2, key) {
186
+ const value = target2[key];
187
+ tracked.set(key, value);
188
+ return value;
189
+ }
190
+ }) : _target;
191
+ };
192
+ }
193
+ function useDragDropManager() {
194
+ return solidJs.useContext(DragDropContext);
195
+ }
196
+
197
+ // src/core/hooks/useInstance.ts
198
+ function useInstance(initializer) {
199
+ const manager = useDragDropManager() ?? void 0;
200
+ const instance = initializer(manager);
201
+ solidJs.createEffect(() => {
202
+ instance.manager = manager;
203
+ const cleanup = instance.register();
204
+ solidJs.onCleanup(() => cleanup?.());
205
+ });
206
+ return instance;
207
+ }
208
+
209
+ // src/core/draggable/useDraggable.ts
210
+ function useDraggable(input) {
211
+ const draggable = useInstance(
212
+ (manager) => new dom.Draggable(
213
+ {
214
+ ...input,
215
+ register: false,
216
+ element: input.element,
217
+ handle: input.handle
218
+ },
219
+ manager
220
+ )
221
+ );
222
+ const trackedDraggable = useDeepSignal(() => draggable);
223
+ const [element, setElement] = solidJs.createSignal(
224
+ input.element
225
+ );
226
+ const [handle, setHandle] = solidJs.createSignal(input.handle);
227
+ solidJs.createEffect(() => {
228
+ const el = element();
229
+ if (el) draggable.element = el;
230
+ const h = handle();
231
+ if (h) draggable.handle = h;
232
+ draggable.id = input.id;
233
+ draggable.disabled = input.disabled ?? false;
234
+ draggable.feedback = input.feedback ?? "default";
235
+ draggable.alignment = input.alignment;
236
+ draggable.modifiers = input.modifiers;
237
+ draggable.sensors = input.sensors;
238
+ if (input.data) {
239
+ draggable.data = input.data;
240
+ }
241
+ });
242
+ return {
243
+ get draggable() {
244
+ return draggable;
245
+ },
246
+ isDragging: () => trackedDraggable().isDragging,
247
+ isDropping: () => trackedDraggable().isDropping,
248
+ isDragSource: () => trackedDraggable().isDragSource,
249
+ ref: setElement,
250
+ handleRef: setHandle
251
+ };
252
+ }
253
+
254
+ // src/core/hooks/useDragOperation.ts
255
+ function useDragOperation() {
256
+ const manager = useDragDropManager();
257
+ const trackedDragOperation = useDeepSignal(
258
+ () => manager?.dragOperation
259
+ );
260
+ return {
261
+ source: () => trackedDragOperation()?.source,
262
+ target: () => trackedDragOperation()?.target,
263
+ status: () => trackedDragOperation()?.status
264
+ };
265
+ }
266
+
267
+ // src/core/draggable/DragOverlay.tsx
268
+ function DragOverlay(props) {
269
+ const [element, setElement] = solidJs.createSignal();
270
+ const manager = useDragDropManager();
271
+ const patchedManager = createPatchedManager(() => manager);
272
+ const dragOperation = useDragOperation();
273
+ const source = () => dragOperation.source();
274
+ const isDisabled = () => {
275
+ if (typeof props.disabled === "function") {
276
+ return props.disabled(source());
277
+ }
278
+ return props.disabled ?? false;
279
+ };
280
+ solidJs.createEffect(() => {
281
+ if (!source()) {
282
+ setElement(void 0);
283
+ }
284
+ });
285
+ solidJs.createEffect(() => {
286
+ const _manager = manager;
287
+ if (!_manager || isDisabled()) return;
288
+ const feedback = _manager.plugins.find((plugin) => plugin instanceof dom.Feedback);
289
+ if (!feedback) return;
290
+ feedback.overlay = element();
291
+ solidJs.onCleanup(() => {
292
+ feedback.overlay = void 0;
293
+ });
294
+ });
295
+ return web.createComponent(DragDropContext.Provider, {
296
+ get value() {
297
+ return patchedManager();
298
+ },
299
+ get children() {
300
+ return web.createComponent(solidJs.Show, {
301
+ get when() {
302
+ return web.memo(() => !!!isDisabled())() ? source() : void 0;
303
+ },
304
+ children: (src) => web.createComponent(web.Dynamic, {
305
+ get component() {
306
+ return props.tag || "div";
307
+ },
308
+ get ["class"]() {
309
+ return props.class;
310
+ },
311
+ get style() {
312
+ return props.style;
313
+ },
314
+ "data-dnd-overlay": true,
315
+ ref: setElement,
316
+ get children() {
317
+ return web.memo(() => typeof props.children === "function")() ? props.children(src()) : props.children;
318
+ }
319
+ })
320
+ });
321
+ }
322
+ });
323
+ }
324
+ function createPatchedManager(manager) {
325
+ return solidJs.createMemo(() => {
326
+ const _manager = manager();
327
+ if (!_manager) return null;
328
+ const patchedRegistry = new Proxy(_manager.registry, {
329
+ get(target, property) {
330
+ if (property === "register" || property === "unregister") {
331
+ return noop;
332
+ }
333
+ return target[property];
334
+ }
335
+ });
336
+ return new Proxy(_manager, {
337
+ get(target, property) {
338
+ if (property === "registry") {
339
+ return patchedRegistry;
340
+ }
341
+ return target[property];
342
+ }
343
+ });
344
+ });
345
+ }
346
+ function noop() {
347
+ return () => {
348
+ };
349
+ }
350
+ function useDroppable(input) {
351
+ const droppable = useInstance(
352
+ (manager) => new dom.Droppable(
353
+ {
354
+ ...input,
355
+ register: false,
356
+ element: input.element
357
+ },
358
+ manager
359
+ )
360
+ );
361
+ const trackedDroppable = useDeepSignal(() => droppable);
362
+ const [element, setElement] = solidJs.createSignal(
363
+ input.element
364
+ );
365
+ solidJs.createEffect(() => {
366
+ const el = element();
367
+ if (el) droppable.element = el;
368
+ droppable.id = input.id;
369
+ droppable.accept = input.accept;
370
+ droppable.type = input.type;
371
+ droppable.disabled = input.disabled ?? false;
372
+ if (input.collisionDetector) {
373
+ droppable.collisionDetector = input.collisionDetector;
374
+ }
375
+ if (input.data) {
376
+ droppable.data = input.data;
377
+ }
378
+ });
379
+ return {
380
+ get droppable() {
381
+ return droppable;
382
+ },
383
+ isDropTarget: () => trackedDroppable().isDropTarget,
384
+ ref: setElement
385
+ };
386
+ }
387
+ function useDragDropMonitor(handlers) {
388
+ const manager = useDragDropManager();
389
+ solidJs.createEffect(() => {
390
+ if (!manager) {
391
+ if (process.env.NODE_ENV !== "production") {
392
+ console.warn(
393
+ "useDragDropMonitor hook was called outside of a DragDropProvider. Make sure your app is wrapped in a DragDropProvider component."
394
+ );
395
+ }
396
+ return;
397
+ }
398
+ const cleanupFns = Object.entries(handlers).reduce(
399
+ (acc, [handlerName, handler]) => {
400
+ if (handler) {
401
+ const eventName = handlerName.replace(/^on/, "").toLowerCase();
402
+ const unsubscribe = manager.monitor.addEventListener(
403
+ eventName,
404
+ handler
405
+ );
406
+ acc.push(unsubscribe);
407
+ }
408
+ return acc;
409
+ },
410
+ []
411
+ );
412
+ solidJs.onCleanup(() => cleanupFns.forEach((cleanup) => cleanup()));
413
+ });
414
+ }
415
+
416
+ Object.defineProperty(exports, "KeyboardSensor", {
417
+ enumerable: true,
418
+ get: function () { return dom.KeyboardSensor; }
419
+ });
420
+ Object.defineProperty(exports, "PointerSensor", {
421
+ enumerable: true,
422
+ get: function () { return dom.PointerSensor; }
423
+ });
424
+ exports.DragDropProvider = DragDropProvider;
425
+ exports.DragOverlay = DragOverlay;
426
+ exports.useDragDropManager = useDragDropManager;
427
+ exports.useDragDropMonitor = useDragDropMonitor;
428
+ exports.useDragOperation = useDragOperation;
429
+ exports.useDraggable = useDraggable;
430
+ exports.useDroppable = useDroppable;
431
+ exports.useInstance = useInstance;
432
+ //# sourceMappingURL=index.cjs.map
433
+ //# sourceMappingURL=index.cjs.map
package/index.d.ts ADDED
@@ -0,0 +1,77 @@
1
+ import * as solid_js from 'solid-js';
2
+ import { ParentProps, JSX, ValidComponent } from 'solid-js';
3
+ import * as _dnd_kit_dom from '@dnd-kit/dom';
4
+ import { DragDropManagerInput, DragDropManager, Draggable, Droppable, DraggableInput, DroppableInput } from '@dnd-kit/dom';
5
+ export { DragDropManager, KeyboardSensor, PointerSensor } from '@dnd-kit/dom';
6
+ import * as _dnd_kit_abstract from '@dnd-kit/abstract';
7
+ import { DragDropEvents, Data } from '@dnd-kit/abstract';
8
+ import { CleanupFunction } from '@dnd-kit/state';
9
+
10
+ type Events$1 = DragDropEvents<Draggable, Droppable, DragDropManager>;
11
+ interface DragDropProviderProps extends DragDropManagerInput, ParentProps {
12
+ manager?: DragDropManager;
13
+ onBeforeDragStart?: Events$1['beforedragstart'];
14
+ onCollision?: Events$1['collision'];
15
+ onDragStart?: Events$1['dragstart'];
16
+ onDragMove?: Events$1['dragmove'];
17
+ onDragOver?: Events$1['dragover'];
18
+ onDragEnd?: Events$1['dragend'];
19
+ }
20
+ declare function DragDropProvider(props: DragDropProviderProps): solid_js.JSX.Element;
21
+
22
+ interface UseDraggableInput<T extends Data = Data> extends Omit<DraggableInput<T>, 'handle' | 'element'> {
23
+ handle?: Element;
24
+ element?: Element;
25
+ }
26
+ declare function useDraggable<T extends Data = Data>(input: UseDraggableInput<T>): {
27
+ readonly draggable: Draggable<T>;
28
+ isDragging: () => boolean;
29
+ isDropping: () => boolean;
30
+ isDragSource: () => boolean;
31
+ ref: solid_js.Setter<Element | undefined>;
32
+ handleRef: solid_js.Setter<Element | undefined>;
33
+ };
34
+
35
+ interface DragOverlayProps<T extends Data, U extends Draggable<T>> {
36
+ class?: string;
37
+ children: JSX.Element | ((source: U) => JSX.Element);
38
+ style?: JSX.CSSProperties;
39
+ tag?: ValidComponent;
40
+ disabled?: boolean | ((source: U | null) => boolean);
41
+ }
42
+ declare function DragOverlay<T extends Data, U extends Draggable<T>>(props: DragOverlayProps<T, U>): JSX.Element;
43
+
44
+ interface UseDroppableInput<T extends Data = Data> extends Omit<DroppableInput<T>, 'element'> {
45
+ element?: Element;
46
+ }
47
+ declare function useDroppable<T extends Data = Data>(input: UseDroppableInput<T>): {
48
+ readonly droppable: Droppable<T>;
49
+ isDropTarget: () => boolean;
50
+ ref: solid_js.Setter<Element | undefined>;
51
+ };
52
+
53
+ declare function useDragDropManager(): _dnd_kit_dom.DragDropManager<_dnd_kit_abstract.Data, _dnd_kit_dom.Draggable<_dnd_kit_abstract.Data>, _dnd_kit_dom.Droppable<_dnd_kit_abstract.Data>> | null;
54
+
55
+ type DragDropEventMap = {
56
+ beforedragstart: 'onBeforeDragStart';
57
+ };
58
+ type EventHandlerName<T extends string> = T extends keyof DragDropEventMap ? DragDropEventMap[T] : T extends `drag${infer Second}${infer Rest}` ? `onDrag${Uppercase<Second>}${Rest}` : `on${Capitalize<T>}`;
59
+ type Events<T extends Data, U extends Draggable<T>, V extends Droppable<T>, W extends DragDropManager<T, U, V>> = DragDropEvents<U, V, W>;
60
+ type EventHandlers<T extends Data = Data, U extends Draggable<T> = Draggable<T>, V extends Droppable<T> = Droppable<T>, W extends DragDropManager<T, U, V> = DragDropManager<T, U, V>> = {
61
+ [K in keyof Events<T, U, V, W> as EventHandlerName<K>]?: Events<T, U, V, W>[K];
62
+ };
63
+ declare function useDragDropMonitor<T extends Data = Data, U extends Draggable<T> = Draggable<T>, V extends Droppable<T> = Droppable<T>, W extends DragDropManager<T, U, V> = DragDropManager<T, U, V>>(handlers: EventHandlers<T, U, V, W>): void;
64
+
65
+ declare function useDragOperation(): {
66
+ source: () => _dnd_kit_dom.Draggable<_dnd_kit_abstract.Data> | null | undefined;
67
+ target: () => _dnd_kit_dom.Droppable<_dnd_kit_abstract.Data> | null | undefined;
68
+ status: () => _dnd_kit_abstract.DragOperationStatus | undefined;
69
+ };
70
+
71
+ interface Instance<T extends DragDropManager = DragDropManager> {
72
+ manager: T | undefined;
73
+ register(): CleanupFunction | void;
74
+ }
75
+ declare function useInstance<T extends Instance>(initializer: (manager: DragDropManager | undefined) => T): T;
76
+
77
+ export { type EventHandlers as DragDropEventHandlers, type Events$1 as DragDropEvents, DragDropProvider, type DragDropProviderProps, DragOverlay, type UseDraggableInput, type UseDroppableInput, useDragDropManager, useDragDropMonitor, useDragOperation, useDraggable, useDroppable, useInstance };