Support selection of app inputs and outputs from vue mode (#9259)

- The input and output indicators are now plugged directly into the
`LGraphNode.vue` template. Care was taken to make implementation to have
low cost for performance and complexity when not in app mode setup.
- Context menu event handlers are added to each widget in vue mode
instead of resolving the target widget of an event
- Swap the nodeId passed by `useGraphNodeManager` to not include the
locator id. This id was never used and was incorrect since it didn't
resolve across nested subgraphs.
- Continued bug fixes for app mode as a whole.

Known issue: There is disparity of nodeId between litegraph (which
references the widget in the root graph) and vue (which promotes the
original widget). Efforts to reconcile are ongoing.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9259-Support-selection-app-inputs-and-outputs-from-vue-mode-3136d73d365081ae8e56e35bf6322409)
by [Unito](https://www.unito.io)

---------

Co-authored-by: pythongosssss <125205205+pythongosssss@users.noreply.github.com>
This commit is contained in:
AustinMroz
2026-03-02 09:49:21 -08:00
committed by GitHub
parent 84d7aa0fd9
commit 1dd789fa54
11 changed files with 237 additions and 54 deletions

View File

@@ -0,0 +1,51 @@
<script setup lang="ts">
import { remove } from 'es-toolkit'
import { computed } from 'vue'
import type { NodeId } from '@/lib/litegraph/src/LGraphNode'
import { useAppModeStore } from '@/stores/appModeStore'
import { cn } from '@/utils/tailwindUtil'
const { id } = defineProps<{ id: string }>()
const appModeStore = useAppModeStore()
const isPromoted = computed(() =>
appModeStore.selectedOutputs.some(matchesThis)
)
function matchesThis(nodeId: NodeId) {
return id == nodeId
}
function togglePromotion() {
if (isPromoted.value) remove(appModeStore.selectedOutputs, matchesThis)
else appModeStore.selectedOutputs.push(id)
}
</script>
<template>
<div
:class="
cn(
'absolute w-full h-full pointer-events-auto ring-warning-background/50 ring-5 rounded-2xl',
isPromoted && 'ring-warning-background'
)
"
@click.capture.stop.prevent
@pointerup.capture.stop.prevent
@pointermove.capture.stop.prevent
@pointerdown.capture.stop="togglePromotion"
@contextmenu.capture.stop.prevent
>
<div class="absolute top-0 right-0 size-8">
<div
v-if="isPromoted"
class="absolute -top-1/2 -right-1/2 size-full p-2 bg-warning-background rounded-lg"
>
<i class="icon-[lucide--check] bg-text-foreground size-full" />
</div>
<div
v-else
class="absolute -top-1/2 -right-1/2 size-full ring-warning-background/50 ring-4 ring-inset bg-component-node-background rounded-lg"
/>
</div>
</div>
</template>