Update component drag and drop to perform better

This commit is contained in:
Andrew Kingston 2022-05-22 15:34:06 +01:00
parent 12858c2b0f
commit e11c210bf5
3 changed files with 27 additions and 20 deletions

View File

@ -507,7 +507,7 @@ export const getFrontendStore = () => {
} }
await store.actions.preview.saveSelected() await store.actions.preview.saveSelected()
}, },
copy: (component, cut = false) => { copy: (component, cut = false, selectParent = true) => {
const selectedAsset = get(currentAsset) const selectedAsset = get(currentAsset)
if (!selectedAsset) { if (!selectedAsset) {
return null return null
@ -527,12 +527,14 @@ export const getFrontendStore = () => {
parent._children = parent._children.filter( parent._children = parent._children.filter(
child => child._id !== component._id child => child._id !== component._id
) )
if (selectParent) {
store.update(state => { store.update(state => {
state.selectedComponentId = parent._id state.selectedComponentId = parent._id
return state return state
}) })
} }
} }
}
}, },
paste: async (targetComponent, mode) => { paste: async (targetComponent, mode) => {
let promises = [] let promises = []

View File

@ -31,6 +31,7 @@
component._component component._component
) )
const canHaveChildren = definition?.hasChildren const canHaveChildren = definition?.hasChildren
const hasChildren = componentHasChildren(component)
e.dataTransfer.dropEffect = DropEffect.COPY e.dataTransfer.dropEffect = DropEffect.COPY
@ -43,6 +44,7 @@
component, component,
index, index,
canHaveChildren, canHaveChildren,
hasChildren,
mousePosition, mousePosition,
}) })
@ -122,6 +124,7 @@
class:above={$dragDropStore.dropPosition === DropPosition.ABOVE} class:above={$dragDropStore.dropPosition === DropPosition.ABOVE}
class:below={$dragDropStore.dropPosition === DropPosition.BELOW} class:below={$dragDropStore.dropPosition === DropPosition.BELOW}
class:inside={$dragDropStore.dropPosition === DropPosition.INSIDE} class:inside={$dragDropStore.dropPosition === DropPosition.INSIDE}
class:hasChildren={componentHasChildren(component)}
on:drop={onDrop} on:drop={onDrop}
ondragover="return false" ondragover="return false"
ondragenter="return false" ondragenter="return false"
@ -187,7 +190,7 @@
position: absolute; position: absolute;
top: calc(var(--indicatorY) - 1px); top: calc(var(--indicatorY) - 1px);
left: var(--indicatorX); left: var(--indicatorX);
width: 100px; width: calc(100% - var(--indicatorX));
border-radius: 4px; border-radius: 4px;
} }
.drop-item.above { .drop-item.above {
@ -200,5 +203,6 @@
border: 2px solid var(--spectrum-global-color-static-green-500); border: 2px solid var(--spectrum-global-color-static-green-500);
height: 29px; height: 29px;
pointer-events: none; pointer-events: none;
width: calc(100% - var(--indicatorX) - 4px);
} }
</style> </style>

View File

@ -23,29 +23,30 @@ export default function () {
return state return state
}) })
}, },
dragover: ({ component, canHaveChildren, mousePosition }) => { dragover: ({ component, canHaveChildren, hasChildren, mousePosition }) => {
store.update(state => { store.update(state => {
state.targetComponent = component
// only allow dropping inside when container is empty
// if container has children, drag over them
if (canHaveChildren) { if (canHaveChildren) {
if (mousePosition <= 0.33) { if (mousePosition <= 0.33) {
// hovered above center of target
state.dropPosition = DropPosition.ABOVE state.dropPosition = DropPosition.ABOVE
} else if (mousePosition >= 0.66) { } else if (mousePosition >= 0.66) {
// hovered around bottom of target
state.dropPosition = DropPosition.BELOW state.dropPosition = DropPosition.BELOW
} else { } else {
// hovered in center of target
state.dropPosition = DropPosition.INSIDE state.dropPosition = DropPosition.INSIDE
} }
return state } else {
}
// bottom half
state.dropPosition = state.dropPosition =
mousePosition > 0.5 ? DropPosition.BELOW : DropPosition.ABOVE mousePosition > 0.5 ? DropPosition.BELOW : DropPosition.ABOVE
}
// If hovering over a component with children and attempting to drop
// below, we need to change this to be above the first child instead
if (state.dropPosition === DropPosition.BELOW && hasChildren) {
state.targetComponent = component._children[0]
state.dropPosition = DropPosition.ABOVE
} else {
state.targetComponent = component
}
return state return state
}) })
}, },
@ -76,7 +77,7 @@ export default function () {
} }
// Cut and paste the component // Cut and paste the component
frontendStore.actions.components.copy(state.dragged, true) frontendStore.actions.components.copy(state.dragged, true, false)
await frontendStore.actions.components.paste( await frontendStore.actions.components.paste(
state.targetComponent, state.targetComponent,
state.dropPosition state.dropPosition