diff --git a/packages/canvas/src/components/container/CanvasAction.vue b/packages/canvas/src/components/container/CanvasAction.vue index 5008e1c468..0697f220ff 100644 --- a/packages/canvas/src/components/container/CanvasAction.vue +++ b/packages/canvas/src/components/container/CanvasAction.vue @@ -68,7 +68,7 @@
拖放元素到容器内
-
+
@@ -540,11 +540,12 @@ export default { height: 100%; background: var(--ti-lowcode-canvas-hover-line-in-bg-color); } - &.forbid { - width: 100%; - height: 100%; + &.forbidden:not(.in) { background: var(--ti-lowcode-canvas-hover-line-forbid-bg-color); } + &.forbidden.in { + background: var(--ti-lowcode-canvas-hover-line-in-forbid-bg-color); + } } .choose-slots { diff --git a/packages/canvas/src/components/container/container.js b/packages/canvas/src/components/container/container.js index 5812825761..ec547a8877 100644 --- a/packages/canvas/src/components/container/container.js +++ b/packages/canvas/src/components/container/container.js @@ -25,8 +25,7 @@ export const POSITION = Object.freeze({ BOTTOM: 'bottom', LEFT: 'left', RIGHT: 'right', - IN: 'in', - FORBID: 'forbid' + IN: 'in' }) import { isVsCodeEnv } from '@opentiny/tiny-engine-controller/js/environments' @@ -98,6 +97,7 @@ const initialLineState = { width: 0, left: 0, position: '', + forbidden: false, id: '', config: null, doc: null @@ -416,6 +416,23 @@ export const allowInsert = (configure = hoverState.configure || {}, data = dragS return flag } +const isAncestor = (ancestor, descendant) => { + const ancestorId = typeof ancestor === 'string' ? ancestor : ancestor.id + let descendantId = typeof descendant === 'string' ? descendant : descendant.id + + while (descendantId) { + const { parent } = getNode(descendantId, true) || {} + + if (parent.id === ancestorId) { + return true + } + + descendantId = parent.id + } + + return false +} + // 获取位置信息,返回状态 const lineAbs = 20 const getPosLine = (rect, configure) => { @@ -423,6 +440,7 @@ const getPosLine = (rect, configure) => { const yAbs = Math.min(lineAbs, rect.height / 3) const xAbs = Math.min(lineAbs, rect.width / 3) let type + let forbidden = false if (mousePos.y < rect.top + yAbs) { type = POSITION.TOP @@ -433,12 +451,21 @@ const getPosLine = (rect, configure) => { } else if (mousePos.x > rect.right - xAbs) { type = POSITION.RIGHT } else if (configure.isContainer) { - type = allowInsert() ? POSITION.IN : POSITION.FORBID + type = POSITION.IN + if (!allowInsert()) { + forbidden = true + } } else { type = POSITION.BOTTOM } - return { type } + // 如果被拖拽的节点不是新增的,并且是放置的节点的祖先节点,则禁止插入 + const draggedId = dragState.data?.id + if (draggedId && isAncestor(draggedId, lineState.id)) { + forbidden = true + } + + return { type, forbidden } } const isBodyEl = (element) => element.nodeName === 'BODY' @@ -484,20 +511,24 @@ const setHoverRect = (element, data) => { const childRect = getRect(childEle) const { left, height, top, width } = childRect const { x, y } = getOffset(childEle) + const posLine = getPosLine(childRect, lineState.configure) Object.assign(lineState, { width: width * scale, height: height * scale, top: top * scale + y - siteCanvasRect.y, left: left * scale + x - siteCanvasRect.x, - position: canvasState.type === 'absolute' || getPosLine(childRect, lineState.configure).type + position: canvasState.type === 'absolute' || posLine.type, + forbidden: posLine.forbidden }) } else { + const posLine = getPosLine(rect, configure) Object.assign(lineState, { width: width * scale, height: height * scale, top: top * scale + y - siteCanvasRect.y, left: left * scale + x - siteCanvasRect.x, - position: canvasState.type === 'absolute' || getPosLine(rect, configure).type + position: canvasState.type === 'absolute' || posLine.type, + forbidden: posLine.forbidden }) } @@ -670,13 +701,12 @@ export const copyNode = (id) => { export const onMouseUp = () => { const { draging, data } = dragState - const { position } = lineState + const { position, forbidden } = lineState const absolute = canvasState.type === 'absolute' const sourceId = data?.id const lineId = lineState.id - const allowInsert = position !== POSITION.FORBID - if (draging && allowInsert) { + if (draging && !forbidden) { const { parent, node } = getNode(lineId, true) || {} // target const targetNode = { parent, node, data: toRaw(data) } diff --git a/packages/theme/dark/canvas.less b/packages/theme/dark/canvas.less index d3f83fe1e5..9201f83426 100644 --- a/packages/theme/dark/canvas.less +++ b/packages/theme/dark/canvas.less @@ -1,7 +1,8 @@ #canvas-wrap { --ti-lowcode-canvas-rect-border-color: var(--ti-lowcode-base-primary-color-2); --ti-lowcode-canvas-hover-line-in-bg-color: rgba(0, 255, 0, 0.1); - --ti-lowcode-canvas-hover-line-forbid-bg-color: rgb(255, 66, 77); + --ti-lowcode-canvas-hover-line-forbid-bg-color: var(--ti-lowcode-base-error-color); + --ti-lowcode-canvas-hover-line-in-forbid-bg-color: rgba(242, 48, 48, 0.3); --ti-lowcode-canvas-choose-slot-border-color: var(--ti-lowcode-base-text-color-2); --ti-lowcode-canvas-choose-slot-color: var(--ti-lowcode-base-text-color-2); --ti-lowcode-canvas-corner-mark-left-color: var(--ti-lowcode-base-text-color-2); diff --git a/packages/theme/light/canvas.less b/packages/theme/light/canvas.less index 35e3824ac5..1342c94571 100644 --- a/packages/theme/light/canvas.less +++ b/packages/theme/light/canvas.less @@ -1,7 +1,8 @@ #canvas-wrap { --ti-lowcode-canvas-rect-border-color: var(--ti-lowcode-base-primary-color-2); --ti-lowcode-canvas-hover-line-in-bg-color: rgba(0, 255, 0, 0.1); - --ti-lowcode-canvas-hover-line-forbid-bg-color: rgb(255, 66, 77); + --ti-lowcode-canvas-hover-line-forbid-bg-color: var(--ti-lowcode-base-error-color); + --ti-lowcode-canvas-hover-line-in-forbid-bg-color: rgba(242, 48, 48, 0.3); --ti-lowcode-canvas-choose-slot-border-color: var(--ti-lowcode-base-text-color-2); --ti-lowcode-canvas-choose-slot-color: var(--ti-lowcode-base-text-color-2); --ti-lowcode-canvas-corner-mark-left-color: var(--ti-lowcode-base-text-color-2);