fix selection

This commit is contained in:
Vikhyath Mondreti
2026-01-18 13:23:40 -08:00
parent b300192110
commit dec523c6e4
2 changed files with 30 additions and 5 deletions

View File

@@ -8,13 +8,14 @@ type MenuType = 'block' | 'pane' | null
interface UseCanvasContextMenuProps {
blocks: Record<string, BlockState>
getNodes: () => Node[]
setNodes: (updater: (nodes: Node[]) => Node[]) => void
}
/**
* Hook for managing workflow canvas context menus.
* Handles right-click events, menu state, click-outside detection, and block info extraction.
*/
export function useCanvasContextMenu({ blocks, getNodes }: UseCanvasContextMenuProps) {
export function useCanvasContextMenu({ blocks, getNodes, setNodes }: UseCanvasContextMenuProps) {
const [activeMenu, setActiveMenu] = useState<MenuType>(null)
const [position, setPosition] = useState({ x: 0, y: 0 })
const [selectedBlocks, setSelectedBlocks] = useState<BlockInfo[]>([])
@@ -44,14 +45,26 @@ export function useCanvasContextMenu({ blocks, getNodes }: UseCanvasContextMenuP
event.preventDefault()
event.stopPropagation()
const isMultiSelect = event.shiftKey || event.metaKey || event.ctrlKey
setNodes((nodes) =>
nodes.map((n) => ({
...n,
selected: isMultiSelect ? (n.id === node.id ? true : n.selected) : n.id === node.id,
}))
)
const selectedNodes = getNodes().filter((n) => n.selected)
const nodesToUse = selectedNodes.some((n) => n.id === node.id) ? selectedNodes : [node]
const nodesToUse = isMultiSelect
? selectedNodes.some((n) => n.id === node.id)
? selectedNodes
: [...selectedNodes, node]
: [node]
setPosition({ x: event.clientX, y: event.clientY })
setSelectedBlocks(nodesToBlockInfos(nodesToUse))
setActiveMenu('block')
},
[getNodes, nodesToBlockInfos]
[getNodes, nodesToBlockInfos, setNodes]
)
const handlePaneContextMenu = useCallback((event: React.MouseEvent) => {

View File

@@ -234,6 +234,7 @@ const WorkflowContent = React.memo(() => {
const [potentialParentId, setPotentialParentId] = useState<string | null>(null)
const [selectedEdges, setSelectedEdges] = useState<SelectedEdgesMap>(new Map())
const [isErrorConnectionDrag, setIsErrorConnectionDrag] = useState(false)
const selectedIdsRef = useRef<string[] | null>(null)
const canvasMode = useCanvasModeStore((state) => state.mode)
const isHandMode = canvasMode === 'hand'
const { handleCanvasMouseDown, selectionProps } = useShiftSelectionLock({ isHandMode })
@@ -864,7 +865,7 @@ const WorkflowContent = React.memo(() => {
handlePaneContextMenu,
handleSelectionContextMenu,
closeMenu: closeContextMenu,
} = useCanvasContextMenu({ blocks, getNodes })
} = useCanvasContextMenu({ blocks, getNodes, setNodes })
const handleContextCopy = useCallback(() => {
const blockIds = contextMenuBlocks.map((b) => b.id)
@@ -2153,11 +2154,22 @@ const WorkflowContent = React.memo(() => {
/** Handles node changes - applies changes and resolves parent-child selection conflicts. */
const onNodesChange = useCallback(
(changes: NodeChange[]) => {
selectedIdsRef.current = null
setDisplayNodes((nds) => {
const updated = applyNodeChanges(changes, nds)
const hasSelectionChange = changes.some((c) => c.type === 'select')
return hasSelectionChange ? resolveParentChildSelectionConflicts(updated, blocks) : updated
if (!hasSelectionChange) return updated
const resolved = resolveParentChildSelectionConflicts(updated, blocks)
selectedIdsRef.current = resolved.filter((node) => node.selected).map((node) => node.id)
return resolved
})
const selectedIds = selectedIdsRef.current as string[] | null
if (selectedIds !== null) {
const { currentBlockId, clearCurrentBlock } = usePanelEditorStore.getState()
if (currentBlockId && selectedIds.indexOf(currentBlockId) === -1) {
clearCurrentBlock()
}
}
},
[blocks]
)