@dnd-kit/react 0.0.8-beta-20250202144138 → 0.0.8-beta-20250203030431
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/hooks.cjs +52 -9
- package/hooks.d.ts +4 -1
- package/hooks.js +54 -12
- package/index.cjs +34 -0
- package/index.d.ts +10 -4
- package/index.js +37 -4
- package/package.json +4 -4
package/hooks.cjs
CHANGED
|
@@ -14,29 +14,38 @@ function useConstant(initializer) {
|
|
|
14
14
|
}
|
|
15
15
|
var canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
16
16
|
var useIsomorphicLayoutEffect = canUseDOM ? react.useLayoutEffect : react.useEffect;
|
|
17
|
+
function useForceUpdate() {
|
|
18
|
+
const setState = react.useState(0)[1];
|
|
19
|
+
return react.useCallback(() => {
|
|
20
|
+
setState((value) => value + 1);
|
|
21
|
+
}, [setState]);
|
|
22
|
+
}
|
|
17
23
|
|
|
18
24
|
// src/hooks/useSignal.ts
|
|
19
25
|
function useSignal(signal, sync = false) {
|
|
20
|
-
|
|
26
|
+
const previous = react.useRef(signal.peek());
|
|
21
27
|
const read = react.useRef(false);
|
|
22
|
-
const
|
|
28
|
+
const forceUpdate = useForceUpdate();
|
|
23
29
|
useIsomorphicLayoutEffect(
|
|
24
30
|
() => state.effect(() => {
|
|
25
|
-
|
|
31
|
+
const previousValue = previous.current;
|
|
32
|
+
const currentValue2 = signal.value;
|
|
33
|
+
if (previousValue !== currentValue2) {
|
|
34
|
+
previous.current = currentValue2;
|
|
26
35
|
if (!read.current) return;
|
|
27
36
|
if (sync) {
|
|
28
|
-
reactDom.flushSync(
|
|
37
|
+
reactDom.flushSync(forceUpdate);
|
|
29
38
|
} else {
|
|
30
|
-
|
|
39
|
+
forceUpdate();
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
}),
|
|
34
|
-
[signal, sync]
|
|
43
|
+
[signal, sync, forceUpdate]
|
|
35
44
|
);
|
|
36
45
|
return {
|
|
37
46
|
get value() {
|
|
38
47
|
read.current = true;
|
|
39
|
-
return signal.
|
|
48
|
+
return signal.peek();
|
|
40
49
|
}
|
|
41
50
|
};
|
|
42
51
|
}
|
|
@@ -50,6 +59,39 @@ function useComputed(compute, dependencies = [], sync = false) {
|
|
|
50
59
|
sync
|
|
51
60
|
);
|
|
52
61
|
}
|
|
62
|
+
function useDeepSignal(target) {
|
|
63
|
+
const tracked = react.useRef(/* @__PURE__ */ new Map());
|
|
64
|
+
const forceUpdate = useForceUpdate();
|
|
65
|
+
useIsomorphicLayoutEffect(() => {
|
|
66
|
+
if (!target) {
|
|
67
|
+
tracked.current.clear();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
return state.effect(() => {
|
|
71
|
+
let stale = false;
|
|
72
|
+
for (const entry of tracked.current) {
|
|
73
|
+
const [key] = entry;
|
|
74
|
+
const value = state.untracked(() => entry[1]);
|
|
75
|
+
const latestValue = target[key];
|
|
76
|
+
if (value !== latestValue) {
|
|
77
|
+
stale = true;
|
|
78
|
+
tracked.current.set(key, latestValue);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (stale) forceUpdate();
|
|
82
|
+
});
|
|
83
|
+
}, [target]);
|
|
84
|
+
return react.useMemo(
|
|
85
|
+
() => target ? new Proxy(target, {
|
|
86
|
+
get(target2, key) {
|
|
87
|
+
const value = target2[key];
|
|
88
|
+
tracked.current.set(key, value);
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
}) : target,
|
|
92
|
+
[target]
|
|
93
|
+
);
|
|
94
|
+
}
|
|
53
95
|
|
|
54
96
|
// src/hooks/useImmediateEffect.ts
|
|
55
97
|
function useImmediateEffect(callback, _) {
|
|
@@ -62,9 +104,9 @@ function useLatest(value) {
|
|
|
62
104
|
}, [value]);
|
|
63
105
|
return valueRef;
|
|
64
106
|
}
|
|
65
|
-
function useOnValueChange(value, onChange,
|
|
107
|
+
function useOnValueChange(value, onChange, effect3 = react.useEffect, compare = Object.is) {
|
|
66
108
|
const tracked = react.useRef(value);
|
|
67
|
-
|
|
109
|
+
effect3(() => {
|
|
68
110
|
const oldValue = tracked.current;
|
|
69
111
|
if (!compare(value, oldValue)) {
|
|
70
112
|
tracked.current = value;
|
|
@@ -85,6 +127,7 @@ function useOnElementChange(value, onChange) {
|
|
|
85
127
|
|
|
86
128
|
exports.useComputed = useComputed;
|
|
87
129
|
exports.useConstant = useConstant;
|
|
130
|
+
exports.useDeepSignal = useDeepSignal;
|
|
88
131
|
exports.useImmediateEffect = useImmediateEffect;
|
|
89
132
|
exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
|
|
90
133
|
exports.useLatest = useLatest;
|
package/hooks.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ declare function useComputed<T = any>(compute: () => T, dependencies?: any[], sy
|
|
|
8
8
|
readonly value: T;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
/** Trigger a re-render when reading signal properties of an object. */
|
|
12
|
+
declare function useDeepSignal<T extends object | null | undefined>(target: T): T;
|
|
13
|
+
|
|
11
14
|
declare function useImmediateEffect(callback: EffectCallback, _?: DependencyList): void;
|
|
12
15
|
|
|
13
16
|
/**
|
|
@@ -22,4 +25,4 @@ declare function useOnValueChange<T>(value: T, onChange: (value: T, oldValue: T)
|
|
|
22
25
|
|
|
23
26
|
declare function useOnElementChange(value: RefOrValue<Element>, onChange: (value: Element | undefined) => void): void;
|
|
24
27
|
|
|
25
|
-
export { useComputed, useConstant, useImmediateEffect, useIsomorphicLayoutEffect, useLatest, useOnElementChange, useOnValueChange };
|
|
28
|
+
export { useComputed, useConstant, useDeepSignal, useImmediateEffect, useIsomorphicLayoutEffect, useLatest, useOnElementChange, useOnValueChange };
|
package/hooks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useRef, useLayoutEffect, useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import { computed, effect } from '@dnd-kit/state';
|
|
1
|
+
import { useRef, useLayoutEffect, useEffect, useMemo, useState, useCallback } from 'react';
|
|
2
|
+
import { computed, effect, untracked } from '@dnd-kit/state';
|
|
3
3
|
import { flushSync } from 'react-dom';
|
|
4
4
|
import { currentValue } from '@dnd-kit/react/utilities';
|
|
5
5
|
|
|
@@ -12,29 +12,38 @@ function useConstant(initializer) {
|
|
|
12
12
|
}
|
|
13
13
|
var canUseDOM = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
14
14
|
var useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect;
|
|
15
|
+
function useForceUpdate() {
|
|
16
|
+
const setState = useState(0)[1];
|
|
17
|
+
return useCallback(() => {
|
|
18
|
+
setState((value) => value + 1);
|
|
19
|
+
}, [setState]);
|
|
20
|
+
}
|
|
15
21
|
|
|
16
22
|
// src/hooks/useSignal.ts
|
|
17
23
|
function useSignal(signal, sync = false) {
|
|
18
|
-
|
|
24
|
+
const previous = useRef(signal.peek());
|
|
19
25
|
const read = useRef(false);
|
|
20
|
-
const
|
|
26
|
+
const forceUpdate = useForceUpdate();
|
|
21
27
|
useIsomorphicLayoutEffect(
|
|
22
28
|
() => effect(() => {
|
|
23
|
-
|
|
29
|
+
const previousValue = previous.current;
|
|
30
|
+
const currentValue2 = signal.value;
|
|
31
|
+
if (previousValue !== currentValue2) {
|
|
32
|
+
previous.current = currentValue2;
|
|
24
33
|
if (!read.current) return;
|
|
25
34
|
if (sync) {
|
|
26
|
-
flushSync(
|
|
35
|
+
flushSync(forceUpdate);
|
|
27
36
|
} else {
|
|
28
|
-
|
|
37
|
+
forceUpdate();
|
|
29
38
|
}
|
|
30
39
|
}
|
|
31
40
|
}),
|
|
32
|
-
[signal, sync]
|
|
41
|
+
[signal, sync, forceUpdate]
|
|
33
42
|
);
|
|
34
43
|
return {
|
|
35
44
|
get value() {
|
|
36
45
|
read.current = true;
|
|
37
|
-
return signal.
|
|
46
|
+
return signal.peek();
|
|
38
47
|
}
|
|
39
48
|
};
|
|
40
49
|
}
|
|
@@ -48,6 +57,39 @@ function useComputed(compute, dependencies = [], sync = false) {
|
|
|
48
57
|
sync
|
|
49
58
|
);
|
|
50
59
|
}
|
|
60
|
+
function useDeepSignal(target) {
|
|
61
|
+
const tracked = useRef(/* @__PURE__ */ new Map());
|
|
62
|
+
const forceUpdate = useForceUpdate();
|
|
63
|
+
useIsomorphicLayoutEffect(() => {
|
|
64
|
+
if (!target) {
|
|
65
|
+
tracked.current.clear();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
return effect(() => {
|
|
69
|
+
let stale = false;
|
|
70
|
+
for (const entry of tracked.current) {
|
|
71
|
+
const [key] = entry;
|
|
72
|
+
const value = untracked(() => entry[1]);
|
|
73
|
+
const latestValue = target[key];
|
|
74
|
+
if (value !== latestValue) {
|
|
75
|
+
stale = true;
|
|
76
|
+
tracked.current.set(key, latestValue);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (stale) forceUpdate();
|
|
80
|
+
});
|
|
81
|
+
}, [target]);
|
|
82
|
+
return useMemo(
|
|
83
|
+
() => target ? new Proxy(target, {
|
|
84
|
+
get(target2, key) {
|
|
85
|
+
const value = target2[key];
|
|
86
|
+
tracked.current.set(key, value);
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
}) : target,
|
|
90
|
+
[target]
|
|
91
|
+
);
|
|
92
|
+
}
|
|
51
93
|
|
|
52
94
|
// src/hooks/useImmediateEffect.ts
|
|
53
95
|
function useImmediateEffect(callback, _) {
|
|
@@ -60,9 +102,9 @@ function useLatest(value) {
|
|
|
60
102
|
}, [value]);
|
|
61
103
|
return valueRef;
|
|
62
104
|
}
|
|
63
|
-
function useOnValueChange(value, onChange,
|
|
105
|
+
function useOnValueChange(value, onChange, effect3 = useEffect, compare = Object.is) {
|
|
64
106
|
const tracked = useRef(value);
|
|
65
|
-
|
|
107
|
+
effect3(() => {
|
|
66
108
|
const oldValue = tracked.current;
|
|
67
109
|
if (!compare(value, oldValue)) {
|
|
68
110
|
tracked.current = value;
|
|
@@ -81,6 +123,6 @@ function useOnElementChange(value, onChange) {
|
|
|
81
123
|
});
|
|
82
124
|
}
|
|
83
125
|
|
|
84
|
-
export { useComputed, useConstant, useImmediateEffect, useIsomorphicLayoutEffect, useLatest, useOnElementChange, useOnValueChange };
|
|
126
|
+
export { useComputed, useConstant, useDeepSignal, useImmediateEffect, useIsomorphicLayoutEffect, useLatest, useOnElementChange, useOnValueChange };
|
|
85
127
|
//# sourceMappingURL=hooks.js.map
|
|
86
128
|
//# sourceMappingURL=hooks.js.map
|
package/index.cjs
CHANGED
|
@@ -245,6 +245,39 @@ function useDraggable(input) {
|
|
|
245
245
|
)
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
|
+
function DragOverlay({ children, className }) {
|
|
249
|
+
const ref = react.useRef(null);
|
|
250
|
+
const manager = useDragDropManager();
|
|
251
|
+
const source = hooks.useComputed(
|
|
252
|
+
() => manager == null ? void 0 : manager.dragOperation.source,
|
|
253
|
+
[manager]
|
|
254
|
+
).value;
|
|
255
|
+
react.useEffect(() => {
|
|
256
|
+
if (!ref.current || !manager) return;
|
|
257
|
+
const feedback = manager.plugins.find(
|
|
258
|
+
(plugin) => plugin instanceof dom.Feedback
|
|
259
|
+
);
|
|
260
|
+
if (!feedback) return;
|
|
261
|
+
feedback.overlay = ref.current;
|
|
262
|
+
return () => {
|
|
263
|
+
feedback.overlay = void 0;
|
|
264
|
+
};
|
|
265
|
+
}, [manager]);
|
|
266
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, ref, "data-dnd-overlay": true, children: renderChildren() });
|
|
267
|
+
function renderChildren() {
|
|
268
|
+
if (!source) return null;
|
|
269
|
+
if (typeof children === "function") {
|
|
270
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Children, { source, children });
|
|
271
|
+
}
|
|
272
|
+
return children;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function Children({
|
|
276
|
+
children,
|
|
277
|
+
source
|
|
278
|
+
}) {
|
|
279
|
+
return children(hooks.useDeepSignal(source));
|
|
280
|
+
}
|
|
248
281
|
function useDroppable(input) {
|
|
249
282
|
const { collisionDetector, data, disabled, element, id, accept, type } = input;
|
|
250
283
|
const droppable = useInstance(
|
|
@@ -295,6 +328,7 @@ function useDragOperation() {
|
|
|
295
328
|
}
|
|
296
329
|
|
|
297
330
|
exports.DragDropProvider = DragDropProvider;
|
|
331
|
+
exports.DragOverlay = DragOverlay;
|
|
298
332
|
exports.useDragDropManager = useDragDropManager;
|
|
299
333
|
exports.useDragOperation = useDragOperation;
|
|
300
334
|
exports.useDraggable = useDraggable;
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { PropsWithChildren, ReactNode } from 'react';
|
|
3
3
|
import * as _dnd_kit_abstract from '@dnd-kit/abstract';
|
|
4
4
|
import { DragDropEvents, Data, DragDropManager as DragDropManager$1 } from '@dnd-kit/abstract';
|
|
5
5
|
import * as _dnd_kit_dom from '@dnd-kit/dom';
|
|
@@ -8,7 +8,7 @@ import { RefOrValue } from '@dnd-kit/react/utilities';
|
|
|
8
8
|
import { CleanupFunction } from '@dnd-kit/state';
|
|
9
9
|
|
|
10
10
|
type Events = DragDropEvents<Draggable, Droppable, DragDropManager>;
|
|
11
|
-
interface Props extends DragDropManagerInput, PropsWithChildren {
|
|
11
|
+
interface Props$1 extends DragDropManagerInput, PropsWithChildren {
|
|
12
12
|
manager?: DragDropManager;
|
|
13
13
|
onBeforeDragStart?: Events['beforedragstart'];
|
|
14
14
|
onCollision?: Events['collision'];
|
|
@@ -17,7 +17,7 @@ interface Props extends DragDropManagerInput, PropsWithChildren {
|
|
|
17
17
|
onDragOver?: Events['dragover'];
|
|
18
18
|
onDragEnd?: Events['dragend'];
|
|
19
19
|
}
|
|
20
|
-
declare function DragDropProvider({ children, onCollision, onBeforeDragStart, onDragStart, onDragMove, onDragOver, onDragEnd, ...input }: Props): react_jsx_runtime.JSX.Element;
|
|
20
|
+
declare function DragDropProvider({ children, onCollision, onBeforeDragStart, onDragStart, onDragMove, onDragOver, onDragEnd, ...input }: Props$1): react_jsx_runtime.JSX.Element;
|
|
21
21
|
|
|
22
22
|
interface UseDraggableInput<T extends Data = Data> extends Omit<DraggableInput<T>, 'handle' | 'element'> {
|
|
23
23
|
handle?: RefOrValue<Element>;
|
|
@@ -31,6 +31,12 @@ declare function useDraggable<T extends Data = Data>(input: UseDraggableInput<T>
|
|
|
31
31
|
ref: (element: Element | null) => void;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
interface Props {
|
|
35
|
+
className?: string;
|
|
36
|
+
children: ReactNode | ((source: Draggable) => ReactNode);
|
|
37
|
+
}
|
|
38
|
+
declare function DragOverlay({ children, className }: Props): react_jsx_runtime.JSX.Element;
|
|
39
|
+
|
|
34
40
|
interface UseDroppableInput<T extends Data = Data> extends Omit<DroppableInput<T>, 'element'> {
|
|
35
41
|
element?: RefOrValue<Element>;
|
|
36
42
|
}
|
|
@@ -53,4 +59,4 @@ interface Instance<T extends DragDropManager$1<any, any> = DragDropManager$1<any
|
|
|
53
59
|
}
|
|
54
60
|
declare function useInstance<T extends Instance>(initializer: (manager: DragDropManager$1<any, any> | undefined) => T): T;
|
|
55
61
|
|
|
56
|
-
export { DragDropProvider, type UseDraggableInput, type UseDroppableInput, useDragDropManager, useDragOperation, useDraggable, useDroppable, useInstance };
|
|
62
|
+
export { DragDropProvider, DragOverlay, type UseDraggableInput, type UseDroppableInput, useDragDropManager, useDragOperation, useDraggable, useDroppable, useInstance };
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createContext, useState, useEffect, startTransition, useContext, useCallback,
|
|
2
|
-
import { DragDropManager, defaultPreset, Draggable, Droppable } from '@dnd-kit/dom';
|
|
3
|
-
import { useLatest, useOnValueChange, useIsomorphicLayoutEffect, useComputed, useOnElementChange, useConstant } from '@dnd-kit/react/hooks';
|
|
1
|
+
import { createContext, useState, useEffect, startTransition, useContext, useCallback, useRef, useTransition, useLayoutEffect } from 'react';
|
|
2
|
+
import { DragDropManager, defaultPreset, Draggable, Feedback, Droppable } from '@dnd-kit/dom';
|
|
3
|
+
import { useLatest, useOnValueChange, useIsomorphicLayoutEffect, useComputed, useOnElementChange, useDeepSignal, useConstant } from '@dnd-kit/react/hooks';
|
|
4
4
|
import { deepEqual } from '@dnd-kit/state';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
6
6
|
import { currentValue } from '@dnd-kit/react/utilities';
|
|
@@ -243,6 +243,39 @@ function useDraggable(input) {
|
|
|
243
243
|
)
|
|
244
244
|
};
|
|
245
245
|
}
|
|
246
|
+
function DragOverlay({ children, className }) {
|
|
247
|
+
const ref = useRef(null);
|
|
248
|
+
const manager = useDragDropManager();
|
|
249
|
+
const source = useComputed(
|
|
250
|
+
() => manager == null ? void 0 : manager.dragOperation.source,
|
|
251
|
+
[manager]
|
|
252
|
+
).value;
|
|
253
|
+
useEffect(() => {
|
|
254
|
+
if (!ref.current || !manager) return;
|
|
255
|
+
const feedback = manager.plugins.find(
|
|
256
|
+
(plugin) => plugin instanceof Feedback
|
|
257
|
+
);
|
|
258
|
+
if (!feedback) return;
|
|
259
|
+
feedback.overlay = ref.current;
|
|
260
|
+
return () => {
|
|
261
|
+
feedback.overlay = void 0;
|
|
262
|
+
};
|
|
263
|
+
}, [manager]);
|
|
264
|
+
return /* @__PURE__ */ jsx("div", { className, ref, "data-dnd-overlay": true, children: renderChildren() });
|
|
265
|
+
function renderChildren() {
|
|
266
|
+
if (!source) return null;
|
|
267
|
+
if (typeof children === "function") {
|
|
268
|
+
return /* @__PURE__ */ jsx(Children, { source, children });
|
|
269
|
+
}
|
|
270
|
+
return children;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function Children({
|
|
274
|
+
children,
|
|
275
|
+
source
|
|
276
|
+
}) {
|
|
277
|
+
return children(useDeepSignal(source));
|
|
278
|
+
}
|
|
246
279
|
function useDroppable(input) {
|
|
247
280
|
const { collisionDetector, data, disabled, element, id, accept, type } = input;
|
|
248
281
|
const droppable = useInstance(
|
|
@@ -292,6 +325,6 @@ function useDragOperation() {
|
|
|
292
325
|
};
|
|
293
326
|
}
|
|
294
327
|
|
|
295
|
-
export { DragDropProvider, useDragDropManager, useDragOperation, useDraggable, useDroppable, useInstance };
|
|
328
|
+
export { DragDropProvider, DragOverlay, useDragDropManager, useDragOperation, useDraggable, useDroppable, useInstance };
|
|
296
329
|
//# sourceMappingURL=index.js.map
|
|
297
330
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dnd-kit/react",
|
|
3
|
-
"version": "0.0.8-beta-
|
|
3
|
+
"version": "0.0.8-beta-20250203030431",
|
|
4
4
|
"main": "./index.cjs",
|
|
5
5
|
"module": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@dnd-kit/abstract": "0.0.8-beta-
|
|
60
|
-
"@dnd-kit/dom": "0.0.8-beta-
|
|
61
|
-
"@dnd-kit/state": "0.0.8-beta-
|
|
59
|
+
"@dnd-kit/abstract": "0.0.8-beta-20250203030431",
|
|
60
|
+
"@dnd-kit/dom": "0.0.8-beta-20250203030431",
|
|
61
|
+
"@dnd-kit/state": "0.0.8-beta-20250203030431",
|
|
62
62
|
"tslib": "^2.6.2"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|