From 7e58836b581f21a3c783a9f78fd6b1c6bf1634bd Mon Sep 17 00:00:00 2001 From: Evgeni Dimov Date: Tue, 12 Dec 2023 10:02:42 +0200 Subject: [PATCH 1/2] adds hover.atTop check in computeDrop --- packages/react-arborist/src/dnd/compute-drop.ts | 7 +++++-- packages/react-arborist/src/dnd/drop-hook.ts | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/react-arborist/src/dnd/compute-drop.ts b/packages/react-arborist/src/dnd/compute-drop.ts index c492aa8..75d9204 100644 --- a/packages/react-arborist/src/dnd/compute-drop.ts +++ b/packages/react-arborist/src/dnd/compute-drop.ts @@ -151,8 +151,11 @@ export function computeDrop(args: Args): ComputedDrop { }; } - /* The above node is an item or a closed folder */ - if (isItem(above) || isClosed(above)) { + /** + * The above node is an item, a closed folder or hovering over + * the top of next node, proposing to append as next sibling. + */ + if (isItem(above) || isClosed(above) || hover.atTop) { const level = getDropLevel(hover, above, below, args.indent); return { drop: walkUpFrom(above, level), diff --git a/packages/react-arborist/src/dnd/drop-hook.ts b/packages/react-arborist/src/dnd/drop-hook.ts index 6be259d..9938bdf 100644 --- a/packages/react-arborist/src/dnd/drop-hook.ts +++ b/packages/react-arborist/src/dnd/drop-hook.ts @@ -20,9 +20,9 @@ export function useDropHook( () => ({ accept: "NODE", canDrop: () => tree.canDrop(), - hover: (_item, m) => { + hover: (item, m) => { const offset = m.getClientOffset(); - if (!el.current || !offset) return; + if (!el.current || !offset || item.id === node.id) return; const { cursor, drop } = computeDrop({ element: el.current, offset: offset, From c9af3ab34ab5f91015ded71459f6f1307a2164af Mon Sep 17 00:00:00 2001 From: Evgeni Dimov Date: Wed, 13 Dec 2023 12:42:11 +0200 Subject: [PATCH 2/2] adds isOpenWithEmptyChildren to hover.atTop check on computeDrop --- packages/react-arborist/src/dnd/compute-drop.ts | 4 ++-- packages/react-arborist/src/utils.ts | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-arborist/src/dnd/compute-drop.ts b/packages/react-arborist/src/dnd/compute-drop.ts index 75d9204..c5357fe 100644 --- a/packages/react-arborist/src/dnd/compute-drop.ts +++ b/packages/react-arborist/src/dnd/compute-drop.ts @@ -1,6 +1,6 @@ import { XYCoord } from "react-dnd"; import { NodeApi } from "../interfaces/node-api"; -import { bound, indexOf, isClosed, isItem } from "../utils"; +import { bound, indexOf, isClosed, isItem, isOpenWithEmptyChildren } from "../utils"; import { DropResult } from "./drop-hook"; function measureHover(el: HTMLElement, offset: XYCoord) { @@ -155,7 +155,7 @@ export function computeDrop(args: Args): ComputedDrop { * The above node is an item, a closed folder or hovering over * the top of next node, proposing to append as next sibling. */ - if (isItem(above) || isClosed(above) || hover.atTop) { + if (isItem(above) || isClosed(above) || (!below && hover.inBottomHalf) || (hover.atTop && isOpenWithEmptyChildren(above))) { const level = getDropLevel(hover, above, below, args.indent); return { drop: walkUpFrom(above, level), diff --git a/packages/react-arborist/src/utils.ts b/packages/react-arborist/src/utils.ts index aeec8e0..4d69307 100644 --- a/packages/react-arborist/src/utils.ts +++ b/packages/react-arborist/src/utils.ts @@ -14,6 +14,10 @@ export function isClosed(node: NodeApi | null) { return node && node.isInternal && !node.isOpen; } +export function isOpenWithEmptyChildren(node: NodeApi | null) { + return node && node.isOpen && !node.children?.length; +} + /** * Is first param a descendant of the second param */