@dnd-kit/react 0.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/README.md +17 -0
- package/hooks.cjs +98 -0
- package/hooks.d.ts +25 -0
- package/hooks.js +89 -0
- package/index.cjs +252 -0
- package/index.d.ts +46 -0
- package/index.js +246 -0
- package/package.json +80 -0
- package/sortable.cjs +121 -0
- package/sortable.d.ts +21 -0
- package/sortable.js +119 -0
- package/utilities.cjs +16 -0
- package/utilities.d.ts +6 -0
- package/utilities.js +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @dnd-kit/react
|
|
2
|
+
|
|
3
|
+
[](https://npm.im/@dnd-kit/react)
|
|
4
|
+
|
|
5
|
+
The React layer for @dnd-kit, built on top of @dnd-kit/dom.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
To get started, install the `@dnd-kit/react` package via npm or yarn:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
npm install @dnd-kit/react
|
|
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,98 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var state = require('@dnd-kit/state');
|
|
5
|
+
var reactDom = require('react-dom');
|
|
6
|
+
|
|
7
|
+
// src/hooks/useConstant.ts
|
|
8
|
+
function useConstant(initializer, dependency) {
|
|
9
|
+
const ref = react.useRef();
|
|
10
|
+
const previousDependency = react.useRef(dependency);
|
|
11
|
+
if (!ref.current) {
|
|
12
|
+
ref.current = initializer();
|
|
13
|
+
}
|
|
14
|
+
if (previousDependency.current !== dependency) {
|
|
15
|
+
previousDependency.current = dependency;
|
|
16
|
+
ref.current = initializer();
|
|
17
|
+
}
|
|
18
|
+
return ref.current;
|
|
19
|
+
}
|
|
20
|
+
var canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
21
|
+
var useIsomorphicLayoutEffect = canUseDOM ? react.useLayoutEffect : react.useEffect;
|
|
22
|
+
|
|
23
|
+
// src/hooks/useSignal.ts
|
|
24
|
+
function useSignal(signalOrValue, sync = false) {
|
|
25
|
+
const sig = useConstant(
|
|
26
|
+
() => signalOrValue instanceof state.Signal ? signalOrValue : state.signal(signalOrValue)
|
|
27
|
+
);
|
|
28
|
+
let val = sig.peek();
|
|
29
|
+
const update = react.useState(val)[1];
|
|
30
|
+
useIsomorphicLayoutEffect(
|
|
31
|
+
() => state.effect(() => {
|
|
32
|
+
if (val !== (val = sig.value)) {
|
|
33
|
+
if (sync) {
|
|
34
|
+
reactDom.flushSync(() => update(val));
|
|
35
|
+
} else {
|
|
36
|
+
update(val);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}),
|
|
40
|
+
[sync]
|
|
41
|
+
);
|
|
42
|
+
return sig;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/hooks/useComputed.ts
|
|
46
|
+
function useComputed(compute, sync = false) {
|
|
47
|
+
return useSignal(
|
|
48
|
+
useConstant(() => state.computed(compute)),
|
|
49
|
+
sync
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
function useLatest(value) {
|
|
53
|
+
const valueRef = react.useRef(value);
|
|
54
|
+
useIsomorphicLayoutEffect(() => {
|
|
55
|
+
valueRef.current = value;
|
|
56
|
+
}, [value]);
|
|
57
|
+
return valueRef;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/hooks/useEvent.ts
|
|
61
|
+
function useEvent(handler) {
|
|
62
|
+
const handlerRef = useLatest(handler);
|
|
63
|
+
return react.useCallback(
|
|
64
|
+
function(...args) {
|
|
65
|
+
return handlerRef.current?.(...args);
|
|
66
|
+
},
|
|
67
|
+
[handlerRef]
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/hooks/useImmediateEffect.ts
|
|
72
|
+
function useImmediateEffect(callback, _) {
|
|
73
|
+
callback();
|
|
74
|
+
}
|
|
75
|
+
function useOnValueChange(value, onChange, effect3 = react.useEffect, compare = Object.is) {
|
|
76
|
+
const tracked = react.useRef(value);
|
|
77
|
+
effect3(() => {
|
|
78
|
+
const oldValue = tracked.current;
|
|
79
|
+
if (!compare(value, tracked.current)) {
|
|
80
|
+
tracked.current = value;
|
|
81
|
+
onChange(value, oldValue);
|
|
82
|
+
}
|
|
83
|
+
}, [onChange, value]);
|
|
84
|
+
}
|
|
85
|
+
function useSignalEffect(compute, deps = []) {
|
|
86
|
+
react.useEffect(() => state.effect(compute), deps);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
exports.useComputed = useComputed;
|
|
90
|
+
exports.useConstant = useConstant;
|
|
91
|
+
exports.useEvent = useEvent;
|
|
92
|
+
exports.useImmediateEffect = useImmediateEffect;
|
|
93
|
+
exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
|
|
94
|
+
exports.useLatest = useLatest;
|
|
95
|
+
exports.useOnValueChange = useOnValueChange;
|
|
96
|
+
exports.useSignalEffect = useSignalEffect;
|
|
97
|
+
//# sourceMappingURL=out.js.map
|
|
98
|
+
//# sourceMappingURL=hooks.cjs.map
|
package/hooks.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as _preact_signals_core from '@preact/signals-core';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { EffectCallback, DependencyList, useLayoutEffect, useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
declare function useConstant<T = any>(initializer: () => T, dependency?: any): T;
|
|
6
|
+
|
|
7
|
+
declare function useComputed<T = any>(compute: () => T, sync?: boolean): _preact_signals_core.ReadonlySignal<T>;
|
|
8
|
+
|
|
9
|
+
declare function useEvent<T extends Function>(handler: T | undefined): (...args: any) => any;
|
|
10
|
+
|
|
11
|
+
declare function useImmediateEffect(callback: EffectCallback, _?: DependencyList): void;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A hook that resolves to useEffect on the server and useLayoutEffect on the client
|
|
15
|
+
* @param callback {function} Callback function that is invoked when the dependencies of the hook change
|
|
16
|
+
*/
|
|
17
|
+
declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
|
|
18
|
+
|
|
19
|
+
declare function useLatest<T>(value: T): react.MutableRefObject<T | undefined>;
|
|
20
|
+
|
|
21
|
+
declare function useOnValueChange<T>(value: T, onChange: (value: T, oldValue: T) => void, effect?: typeof useEffect, compare?: (value1: any, value2: any) => boolean): void;
|
|
22
|
+
|
|
23
|
+
declare function useSignalEffect(compute: () => void, deps?: any[]): void;
|
|
24
|
+
|
|
25
|
+
export { useComputed, useConstant, useEvent, useImmediateEffect, useIsomorphicLayoutEffect, useLatest, useOnValueChange, useSignalEffect };
|
package/hooks.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useRef, useLayoutEffect, useEffect, useCallback, useState } from 'react';
|
|
2
|
+
import { computed, effect, Signal, signal } from '@dnd-kit/state';
|
|
3
|
+
import { flushSync } from 'react-dom';
|
|
4
|
+
|
|
5
|
+
// src/hooks/useConstant.ts
|
|
6
|
+
function useConstant(initializer, dependency) {
|
|
7
|
+
const ref = useRef();
|
|
8
|
+
const previousDependency = useRef(dependency);
|
|
9
|
+
if (!ref.current) {
|
|
10
|
+
ref.current = initializer();
|
|
11
|
+
}
|
|
12
|
+
if (previousDependency.current !== dependency) {
|
|
13
|
+
previousDependency.current = dependency;
|
|
14
|
+
ref.current = initializer();
|
|
15
|
+
}
|
|
16
|
+
return ref.current;
|
|
17
|
+
}
|
|
18
|
+
var canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
19
|
+
var useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect;
|
|
20
|
+
|
|
21
|
+
// src/hooks/useSignal.ts
|
|
22
|
+
function useSignal(signalOrValue, sync = false) {
|
|
23
|
+
const sig = useConstant(
|
|
24
|
+
() => signalOrValue instanceof Signal ? signalOrValue : signal(signalOrValue)
|
|
25
|
+
);
|
|
26
|
+
let val = sig.peek();
|
|
27
|
+
const update = useState(val)[1];
|
|
28
|
+
useIsomorphicLayoutEffect(
|
|
29
|
+
() => effect(() => {
|
|
30
|
+
if (val !== (val = sig.value)) {
|
|
31
|
+
if (sync) {
|
|
32
|
+
flushSync(() => update(val));
|
|
33
|
+
} else {
|
|
34
|
+
update(val);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}),
|
|
38
|
+
[sync]
|
|
39
|
+
);
|
|
40
|
+
return sig;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/hooks/useComputed.ts
|
|
44
|
+
function useComputed(compute, sync = false) {
|
|
45
|
+
return useSignal(
|
|
46
|
+
useConstant(() => computed(compute)),
|
|
47
|
+
sync
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
function useLatest(value) {
|
|
51
|
+
const valueRef = useRef(value);
|
|
52
|
+
useIsomorphicLayoutEffect(() => {
|
|
53
|
+
valueRef.current = value;
|
|
54
|
+
}, [value]);
|
|
55
|
+
return valueRef;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/hooks/useEvent.ts
|
|
59
|
+
function useEvent(handler) {
|
|
60
|
+
const handlerRef = useLatest(handler);
|
|
61
|
+
return useCallback(
|
|
62
|
+
function(...args) {
|
|
63
|
+
return handlerRef.current?.(...args);
|
|
64
|
+
},
|
|
65
|
+
[handlerRef]
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/hooks/useImmediateEffect.ts
|
|
70
|
+
function useImmediateEffect(callback, _) {
|
|
71
|
+
callback();
|
|
72
|
+
}
|
|
73
|
+
function useOnValueChange(value, onChange, effect3 = useEffect, compare = Object.is) {
|
|
74
|
+
const tracked = useRef(value);
|
|
75
|
+
effect3(() => {
|
|
76
|
+
const oldValue = tracked.current;
|
|
77
|
+
if (!compare(value, tracked.current)) {
|
|
78
|
+
tracked.current = value;
|
|
79
|
+
onChange(value, oldValue);
|
|
80
|
+
}
|
|
81
|
+
}, [onChange, value]);
|
|
82
|
+
}
|
|
83
|
+
function useSignalEffect(compute, deps = []) {
|
|
84
|
+
useEffect(() => effect(compute), deps);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { useComputed, useConstant, useEvent, useImmediateEffect, useIsomorphicLayoutEffect, useLatest, useOnValueChange, useSignalEffect };
|
|
88
|
+
//# sourceMappingURL=out.js.map
|
|
89
|
+
//# sourceMappingURL=hooks.js.map
|
package/index.cjs
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var dom = require('@dnd-kit/dom');
|
|
5
|
+
var state = require('@dnd-kit/state');
|
|
6
|
+
var reactDom = require('react-dom');
|
|
7
|
+
var hooks = require('@dnd-kit/react/hooks');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
var utilities = require('@dnd-kit/react/utilities');
|
|
10
|
+
|
|
11
|
+
// src/core/context/hooks.ts
|
|
12
|
+
var DragDropContext = react.createContext(
|
|
13
|
+
new dom.DragDropManager()
|
|
14
|
+
);
|
|
15
|
+
function useConstant(initializer, dependency) {
|
|
16
|
+
const ref = react.useRef();
|
|
17
|
+
const previousDependency = react.useRef(dependency);
|
|
18
|
+
if (!ref.current) {
|
|
19
|
+
ref.current = initializer();
|
|
20
|
+
}
|
|
21
|
+
if (previousDependency.current !== dependency) {
|
|
22
|
+
previousDependency.current = dependency;
|
|
23
|
+
ref.current = initializer();
|
|
24
|
+
}
|
|
25
|
+
return ref.current;
|
|
26
|
+
}
|
|
27
|
+
var canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
28
|
+
var useIsomorphicLayoutEffect = canUseDOM ? react.useLayoutEffect : react.useEffect;
|
|
29
|
+
|
|
30
|
+
// src/hooks/useSignal.ts
|
|
31
|
+
function useSignal(signalOrValue, sync = false) {
|
|
32
|
+
const sig = useConstant(
|
|
33
|
+
() => signalOrValue instanceof state.Signal ? signalOrValue : state.signal(signalOrValue)
|
|
34
|
+
);
|
|
35
|
+
let val = sig.peek();
|
|
36
|
+
const update = react.useState(val)[1];
|
|
37
|
+
useIsomorphicLayoutEffect(
|
|
38
|
+
() => state.effect(() => {
|
|
39
|
+
if (val !== (val = sig.value)) {
|
|
40
|
+
if (sync) {
|
|
41
|
+
reactDom.flushSync(() => update(val));
|
|
42
|
+
} else {
|
|
43
|
+
update(val);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
47
|
+
[sync]
|
|
48
|
+
);
|
|
49
|
+
return sig;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/hooks/useComputed.ts
|
|
53
|
+
function useComputed(compute, sync = false) {
|
|
54
|
+
return useSignal(
|
|
55
|
+
useConstant(() => state.computed(compute)),
|
|
56
|
+
sync
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/core/context/hooks.ts
|
|
61
|
+
function useDragDropManager() {
|
|
62
|
+
return react.useContext(DragDropContext);
|
|
63
|
+
}
|
|
64
|
+
function useDragOperation() {
|
|
65
|
+
const manager = useDragDropManager();
|
|
66
|
+
const { dragOperation } = manager;
|
|
67
|
+
const source = useComputed(() => dragOperation.source);
|
|
68
|
+
const target = useComputed(() => dragOperation.target);
|
|
69
|
+
return {
|
|
70
|
+
get source() {
|
|
71
|
+
return source.value;
|
|
72
|
+
},
|
|
73
|
+
get target() {
|
|
74
|
+
return target.value;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function useRenderer() {
|
|
79
|
+
const [_, startTransition] = react.useTransition();
|
|
80
|
+
const [transitionCount, setTransitionCount] = react.useState(0);
|
|
81
|
+
const rendering = react.useRef();
|
|
82
|
+
const resolver = react.useRef();
|
|
83
|
+
const renderer = hooks.useConstant(() => ({
|
|
84
|
+
get rendering() {
|
|
85
|
+
return rendering.current ?? Promise.resolve();
|
|
86
|
+
}
|
|
87
|
+
}));
|
|
88
|
+
hooks.useOnValueChange(transitionCount, () => {
|
|
89
|
+
resolver.current?.();
|
|
90
|
+
rendering.current = void 0;
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
renderer,
|
|
94
|
+
trackRendering(callback) {
|
|
95
|
+
if (!rendering.current) {
|
|
96
|
+
rendering.current = new Promise((resolve) => {
|
|
97
|
+
resolver.current = resolve;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
startTransition(() => {
|
|
101
|
+
callback();
|
|
102
|
+
setTransitionCount((count) => count + 1);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
var DragDropProvider = react.forwardRef(
|
|
108
|
+
function DragDropProvider2({
|
|
109
|
+
children,
|
|
110
|
+
onCollision,
|
|
111
|
+
onBeforeDragStart,
|
|
112
|
+
onDragStart,
|
|
113
|
+
onDragMove,
|
|
114
|
+
onDragOver,
|
|
115
|
+
onDragEnd,
|
|
116
|
+
...input
|
|
117
|
+
}, ref) {
|
|
118
|
+
const { renderer, trackRendering } = useRenderer();
|
|
119
|
+
const manager = hooks.useConstant(() => {
|
|
120
|
+
const instance = input.manager ?? new dom.DragDropManager(input);
|
|
121
|
+
instance.renderer = renderer;
|
|
122
|
+
return instance;
|
|
123
|
+
});
|
|
124
|
+
const { plugins, modifiers } = input;
|
|
125
|
+
const handleBeforeDragStart = hooks.useLatest(onBeforeDragStart);
|
|
126
|
+
const handleDragStart = hooks.useEvent(onDragStart);
|
|
127
|
+
const handleDragOver = hooks.useLatest(onDragOver);
|
|
128
|
+
const handleDragMove = hooks.useLatest(onDragMove);
|
|
129
|
+
const handleDragEnd = hooks.useLatest(onDragEnd);
|
|
130
|
+
const handleCollision = hooks.useEvent(onCollision);
|
|
131
|
+
react.useEffect(() => {
|
|
132
|
+
manager.monitor.addEventListener("beforedragstart", (event, manager2) => {
|
|
133
|
+
const callback = handleBeforeDragStart.current;
|
|
134
|
+
if (callback) {
|
|
135
|
+
trackRendering(() => callback(event, manager2));
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
manager.monitor.addEventListener("dragstart", handleDragStart);
|
|
139
|
+
manager.monitor.addEventListener("dragover", (event, manager2) => {
|
|
140
|
+
const callback = handleDragOver.current;
|
|
141
|
+
if (callback) {
|
|
142
|
+
trackRendering(() => callback(event, manager2));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
manager.monitor.addEventListener("dragmove", (event, manager2) => {
|
|
146
|
+
const callback = handleDragMove.current;
|
|
147
|
+
if (callback) {
|
|
148
|
+
trackRendering(() => callback(event, manager2));
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
manager.monitor.addEventListener("dragend", (event, manager2) => {
|
|
152
|
+
const callback = handleDragEnd.current;
|
|
153
|
+
if (callback) {
|
|
154
|
+
trackRendering(() => callback(event, manager2));
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
manager.monitor.addEventListener("collision", handleCollision);
|
|
158
|
+
return () => {
|
|
159
|
+
manager.destroy();
|
|
160
|
+
};
|
|
161
|
+
}, [manager]);
|
|
162
|
+
hooks.useOnValueChange(
|
|
163
|
+
plugins,
|
|
164
|
+
() => manager.plugins = plugins ?? dom.defaultPreset.plugins
|
|
165
|
+
);
|
|
166
|
+
hooks.useOnValueChange(modifiers, () => manager.modifiers = modifiers ?? []);
|
|
167
|
+
react.useImperativeHandle(ref, () => manager, [manager]);
|
|
168
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DragDropContext.Provider, { value: manager, children });
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
function useDraggable(input) {
|
|
172
|
+
const { disabled, id, sensors } = input;
|
|
173
|
+
const manager = useDragDropManager();
|
|
174
|
+
const handle = utilities.getCurrentValue(input.handle);
|
|
175
|
+
const element = utilities.getCurrentValue(input.element);
|
|
176
|
+
const draggable = hooks.useConstant(
|
|
177
|
+
() => new dom.Draggable({ ...input, handle, element }, manager),
|
|
178
|
+
manager
|
|
179
|
+
);
|
|
180
|
+
const isDragSource = hooks.useComputed(() => draggable.isDragSource);
|
|
181
|
+
hooks.useOnValueChange(id, () => draggable.id = id);
|
|
182
|
+
hooks.useOnValueChange(handle, () => draggable.handle = handle);
|
|
183
|
+
hooks.useOnValueChange(element, () => draggable.element = element);
|
|
184
|
+
hooks.useOnValueChange(disabled, () => draggable.disabled = disabled === true);
|
|
185
|
+
hooks.useOnValueChange(sensors, () => draggable.sensors = sensors);
|
|
186
|
+
hooks.useOnValueChange(
|
|
187
|
+
input.feedback,
|
|
188
|
+
() => draggable.feedback = input.feedback ?? "default"
|
|
189
|
+
);
|
|
190
|
+
react.useEffect(() => {
|
|
191
|
+
return draggable.destroy;
|
|
192
|
+
}, [draggable]);
|
|
193
|
+
return {
|
|
194
|
+
get isDragSource() {
|
|
195
|
+
return isDragSource.value;
|
|
196
|
+
},
|
|
197
|
+
handleRef: react.useCallback(
|
|
198
|
+
(element2) => {
|
|
199
|
+
draggable.handle = element2 ?? void 0;
|
|
200
|
+
},
|
|
201
|
+
[draggable]
|
|
202
|
+
),
|
|
203
|
+
ref: react.useCallback(
|
|
204
|
+
(element2) => {
|
|
205
|
+
draggable.element = element2 ?? void 0;
|
|
206
|
+
},
|
|
207
|
+
[draggable]
|
|
208
|
+
)
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function useDroppable(input) {
|
|
212
|
+
const manager = useDragDropManager();
|
|
213
|
+
const { collisionDetector, disabled, id, accept, type } = input;
|
|
214
|
+
const element = utilities.getCurrentValue(input.element);
|
|
215
|
+
const droppable = hooks.useConstant(
|
|
216
|
+
() => new dom.Droppable({ ...input, element }, manager),
|
|
217
|
+
manager
|
|
218
|
+
);
|
|
219
|
+
const isDisabled = hooks.useComputed(() => droppable.disabled);
|
|
220
|
+
const isDropTarget = hooks.useComputed(() => droppable.isDropTarget);
|
|
221
|
+
hooks.useOnValueChange(id, () => droppable.id = id);
|
|
222
|
+
hooks.useOnValueChange(accept, () => droppable.id = id, void 0, state.deepEqual);
|
|
223
|
+
hooks.useOnValueChange(collisionDetector, () => droppable.id = id);
|
|
224
|
+
hooks.useOnValueChange(disabled, () => droppable.disabled = disabled === true);
|
|
225
|
+
hooks.useOnValueChange(element, () => droppable.element = element);
|
|
226
|
+
hooks.useOnValueChange(type, () => droppable.id = id);
|
|
227
|
+
react.useEffect(() => {
|
|
228
|
+
return droppable.destroy;
|
|
229
|
+
}, [droppable]);
|
|
230
|
+
return {
|
|
231
|
+
get isDisabled() {
|
|
232
|
+
return isDisabled.value;
|
|
233
|
+
},
|
|
234
|
+
get isDropTarget() {
|
|
235
|
+
return isDropTarget.value;
|
|
236
|
+
},
|
|
237
|
+
ref: react.useCallback(
|
|
238
|
+
(element2) => {
|
|
239
|
+
droppable.element = element2 ?? void 0;
|
|
240
|
+
},
|
|
241
|
+
[droppable]
|
|
242
|
+
)
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
exports.DragDropProvider = DragDropProvider;
|
|
247
|
+
exports.useDragDropManager = useDragDropManager;
|
|
248
|
+
exports.useDragOperation = useDragOperation;
|
|
249
|
+
exports.useDraggable = useDraggable;
|
|
250
|
+
exports.useDroppable = useDroppable;
|
|
251
|
+
//# sourceMappingURL=out.js.map
|
|
252
|
+
//# sourceMappingURL=index.cjs.map
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as _dnd_kit_dom from '@dnd-kit/dom';
|
|
2
|
+
import { DragDropManager, Draggable, Droppable, DragDropManagerInput, DraggableInput, DroppableInput } from '@dnd-kit/dom';
|
|
3
|
+
import * as _dnd_kit_abstract from '@dnd-kit/abstract';
|
|
4
|
+
import { DragDropEvents, Data } from '@dnd-kit/abstract';
|
|
5
|
+
import * as react from 'react';
|
|
6
|
+
import { PropsWithChildren } from 'react';
|
|
7
|
+
import { RefOrValue } from '@dnd-kit/react/utilities';
|
|
8
|
+
|
|
9
|
+
declare function useDragDropManager(): _dnd_kit_dom.DragDropManager<_dnd_kit_dom.Draggable<_dnd_kit_abstract.Data>, _dnd_kit_dom.Droppable<_dnd_kit_abstract.Data>>;
|
|
10
|
+
declare function useDragOperation(): {
|
|
11
|
+
readonly source: _dnd_kit_dom.Draggable<_dnd_kit_abstract.Data> | null;
|
|
12
|
+
readonly target: _dnd_kit_dom.Droppable<_dnd_kit_abstract.Data> | null;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type Events = DragDropEvents<Draggable, Droppable, DragDropManager>;
|
|
16
|
+
interface Props extends DragDropManagerInput, PropsWithChildren {
|
|
17
|
+
manager?: DragDropManager;
|
|
18
|
+
onBeforeDragStart?: Events['beforedragstart'];
|
|
19
|
+
onCollision?: Events['collision'];
|
|
20
|
+
onDragStart?: Events['dragstart'];
|
|
21
|
+
onDragMove?: Events['dragmove'];
|
|
22
|
+
onDragOver?: Events['dragover'];
|
|
23
|
+
onDragEnd?: Events['dragend'];
|
|
24
|
+
}
|
|
25
|
+
declare const DragDropProvider: react.ForwardRefExoticComponent<Props & react.RefAttributes<DragDropManager<Draggable<_dnd_kit_abstract.Data>, Droppable<_dnd_kit_abstract.Data>>>>;
|
|
26
|
+
|
|
27
|
+
interface UseDraggableInput<T extends Data = Data> extends Omit<DraggableInput<T>, 'handle' | 'element'> {
|
|
28
|
+
handle?: RefOrValue<Element>;
|
|
29
|
+
element?: RefOrValue<Element>;
|
|
30
|
+
}
|
|
31
|
+
declare function useDraggable<T extends Data = Data>(input: UseDraggableInput<T>): {
|
|
32
|
+
readonly isDragSource: boolean;
|
|
33
|
+
handleRef: (element: Element | null) => void;
|
|
34
|
+
ref: (element: Element | null) => void;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
interface UseDroppableInput<T extends Data = Data> extends Omit<DroppableInput<T>, 'element'> {
|
|
38
|
+
element?: RefOrValue<Element>;
|
|
39
|
+
}
|
|
40
|
+
declare function useDroppable<T extends Data = Data>(input: UseDroppableInput<T>): {
|
|
41
|
+
readonly isDisabled: boolean;
|
|
42
|
+
readonly isDropTarget: boolean;
|
|
43
|
+
ref: (element: Element | null) => void;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { DragDropProvider, useDragDropManager, useDragOperation, useDraggable, useDroppable };
|
package/index.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { createContext, forwardRef, useEffect, useImperativeHandle, useContext, useTransition, useState, useRef, useCallback, useLayoutEffect } from 'react';
|
|
2
|
+
import { DragDropManager, defaultPreset, Draggable, Droppable } from '@dnd-kit/dom';
|
|
3
|
+
import { deepEqual, Signal, signal, effect, computed } from '@dnd-kit/state';
|
|
4
|
+
import { flushSync } from 'react-dom';
|
|
5
|
+
import { useConstant as useConstant$1, useLatest, useEvent, useOnValueChange, useComputed as useComputed$1 } from '@dnd-kit/react/hooks';
|
|
6
|
+
import { jsx } from 'react/jsx-runtime';
|
|
7
|
+
import { getCurrentValue } from '@dnd-kit/react/utilities';
|
|
8
|
+
|
|
9
|
+
// src/core/context/hooks.ts
|
|
10
|
+
var DragDropContext = createContext(
|
|
11
|
+
new DragDropManager()
|
|
12
|
+
);
|
|
13
|
+
function useConstant(initializer, dependency) {
|
|
14
|
+
const ref = useRef();
|
|
15
|
+
const previousDependency = useRef(dependency);
|
|
16
|
+
if (!ref.current) {
|
|
17
|
+
ref.current = initializer();
|
|
18
|
+
}
|
|
19
|
+
if (previousDependency.current !== dependency) {
|
|
20
|
+
previousDependency.current = dependency;
|
|
21
|
+
ref.current = initializer();
|
|
22
|
+
}
|
|
23
|
+
return ref.current;
|
|
24
|
+
}
|
|
25
|
+
var canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
26
|
+
var useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect;
|
|
27
|
+
|
|
28
|
+
// src/hooks/useSignal.ts
|
|
29
|
+
function useSignal(signalOrValue, sync = false) {
|
|
30
|
+
const sig = useConstant(
|
|
31
|
+
() => signalOrValue instanceof Signal ? signalOrValue : signal(signalOrValue)
|
|
32
|
+
);
|
|
33
|
+
let val = sig.peek();
|
|
34
|
+
const update = useState(val)[1];
|
|
35
|
+
useIsomorphicLayoutEffect(
|
|
36
|
+
() => effect(() => {
|
|
37
|
+
if (val !== (val = sig.value)) {
|
|
38
|
+
if (sync) {
|
|
39
|
+
flushSync(() => update(val));
|
|
40
|
+
} else {
|
|
41
|
+
update(val);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}),
|
|
45
|
+
[sync]
|
|
46
|
+
);
|
|
47
|
+
return sig;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/hooks/useComputed.ts
|
|
51
|
+
function useComputed(compute, sync = false) {
|
|
52
|
+
return useSignal(
|
|
53
|
+
useConstant(() => computed(compute)),
|
|
54
|
+
sync
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/core/context/hooks.ts
|
|
59
|
+
function useDragDropManager() {
|
|
60
|
+
return useContext(DragDropContext);
|
|
61
|
+
}
|
|
62
|
+
function useDragOperation() {
|
|
63
|
+
const manager = useDragDropManager();
|
|
64
|
+
const { dragOperation } = manager;
|
|
65
|
+
const source = useComputed(() => dragOperation.source);
|
|
66
|
+
const target = useComputed(() => dragOperation.target);
|
|
67
|
+
return {
|
|
68
|
+
get source() {
|
|
69
|
+
return source.value;
|
|
70
|
+
},
|
|
71
|
+
get target() {
|
|
72
|
+
return target.value;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function useRenderer() {
|
|
77
|
+
const [_, startTransition] = useTransition();
|
|
78
|
+
const [transitionCount, setTransitionCount] = useState(0);
|
|
79
|
+
const rendering = useRef();
|
|
80
|
+
const resolver = useRef();
|
|
81
|
+
const renderer = useConstant$1(() => ({
|
|
82
|
+
get rendering() {
|
|
83
|
+
return rendering.current ?? Promise.resolve();
|
|
84
|
+
}
|
|
85
|
+
}));
|
|
86
|
+
useOnValueChange(transitionCount, () => {
|
|
87
|
+
resolver.current?.();
|
|
88
|
+
rendering.current = void 0;
|
|
89
|
+
});
|
|
90
|
+
return {
|
|
91
|
+
renderer,
|
|
92
|
+
trackRendering(callback) {
|
|
93
|
+
if (!rendering.current) {
|
|
94
|
+
rendering.current = new Promise((resolve) => {
|
|
95
|
+
resolver.current = resolve;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
startTransition(() => {
|
|
99
|
+
callback();
|
|
100
|
+
setTransitionCount((count) => count + 1);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
var DragDropProvider = forwardRef(
|
|
106
|
+
function DragDropProvider2({
|
|
107
|
+
children,
|
|
108
|
+
onCollision,
|
|
109
|
+
onBeforeDragStart,
|
|
110
|
+
onDragStart,
|
|
111
|
+
onDragMove,
|
|
112
|
+
onDragOver,
|
|
113
|
+
onDragEnd,
|
|
114
|
+
...input
|
|
115
|
+
}, ref) {
|
|
116
|
+
const { renderer, trackRendering } = useRenderer();
|
|
117
|
+
const manager = useConstant$1(() => {
|
|
118
|
+
const instance = input.manager ?? new DragDropManager(input);
|
|
119
|
+
instance.renderer = renderer;
|
|
120
|
+
return instance;
|
|
121
|
+
});
|
|
122
|
+
const { plugins, modifiers } = input;
|
|
123
|
+
const handleBeforeDragStart = useLatest(onBeforeDragStart);
|
|
124
|
+
const handleDragStart = useEvent(onDragStart);
|
|
125
|
+
const handleDragOver = useLatest(onDragOver);
|
|
126
|
+
const handleDragMove = useLatest(onDragMove);
|
|
127
|
+
const handleDragEnd = useLatest(onDragEnd);
|
|
128
|
+
const handleCollision = useEvent(onCollision);
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
manager.monitor.addEventListener("beforedragstart", (event, manager2) => {
|
|
131
|
+
const callback = handleBeforeDragStart.current;
|
|
132
|
+
if (callback) {
|
|
133
|
+
trackRendering(() => callback(event, manager2));
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
manager.monitor.addEventListener("dragstart", handleDragStart);
|
|
137
|
+
manager.monitor.addEventListener("dragover", (event, manager2) => {
|
|
138
|
+
const callback = handleDragOver.current;
|
|
139
|
+
if (callback) {
|
|
140
|
+
trackRendering(() => callback(event, manager2));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
manager.monitor.addEventListener("dragmove", (event, manager2) => {
|
|
144
|
+
const callback = handleDragMove.current;
|
|
145
|
+
if (callback) {
|
|
146
|
+
trackRendering(() => callback(event, manager2));
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
manager.monitor.addEventListener("dragend", (event, manager2) => {
|
|
150
|
+
const callback = handleDragEnd.current;
|
|
151
|
+
if (callback) {
|
|
152
|
+
trackRendering(() => callback(event, manager2));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
manager.monitor.addEventListener("collision", handleCollision);
|
|
156
|
+
return () => {
|
|
157
|
+
manager.destroy();
|
|
158
|
+
};
|
|
159
|
+
}, [manager]);
|
|
160
|
+
useOnValueChange(
|
|
161
|
+
plugins,
|
|
162
|
+
() => manager.plugins = plugins ?? defaultPreset.plugins
|
|
163
|
+
);
|
|
164
|
+
useOnValueChange(modifiers, () => manager.modifiers = modifiers ?? []);
|
|
165
|
+
useImperativeHandle(ref, () => manager, [manager]);
|
|
166
|
+
return /* @__PURE__ */ jsx(DragDropContext.Provider, { value: manager, children });
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
function useDraggable(input) {
|
|
170
|
+
const { disabled, id, sensors } = input;
|
|
171
|
+
const manager = useDragDropManager();
|
|
172
|
+
const handle = getCurrentValue(input.handle);
|
|
173
|
+
const element = getCurrentValue(input.element);
|
|
174
|
+
const draggable = useConstant$1(
|
|
175
|
+
() => new Draggable({ ...input, handle, element }, manager),
|
|
176
|
+
manager
|
|
177
|
+
);
|
|
178
|
+
const isDragSource = useComputed$1(() => draggable.isDragSource);
|
|
179
|
+
useOnValueChange(id, () => draggable.id = id);
|
|
180
|
+
useOnValueChange(handle, () => draggable.handle = handle);
|
|
181
|
+
useOnValueChange(element, () => draggable.element = element);
|
|
182
|
+
useOnValueChange(disabled, () => draggable.disabled = disabled === true);
|
|
183
|
+
useOnValueChange(sensors, () => draggable.sensors = sensors);
|
|
184
|
+
useOnValueChange(
|
|
185
|
+
input.feedback,
|
|
186
|
+
() => draggable.feedback = input.feedback ?? "default"
|
|
187
|
+
);
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
return draggable.destroy;
|
|
190
|
+
}, [draggable]);
|
|
191
|
+
return {
|
|
192
|
+
get isDragSource() {
|
|
193
|
+
return isDragSource.value;
|
|
194
|
+
},
|
|
195
|
+
handleRef: useCallback(
|
|
196
|
+
(element2) => {
|
|
197
|
+
draggable.handle = element2 ?? void 0;
|
|
198
|
+
},
|
|
199
|
+
[draggable]
|
|
200
|
+
),
|
|
201
|
+
ref: useCallback(
|
|
202
|
+
(element2) => {
|
|
203
|
+
draggable.element = element2 ?? void 0;
|
|
204
|
+
},
|
|
205
|
+
[draggable]
|
|
206
|
+
)
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function useDroppable(input) {
|
|
210
|
+
const manager = useDragDropManager();
|
|
211
|
+
const { collisionDetector, disabled, id, accept, type } = input;
|
|
212
|
+
const element = getCurrentValue(input.element);
|
|
213
|
+
const droppable = useConstant$1(
|
|
214
|
+
() => new Droppable({ ...input, element }, manager),
|
|
215
|
+
manager
|
|
216
|
+
);
|
|
217
|
+
const isDisabled = useComputed$1(() => droppable.disabled);
|
|
218
|
+
const isDropTarget = useComputed$1(() => droppable.isDropTarget);
|
|
219
|
+
useOnValueChange(id, () => droppable.id = id);
|
|
220
|
+
useOnValueChange(accept, () => droppable.id = id, void 0, deepEqual);
|
|
221
|
+
useOnValueChange(collisionDetector, () => droppable.id = id);
|
|
222
|
+
useOnValueChange(disabled, () => droppable.disabled = disabled === true);
|
|
223
|
+
useOnValueChange(element, () => droppable.element = element);
|
|
224
|
+
useOnValueChange(type, () => droppable.id = id);
|
|
225
|
+
useEffect(() => {
|
|
226
|
+
return droppable.destroy;
|
|
227
|
+
}, [droppable]);
|
|
228
|
+
return {
|
|
229
|
+
get isDisabled() {
|
|
230
|
+
return isDisabled.value;
|
|
231
|
+
},
|
|
232
|
+
get isDropTarget() {
|
|
233
|
+
return isDropTarget.value;
|
|
234
|
+
},
|
|
235
|
+
ref: useCallback(
|
|
236
|
+
(element2) => {
|
|
237
|
+
droppable.element = element2 ?? void 0;
|
|
238
|
+
},
|
|
239
|
+
[droppable]
|
|
240
|
+
)
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export { DragDropProvider, useDragDropManager, useDragOperation, useDraggable, useDroppable };
|
|
245
|
+
//# sourceMappingURL=out.js.map
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dnd-kit/react",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "./index.cjs",
|
|
5
|
+
"module": "./index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "./index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"files": [
|
|
11
|
+
"LICENSE",
|
|
12
|
+
"README.md",
|
|
13
|
+
"index.js",
|
|
14
|
+
"index.d.ts",
|
|
15
|
+
"index.cjs",
|
|
16
|
+
"hooks.js",
|
|
17
|
+
"hooks.d.ts",
|
|
18
|
+
"hooks.cjs",
|
|
19
|
+
"sortable.js",
|
|
20
|
+
"sortable.d.ts",
|
|
21
|
+
"sortable.cjs",
|
|
22
|
+
"utilities.js",
|
|
23
|
+
"utilities.d.ts",
|
|
24
|
+
"utilities.cjs"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./index.d.ts",
|
|
29
|
+
"import": "./index.js",
|
|
30
|
+
"require": "./index.cjs"
|
|
31
|
+
},
|
|
32
|
+
"./hooks": {
|
|
33
|
+
"types": "./hooks.d.ts",
|
|
34
|
+
"import": "./hooks.js",
|
|
35
|
+
"require": "./hooks.cjs"
|
|
36
|
+
},
|
|
37
|
+
"./sortable": {
|
|
38
|
+
"types": "./sortable.d.ts",
|
|
39
|
+
"import": "./sortable.js",
|
|
40
|
+
"require": "./sortable.cjs"
|
|
41
|
+
},
|
|
42
|
+
"./utilities": {
|
|
43
|
+
"types": "./utilities.d.ts",
|
|
44
|
+
"import": "./utilities.js",
|
|
45
|
+
"require": "./utilities.cjs"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "bun build:hooks && bun build:utilities && bun build:core && bun build:sortable",
|
|
50
|
+
"build:core": "tsup src/core/index.ts",
|
|
51
|
+
"build:hooks": "tsup --entry.hooks src/hooks/index.ts",
|
|
52
|
+
"build:sortable": "tsup --entry.sortable src/sortable/index.ts",
|
|
53
|
+
"build:utilities": "tsup --entry.utilities src/utilities/index.ts",
|
|
54
|
+
"dev": "bun build:hooks --watch & bun build:utilities --watch & bun build:core --watch & bun build:sortable --watch",
|
|
55
|
+
"lint": "TIMING=1 eslint src/**/*.ts* --fix",
|
|
56
|
+
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@dnd-kit/abstract": "*",
|
|
60
|
+
"@dnd-kit/dom": "*",
|
|
61
|
+
"@dnd-kit/state": "*",
|
|
62
|
+
"tslib": "^2.6.2"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"react": "^18.0.0",
|
|
66
|
+
"react-dom": "^18.0.0"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@types/react": "^18.0.9",
|
|
70
|
+
"@types/react-dom": "^18.0.4",
|
|
71
|
+
"eslint": "^8.38.0",
|
|
72
|
+
"@dnd-kit/eslint-config": "*",
|
|
73
|
+
"react": "^18.1.0",
|
|
74
|
+
"tsup": "^7.2.0",
|
|
75
|
+
"typescript": "^5.1.6"
|
|
76
|
+
},
|
|
77
|
+
"publishConfig": {
|
|
78
|
+
"access": "public"
|
|
79
|
+
}
|
|
80
|
+
}
|
package/sortable.cjs
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react$1 = require('react');
|
|
4
|
+
var state = require('@dnd-kit/state');
|
|
5
|
+
var sortable = require('@dnd-kit/dom/sortable');
|
|
6
|
+
var react = require('@dnd-kit/react');
|
|
7
|
+
var hooks = require('@dnd-kit/react/hooks');
|
|
8
|
+
var utilities = require('@dnd-kit/react/utilities');
|
|
9
|
+
|
|
10
|
+
// src/sortable/useSortable.ts
|
|
11
|
+
function useSortable(input) {
|
|
12
|
+
const {
|
|
13
|
+
accept,
|
|
14
|
+
collisionDetector,
|
|
15
|
+
collisionPriority,
|
|
16
|
+
id,
|
|
17
|
+
data,
|
|
18
|
+
index,
|
|
19
|
+
disabled,
|
|
20
|
+
sensors,
|
|
21
|
+
transition = sortable.defaultSortableTransition,
|
|
22
|
+
type
|
|
23
|
+
} = input;
|
|
24
|
+
const feedback = typeof input.feedback === "function" ? "none" : input.feedback;
|
|
25
|
+
const manager = react.useDragDropManager();
|
|
26
|
+
const handle = utilities.getCurrentValue(input.handle);
|
|
27
|
+
const element = utilities.getCurrentValue(input.element);
|
|
28
|
+
const sortable$1 = hooks.useConstant(
|
|
29
|
+
() => new sortable.Sortable(
|
|
30
|
+
{
|
|
31
|
+
...input,
|
|
32
|
+
handle,
|
|
33
|
+
element,
|
|
34
|
+
feedback
|
|
35
|
+
},
|
|
36
|
+
manager
|
|
37
|
+
),
|
|
38
|
+
manager
|
|
39
|
+
);
|
|
40
|
+
const isDisabled = hooks.useComputed(() => sortable$1.disabled);
|
|
41
|
+
const isDropTarget = hooks.useComputed(() => sortable$1.isDropTarget);
|
|
42
|
+
const isDragSource = hooks.useComputed(() => sortable$1.isDragSource);
|
|
43
|
+
hooks.useOnValueChange(
|
|
44
|
+
accept,
|
|
45
|
+
() => sortable$1.accept = accept,
|
|
46
|
+
void 0,
|
|
47
|
+
state.deepEqual
|
|
48
|
+
);
|
|
49
|
+
hooks.useOnValueChange(type, () => sortable$1.type = type);
|
|
50
|
+
hooks.useOnValueChange(id, () => sortable$1.id = id);
|
|
51
|
+
hooks.useOnValueChange(data, () => sortable$1.data = data ?? null);
|
|
52
|
+
hooks.useOnValueChange(
|
|
53
|
+
index,
|
|
54
|
+
() => {
|
|
55
|
+
if (manager.dragOperation.status.idle && transition) {
|
|
56
|
+
sortable$1.refreshShape();
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
hooks.useImmediateEffect
|
|
60
|
+
);
|
|
61
|
+
hooks.useOnValueChange(index, () => sortable$1.index = index, hooks.useIsomorphicLayoutEffect);
|
|
62
|
+
hooks.useOnValueChange(handle, () => sortable$1.handle = handle);
|
|
63
|
+
hooks.useOnValueChange(element, () => sortable$1.element = element);
|
|
64
|
+
hooks.useOnValueChange(disabled, () => sortable$1.disabled = disabled === true);
|
|
65
|
+
hooks.useOnValueChange(sensors, () => sortable$1.sensors = sensors);
|
|
66
|
+
hooks.useOnValueChange(
|
|
67
|
+
collisionDetector,
|
|
68
|
+
() => sortable$1.collisionDetector = collisionDetector
|
|
69
|
+
);
|
|
70
|
+
hooks.useOnValueChange(
|
|
71
|
+
collisionPriority,
|
|
72
|
+
() => sortable$1.collisionPriority = collisionPriority
|
|
73
|
+
);
|
|
74
|
+
hooks.useOnValueChange(
|
|
75
|
+
input.feedback,
|
|
76
|
+
() => sortable$1.feedback = feedback ?? "default"
|
|
77
|
+
);
|
|
78
|
+
hooks.useOnValueChange(transition, () => sortable$1.transition = transition);
|
|
79
|
+
react$1.useEffect(() => {
|
|
80
|
+
return sortable$1.destroy;
|
|
81
|
+
}, [sortable$1]);
|
|
82
|
+
return {
|
|
83
|
+
get isDisabled() {
|
|
84
|
+
return isDisabled.value;
|
|
85
|
+
},
|
|
86
|
+
get isDragSource() {
|
|
87
|
+
return isDragSource.value;
|
|
88
|
+
},
|
|
89
|
+
get isDropTarget() {
|
|
90
|
+
return isDropTarget.value;
|
|
91
|
+
},
|
|
92
|
+
handleRef: react$1.useCallback(
|
|
93
|
+
(element2) => {
|
|
94
|
+
sortable$1.handle = element2 ?? void 0;
|
|
95
|
+
},
|
|
96
|
+
[sortable$1]
|
|
97
|
+
),
|
|
98
|
+
ref: react$1.useCallback(
|
|
99
|
+
(element2) => {
|
|
100
|
+
sortable$1.element = element2 ?? void 0;
|
|
101
|
+
},
|
|
102
|
+
[sortable$1]
|
|
103
|
+
),
|
|
104
|
+
sourceRef: react$1.useCallback(
|
|
105
|
+
(element2) => {
|
|
106
|
+
sortable$1.source = element2 ?? void 0;
|
|
107
|
+
},
|
|
108
|
+
[sortable$1]
|
|
109
|
+
),
|
|
110
|
+
targetRef: react$1.useCallback(
|
|
111
|
+
(element2) => {
|
|
112
|
+
sortable$1.target = element2 ?? void 0;
|
|
113
|
+
},
|
|
114
|
+
[sortable$1]
|
|
115
|
+
)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
exports.useSortable = useSortable;
|
|
120
|
+
//# sourceMappingURL=out.js.map
|
|
121
|
+
//# sourceMappingURL=sortable.cjs.map
|
package/sortable.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Data } from '@dnd-kit/abstract';
|
|
2
|
+
import { SortableInput } from '@dnd-kit/dom/sortable';
|
|
3
|
+
import { RefOrValue } from '@dnd-kit/react/utilities';
|
|
4
|
+
import { FeedbackType } from '@dnd-kit/dom';
|
|
5
|
+
|
|
6
|
+
interface UseSortableInput<T extends Data = Data> extends Omit<SortableInput<T>, 'handle' | 'element' | 'feedback'> {
|
|
7
|
+
handle?: RefOrValue<Element>;
|
|
8
|
+
element?: RefOrValue<Element>;
|
|
9
|
+
feedback?: FeedbackType | (() => React.ReactNode);
|
|
10
|
+
}
|
|
11
|
+
declare function useSortable<T extends Data = Data>(input: UseSortableInput<T>): {
|
|
12
|
+
readonly isDisabled: boolean;
|
|
13
|
+
readonly isDragSource: boolean;
|
|
14
|
+
readonly isDropTarget: boolean;
|
|
15
|
+
handleRef: (element: Element | null) => void;
|
|
16
|
+
ref: (element: Element | null) => void;
|
|
17
|
+
sourceRef: (element: Element | null) => void;
|
|
18
|
+
targetRef: (element: Element | null) => void;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { UseSortableInput, useSortable };
|
package/sortable.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { useEffect, useCallback } from 'react';
|
|
2
|
+
import { deepEqual } from '@dnd-kit/state';
|
|
3
|
+
import { Sortable, defaultSortableTransition } from '@dnd-kit/dom/sortable';
|
|
4
|
+
import { useDragDropManager } from '@dnd-kit/react';
|
|
5
|
+
import { useConstant, useComputed, useOnValueChange, useImmediateEffect, useIsomorphicLayoutEffect } from '@dnd-kit/react/hooks';
|
|
6
|
+
import { getCurrentValue } from '@dnd-kit/react/utilities';
|
|
7
|
+
|
|
8
|
+
// src/sortable/useSortable.ts
|
|
9
|
+
function useSortable(input) {
|
|
10
|
+
const {
|
|
11
|
+
accept,
|
|
12
|
+
collisionDetector,
|
|
13
|
+
collisionPriority,
|
|
14
|
+
id,
|
|
15
|
+
data,
|
|
16
|
+
index,
|
|
17
|
+
disabled,
|
|
18
|
+
sensors,
|
|
19
|
+
transition = defaultSortableTransition,
|
|
20
|
+
type
|
|
21
|
+
} = input;
|
|
22
|
+
const feedback = typeof input.feedback === "function" ? "none" : input.feedback;
|
|
23
|
+
const manager = useDragDropManager();
|
|
24
|
+
const handle = getCurrentValue(input.handle);
|
|
25
|
+
const element = getCurrentValue(input.element);
|
|
26
|
+
const sortable = useConstant(
|
|
27
|
+
() => new Sortable(
|
|
28
|
+
{
|
|
29
|
+
...input,
|
|
30
|
+
handle,
|
|
31
|
+
element,
|
|
32
|
+
feedback
|
|
33
|
+
},
|
|
34
|
+
manager
|
|
35
|
+
),
|
|
36
|
+
manager
|
|
37
|
+
);
|
|
38
|
+
const isDisabled = useComputed(() => sortable.disabled);
|
|
39
|
+
const isDropTarget = useComputed(() => sortable.isDropTarget);
|
|
40
|
+
const isDragSource = useComputed(() => sortable.isDragSource);
|
|
41
|
+
useOnValueChange(
|
|
42
|
+
accept,
|
|
43
|
+
() => sortable.accept = accept,
|
|
44
|
+
void 0,
|
|
45
|
+
deepEqual
|
|
46
|
+
);
|
|
47
|
+
useOnValueChange(type, () => sortable.type = type);
|
|
48
|
+
useOnValueChange(id, () => sortable.id = id);
|
|
49
|
+
useOnValueChange(data, () => sortable.data = data ?? null);
|
|
50
|
+
useOnValueChange(
|
|
51
|
+
index,
|
|
52
|
+
() => {
|
|
53
|
+
if (manager.dragOperation.status.idle && transition) {
|
|
54
|
+
sortable.refreshShape();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
useImmediateEffect
|
|
58
|
+
);
|
|
59
|
+
useOnValueChange(index, () => sortable.index = index, useIsomorphicLayoutEffect);
|
|
60
|
+
useOnValueChange(handle, () => sortable.handle = handle);
|
|
61
|
+
useOnValueChange(element, () => sortable.element = element);
|
|
62
|
+
useOnValueChange(disabled, () => sortable.disabled = disabled === true);
|
|
63
|
+
useOnValueChange(sensors, () => sortable.sensors = sensors);
|
|
64
|
+
useOnValueChange(
|
|
65
|
+
collisionDetector,
|
|
66
|
+
() => sortable.collisionDetector = collisionDetector
|
|
67
|
+
);
|
|
68
|
+
useOnValueChange(
|
|
69
|
+
collisionPriority,
|
|
70
|
+
() => sortable.collisionPriority = collisionPriority
|
|
71
|
+
);
|
|
72
|
+
useOnValueChange(
|
|
73
|
+
input.feedback,
|
|
74
|
+
() => sortable.feedback = feedback ?? "default"
|
|
75
|
+
);
|
|
76
|
+
useOnValueChange(transition, () => sortable.transition = transition);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
return sortable.destroy;
|
|
79
|
+
}, [sortable]);
|
|
80
|
+
return {
|
|
81
|
+
get isDisabled() {
|
|
82
|
+
return isDisabled.value;
|
|
83
|
+
},
|
|
84
|
+
get isDragSource() {
|
|
85
|
+
return isDragSource.value;
|
|
86
|
+
},
|
|
87
|
+
get isDropTarget() {
|
|
88
|
+
return isDropTarget.value;
|
|
89
|
+
},
|
|
90
|
+
handleRef: useCallback(
|
|
91
|
+
(element2) => {
|
|
92
|
+
sortable.handle = element2 ?? void 0;
|
|
93
|
+
},
|
|
94
|
+
[sortable]
|
|
95
|
+
),
|
|
96
|
+
ref: useCallback(
|
|
97
|
+
(element2) => {
|
|
98
|
+
sortable.element = element2 ?? void 0;
|
|
99
|
+
},
|
|
100
|
+
[sortable]
|
|
101
|
+
),
|
|
102
|
+
sourceRef: useCallback(
|
|
103
|
+
(element2) => {
|
|
104
|
+
sortable.source = element2 ?? void 0;
|
|
105
|
+
},
|
|
106
|
+
[sortable]
|
|
107
|
+
),
|
|
108
|
+
targetRef: useCallback(
|
|
109
|
+
(element2) => {
|
|
110
|
+
sortable.target = element2 ?? void 0;
|
|
111
|
+
},
|
|
112
|
+
[sortable]
|
|
113
|
+
)
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export { useSortable };
|
|
118
|
+
//# sourceMappingURL=out.js.map
|
|
119
|
+
//# sourceMappingURL=sortable.js.map
|
package/utilities.cjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/utilities/getCurrentValue.ts
|
|
4
|
+
function getCurrentValue(value) {
|
|
5
|
+
if (value == null) {
|
|
6
|
+
return void 0;
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === "object" && "current" in value) {
|
|
9
|
+
return value.current ?? void 0;
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.getCurrentValue = getCurrentValue;
|
|
15
|
+
//# sourceMappingURL=out.js.map
|
|
16
|
+
//# sourceMappingURL=utilities.cjs.map
|
package/utilities.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { RefObject, MutableRefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
type RefOrValue<T> = T | RefObject<T | null | undefined> | MutableRefObject<T> | null | undefined;
|
|
4
|
+
declare function getCurrentValue<T>(value: RefOrValue<T>): NonNullable<T> | undefined;
|
|
5
|
+
|
|
6
|
+
export { RefOrValue, getCurrentValue };
|
package/utilities.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/utilities/getCurrentValue.ts
|
|
2
|
+
function getCurrentValue(value) {
|
|
3
|
+
if (value == null) {
|
|
4
|
+
return void 0;
|
|
5
|
+
}
|
|
6
|
+
if (typeof value === "object" && "current" in value) {
|
|
7
|
+
return value.current ?? void 0;
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { getCurrentValue };
|
|
13
|
+
//# sourceMappingURL=out.js.map
|
|
14
|
+
//# sourceMappingURL=utilities.js.map
|