dnd-block-tree 0.2.0 → 0.3.0
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 +9 -0
- package/dist/index.js +25 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# dnd-block-tree
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/dnd-block-tree)
|
|
4
|
+
[](https://www.npmjs.com/package/dnd-block-tree)
|
|
5
|
+
[](https://bundlephobia.com/package/dnd-block-tree)
|
|
6
|
+
[](https://github.com/thesandybridge/dnd-block-tree/actions/workflows/ci.yml)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://dnd-block-tree.vercel.app)
|
|
10
|
+
|
|
3
11
|
A headless React library for building hierarchical drag-and-drop interfaces. Bring your own components, we handle the complexity.
|
|
4
12
|
|
|
5
13
|
## Features
|
|
@@ -7,6 +15,7 @@ A headless React library for building hierarchical drag-and-drop interfaces. Bri
|
|
|
7
15
|
- **Stable Drop Zones** - Zones render based on original block positions, not preview state, ensuring consistent drop targets during drag
|
|
8
16
|
- **Ghost Preview** - Semi-transparent preview shows where blocks will land without affecting zone positions
|
|
9
17
|
- **Depth-Aware Collision** - Smart algorithm prefers nested zones when cursor is at indented levels, with hysteresis to prevent flickering
|
|
18
|
+
- **Mobile & Touch Support** - Separate touch/pointer activation constraints prevent interference with scrolling on mobile devices
|
|
10
19
|
- **8px Activation Distance** - Prevents accidental drags. Pointer must move 8px before drag starts, allowing normal clicks
|
|
11
20
|
- **Snapshot-Based Computation** - State captured at drag start. All preview computations use snapshot, ensuring consistent behavior
|
|
12
21
|
- **Debounced Preview** - 150ms debounced virtual state for smooth drag previews without jitter
|
package/dist/index.js
CHANGED
|
@@ -122,23 +122,29 @@ function useConfiguredSensors(config = {}) {
|
|
|
122
122
|
activationDelay,
|
|
123
123
|
tolerance
|
|
124
124
|
} = config;
|
|
125
|
-
let
|
|
125
|
+
let pointerConstraint;
|
|
126
|
+
let touchConstraint;
|
|
126
127
|
if (activationDelay !== void 0) {
|
|
127
|
-
|
|
128
|
+
pointerConstraint = {
|
|
128
129
|
delay: activationDelay,
|
|
129
130
|
tolerance: tolerance ?? 5
|
|
130
131
|
};
|
|
132
|
+
touchConstraint = pointerConstraint;
|
|
131
133
|
} else {
|
|
132
|
-
|
|
134
|
+
pointerConstraint = {
|
|
133
135
|
distance: activationDistance
|
|
134
136
|
};
|
|
137
|
+
touchConstraint = {
|
|
138
|
+
delay: 200,
|
|
139
|
+
tolerance: 5
|
|
140
|
+
};
|
|
135
141
|
}
|
|
136
142
|
return core.useSensors(
|
|
137
143
|
core.useSensor(core.PointerSensor, {
|
|
138
|
-
activationConstraint
|
|
144
|
+
activationConstraint: pointerConstraint
|
|
139
145
|
}),
|
|
140
146
|
core.useSensor(core.TouchSensor, {
|
|
141
|
-
activationConstraint
|
|
147
|
+
activationConstraint: touchConstraint
|
|
142
148
|
}),
|
|
143
149
|
core.useSensor(core.KeyboardSensor)
|
|
144
150
|
);
|
|
@@ -232,7 +238,16 @@ function DraggableBlock({
|
|
|
232
238
|
id: block.id,
|
|
233
239
|
disabled
|
|
234
240
|
});
|
|
235
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
241
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
242
|
+
"div",
|
|
243
|
+
{
|
|
244
|
+
ref: setNodeRef,
|
|
245
|
+
...attributes,
|
|
246
|
+
...listeners,
|
|
247
|
+
style: { touchAction: "none", minWidth: 0 },
|
|
248
|
+
children: children({ isDragging })
|
|
249
|
+
}
|
|
250
|
+
);
|
|
236
251
|
}
|
|
237
252
|
function TreeRenderer({
|
|
238
253
|
blocks,
|
|
@@ -257,7 +272,7 @@ function TreeRenderer({
|
|
|
257
272
|
const filteredBlocks = items.filter((block) => block.id !== activeId);
|
|
258
273
|
const showGhostHere = previewPosition?.parentId === parentId && draggedBlock;
|
|
259
274
|
const containerClass = depth === 0 ? rootClassName : indentClassName;
|
|
260
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: containerClass, children: [
|
|
275
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: containerClass, style: { minWidth: 0 }, children: [
|
|
261
276
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
262
277
|
DropZone,
|
|
263
278
|
{
|
|
@@ -283,7 +298,7 @@ function TreeRenderer({
|
|
|
283
298
|
}
|
|
284
299
|
const GhostRenderer = draggedBlock ? renderers[draggedBlock.type] : null;
|
|
285
300
|
return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
286
|
-
ghostBeforeThis && GhostRenderer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 pointer-events-none", children: GhostRenderer({
|
|
301
|
+
ghostBeforeThis && GhostRenderer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 pointer-events-none", style: { minWidth: 0 }, children: GhostRenderer({
|
|
287
302
|
block: draggedBlock,
|
|
288
303
|
isDragging: true,
|
|
289
304
|
depth
|
|
@@ -342,7 +357,7 @@ function TreeRenderer({
|
|
|
342
357
|
}),
|
|
343
358
|
showGhostHere && previewPosition.index >= filteredBlocks.length && draggedBlock && (() => {
|
|
344
359
|
const GhostRenderer = renderers[draggedBlock.type];
|
|
345
|
-
return GhostRenderer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 pointer-events-none", children: GhostRenderer({
|
|
360
|
+
return GhostRenderer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 pointer-events-none", style: { minWidth: 0 }, children: GhostRenderer({
|
|
346
361
|
block: draggedBlock,
|
|
347
362
|
isDragging: true,
|
|
348
363
|
depth
|
|
@@ -782,7 +797,7 @@ function BlockTree({
|
|
|
782
797
|
onDragEnd: handleDragEnd,
|
|
783
798
|
onDragCancel: handleDragCancel,
|
|
784
799
|
children: [
|
|
785
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
800
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { minWidth: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
786
801
|
TreeRenderer,
|
|
787
802
|
{
|
|
788
803
|
blocks,
|