From d969e1540dd7e4de5d91333b387577e7595e31e9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 May 2022 19:14:12 +0100 Subject: [PATCH] Add initial work on component drag and drop refactor --- .../src/components/common/NavItem.svelte | 1 + .../navigation/ComponentTree.svelte | 57 ++++++++++++------- .../_components/navigation/dragDropStore.js | 35 ++++-------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/packages/builder/src/components/common/NavItem.svelte b/packages/builder/src/components/common/NavItem.svelte index 5b8c416260..f0c447826e 100644 --- a/packages/builder/src/components/common/NavItem.svelte +++ b/packages/builder/src/components/common/NavItem.svelte @@ -138,6 +138,7 @@ overflow: hidden; position: relative; padding-left: var(--spacing-l); + pointer-events: none; } /* Needed to fully display the actions icon */ diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentTree.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentTree.svelte index fc5e5fb148..d7e6500dd1 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentTree.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentTree.svelte @@ -19,6 +19,7 @@ export let dragDropStore let closedNodes = {} + let indicatorY = 0 const dragstart = component => e => { e.dataTransfer.dropEffect = DropEffect.MOVE @@ -29,18 +30,19 @@ const definition = store.actions.components.getDefinition( component._component ) - const canHaveChildrenButIsEmpty = - definition?.hasChildren && !component._children?.length + const canHaveChildren = definition?.hasChildren e.dataTransfer.dropEffect = DropEffect.COPY // how far down the mouse pointer is on the drop target const mousePosition = e.offsetY / e.currentTarget.offsetHeight + indicatorY = e.currentTarget.offsetTop + dragDropStore.actions.dragover({ component, index, - canHaveChildrenButIsEmpty, + canHaveChildren, mousePosition, }) @@ -62,9 +64,13 @@ return def?.icon } - const componentHasChildren = component => { + const componentSupportsChildren = component => { const def = store.actions.components.getDefinition(component?._component) - return def?.hasChildren && component._children?.length + return def?.hasChildren + } + + const componentHasChildren = component => { + return componentSupportsChildren(component) && component._children?.length } function toggleNodeOpen(componentId) { @@ -111,13 +117,17 @@ $store.selectedComponentId = component._id }} > - {#if $dragDropStore?.targetComponent === component && $dragDropStore.dropPosition === DropPosition.ABOVE} + {#if dragDropStore && $dragDropStore?.targetComponent === component}
{/if} @@ -148,18 +158,6 @@ level={level + 1} /> {/if} - - {#if $dragDropStore?.targetComponent === component && ($dragDropStore.dropPosition === DropPosition.INSIDE || $dragDropStore.dropPosition === DropPosition.BELOW)} -
- {/if} {/each} @@ -183,8 +181,25 @@ } .drop-item { - border-radius: var(--border-radius-m); + height: 2px; + background: green; + z-index: 999; + position: absolute; + top: calc(var(--indicatorY) - 1px); + left: var(--indicatorX); + width: 100px; + } + .drop-item.above { + background: red; + } + .drop-item.below { + background: blue; + margin-top: 32px; + } + .drop-item.inside { + background: transparent; + border: 2px solid green; height: 32px; - background: var(--grey-3); + pointer-events: none; } diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/dragDropStore.js b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/dragDropStore.js index d965a2456d..3355c876bc 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/dragDropStore.js +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/dragDropStore.js @@ -23,44 +23,29 @@ export default function () { return state }) }, - dragover: ({ - component, - index, - canHaveChildrenButIsEmpty, - mousePosition, - }) => { + dragover: ({ component, canHaveChildren, mousePosition }) => { store.update(state => { state.targetComponent = component // only allow dropping inside when container is empty // if container has children, drag over them - if (canHaveChildrenButIsEmpty && index === 0) { - // hovered above center of target - if (mousePosition < 0.4) { + if (canHaveChildren) { + if (mousePosition <= 0.33) { + // hovered above center of target state.dropPosition = DropPosition.ABOVE - } - - // hovered around bottom of target - if (mousePosition > 0.8) { + } else if (mousePosition >= 0.66) { + // hovered around bottom of target state.dropPosition = DropPosition.BELOW - } - - // hovered in center of target - if (mousePosition > 0.4 && mousePosition < 0.8) { + } else { + // hovered in center of target state.dropPosition = DropPosition.INSIDE } return state } // bottom half - if (mousePosition > 0.5) { - state.dropPosition = DropPosition.BELOW - } else { - state.dropPosition = canHaveChildrenButIsEmpty - ? DropPosition.INSIDE - : DropPosition.ABOVE - } - + state.dropPosition = + mousePosition > 0.5 ? DropPosition.BELOW : DropPosition.ABOVE return state }) },