From e04453c359ae11f7af87fe902425dc110bb73887 Mon Sep 17 00:00:00 2001 From: bymyself Date: Fri, 13 Mar 2026 09:38:24 -0700 Subject: [PATCH] feat: rework slot context menu with full LiteGraph parity - Drop PrimeVue ContextMenu, use custom teleported imperative menu - Add Disconnect Links and Remove Slot actions (LiteGraph parity) - Extract useCanvasAnchoredPosition composable from NodeContextMenu - Fix slot label reactivity: add node:slot-label:changed graph event that triggers refreshNodeSlots to update both inputs and outputs - Refresh shallowReactive inputs via splice for property changes - Refresh outputs via spread copy for label changes - Use hasAnySlotAction guard instead of canRenameSlot in slot components - Add i18n keys: disconnectLinks, removeSlot --- src/components/graph/NodeContextMenu.vue | 81 +------- .../graph/useCanvasAnchoredPosition.ts | 77 +++++++ src/composables/graph/useGraphNodeManager.ts | 14 ++ src/lib/litegraph/src/types/graphTriggers.ts | 6 + src/locales/en/main.json | 2 + .../vueNodes/components/InputSlot.vue | 4 +- .../vueNodes/components/OutputSlot.vue | 4 +- .../vueNodes/components/SlotContextMenu.vue | 190 ++++++++---------- .../composables/useSlotContextMenu.ts | 121 +++++++++-- 9 files changed, 293 insertions(+), 206 deletions(-) create mode 100644 src/composables/graph/useCanvasAnchoredPosition.ts diff --git a/src/components/graph/NodeContextMenu.vue b/src/components/graph/NodeContextMenu.vue index 6bd285fd8c..5555b7d7a9 100644 --- a/src/components/graph/NodeContextMenu.vue +++ b/src/components/graph/NodeContextMenu.vue @@ -39,11 +39,12 @@ diff --git a/src/renderer/extensions/vueNodes/components/OutputSlot.vue b/src/renderer/extensions/vueNodes/components/OutputSlot.vue index 973a1a629a..735d50785e 100644 --- a/src/renderer/extensions/vueNodes/components/OutputSlot.vue +++ b/src/renderer/extensions/vueNodes/components/OutputSlot.vue @@ -37,7 +37,7 @@ import { useSlotLinkDragUIState } from '@/renderer/core/canvas/links/slotLinkDra import { getSlotKey } from '@/renderer/core/layout/slots/slotIdentifier' import { useNodeTooltips } from '@/renderer/extensions/vueNodes/composables/useNodeTooltips' import { - canRenameSlot, + hasAnySlotAction, showSlotMenu } from '@/renderer/extensions/vueNodes/composables/useSlotContextMenu' import { useSlotElementTracking } from '@/renderer/extensions/vueNodes/composables/useSlotElementTracking' @@ -141,7 +141,7 @@ const { onPointerDown } = useSlotLinkInteraction({ function onSlotContextMenu(event: MouseEvent) { if (!props.nodeId) return const ctx = { nodeId: props.nodeId, slotIndex: props.index, isInput: false } - if (!canRenameSlot(ctx)) return + if (!hasAnySlotAction(ctx)) return showSlotMenu(event, ctx) } diff --git a/src/renderer/extensions/vueNodes/components/SlotContextMenu.vue b/src/renderer/extensions/vueNodes/components/SlotContextMenu.vue index a9b590df38..f7865e75ee 100644 --- a/src/renderer/extensions/vueNodes/components/SlotContextMenu.vue +++ b/src/renderer/extensions/vueNodes/components/SlotContextMenu.vue @@ -1,29 +1,57 @@