From 5636de41543ff89f3df73fd64a967bc76484a3cf Mon Sep 17 00:00:00 2001 From: clawdbot Date: Thu, 29 Jan 2026 04:27:28 +0800 Subject: [PATCH] editor: disable layer reorder menu items when no-op --- packages/editor/src/editor/ContextMenu.tsx | 61 ++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/packages/editor/src/editor/ContextMenu.tsx b/packages/editor/src/editor/ContextMenu.tsx index a0d42f4..7df54ff 100644 --- a/packages/editor/src/editor/ContextMenu.tsx +++ b/packages/editor/src/editor/ContextMenu.tsx @@ -134,6 +134,59 @@ export function ContextMenu(props: { const canModifySelection = hasSelection && selectionHasUnlocked; + const movableSelectionIds = selectedNodes.filter((n) => !n.locked).map((n) => n.id); + const movableSet = new Set(movableSelectionIds); + const orderIds = props.nodes.map((n) => n.id); + + const maxMovableIndex = movableSelectionIds.length + ? Math.max(...movableSelectionIds.map((id) => orderIds.indexOf(id)).filter((i) => i >= 0)) + : -1; + const minMovableIndex = movableSelectionIds.length + ? Math.min(...movableSelectionIds.map((id) => orderIds.indexOf(id)).filter((i) => i >= 0)) + : -1; + + const lastUnselectedIndex = (() => { + for (let i = orderIds.length - 1; i >= 0; i--) { + if (!movableSet.has(orderIds[i]!)) return i; + } + return -1; + })(); + + const firstUnselectedIndex = (() => { + for (let i = 0; i < orderIds.length; i++) { + if (!movableSet.has(orderIds[i]!)) return i; + } + return -1; + })(); + + const canReorderToFront = + canModifySelection && + movableSelectionIds.length > 0 && + props.onBringToFrontSelected && + lastUnselectedIndex >= 0 && + maxMovableIndex >= 0 && + maxMovableIndex < lastUnselectedIndex; + + const canReorderToBack = + canModifySelection && + movableSelectionIds.length > 0 && + props.onSendToBackSelected && + firstUnselectedIndex >= 0 && + minMovableIndex >= 0 && + minMovableIndex > firstUnselectedIndex; + + const canReorderForward = + canModifySelection && + movableSelectionIds.length > 0 && + props.onBringForwardSelected && + orderIds.some((id, i) => movableSet.has(id) && i < orderIds.length - 1 && !movableSet.has(orderIds[i + 1]!)); + + const canReorderBackward = + canModifySelection && + movableSelectionIds.length > 0 && + props.onSendBackwardSelected && + orderIds.some((id, i) => movableSet.has(id) && i > 0 && !movableSet.has(orderIds[i - 1]!)); + const hasTarget = ctx.kind === 'node'; const targetId = hasTarget ? ctx.targetId : undefined; const targetInSelection = !!targetId && selectionIds.includes(targetId); @@ -259,7 +312,7 @@ export function ContextMenu(props: { { props.onBringToFrontSelected?.(); onClose(); @@ -267,7 +320,7 @@ export function ContextMenu(props: { /> { props.onBringForwardSelected?.(); onClose(); @@ -275,7 +328,7 @@ export function ContextMenu(props: { /> { props.onSendBackwardSelected?.(); onClose(); @@ -283,7 +336,7 @@ export function ContextMenu(props: { /> { props.onSendToBackSelected?.(); onClose();