Use localized labels for Vue node slots and inputs/outputs (fallback to names) (#5773)

## Summary

Fixes https://github.com/Comfy-Org/ComfyUI_frontend/issues/5697 by
adding internationalization support for Vue node widget labels and
output slot names with fallback to original names.

## Changes

- **What**: Added `label` field to widget data structures and
`localized_name` support for output slots
- **Breaking**: None - all changes maintain backward compatibility with
fallback to original names

## Review Focus

Translation key resolution for node definitions and proper fallback
chain for widget labels and slot names.

## Screenshots (if applicable)

Observe that there is parity between Litegraph and Vue nodes w.r.t.
localization of labels/names.

<img width="3455" height="1417" alt="Screenshot from 2025-09-25
13-19-54"
src="https://github.com/user-attachments/assets/93ee8fae-3671-4175-a941-6462f942d0f1"
/>

<img width="3455" height="1417" alt="Screenshot from 2025-09-25
13-19-38"
src="https://github.com/user-attachments/assets/9573eb86-d74a-40ed-a0b5-e30afd3da6eb"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5773-Use-localized-labels-for-Vue-node-slots-and-inputs-outputs-fallback-to-names-2796d73d365081e08fb7d38464f4aa90)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
This commit is contained in:
Christian Byrne
2025-09-25 19:47:18 -07:00
committed by GitHub
parent c033e9e4d7
commit a6600aa109
9 changed files with 15 additions and 5 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -17,6 +17,7 @@ export interface SafeWidgetData {
name: string
type: string
value: WidgetValue
label?: string
options?: Record<string, unknown>
callback?: ((value: unknown) => void) | undefined
}
@@ -86,6 +87,7 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
name: widget.name,
type: widget.type,
value: value,
label: widget.label,
options: widget.options ? { ...widget.options } : undefined,
callback: widget.callback
}

View File

@@ -65,8 +65,10 @@ import IconButton from '@/components/button/IconButton.vue'
import EditableText from '@/components/common/EditableText.vue'
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
import { useErrorHandling } from '@/composables/useErrorHandling'
import { st } from '@/i18n'
import { useNodeTooltips } from '@/renderer/extensions/vueNodes/composables/useNodeTooltips'
import { app } from '@/scripts/app'
import { normalizeI18nKey } from '@/utils/formatUtil'
import {
getLocatorIdFromNodeData,
getNodeByLocatorId
@@ -119,8 +121,10 @@ const tooltipConfig = computed(() => {
const resolveTitle = (info: VueNodeData | undefined) => {
const title = (info?.title ?? '').trim()
if (title.length > 0) return title
const type = (info?.type ?? '').trim()
return type.length > 0 ? type : 'Untitled'
const nodeType = (info?.type ?? '').trim() || 'Untitled'
const key = `nodeDefs.${normalizeI18nKey(nodeType)}.display_name`
return st(key, nodeType)
}
// Local state for title to provide immediate feedback

View File

@@ -135,6 +135,7 @@ const processedWidgets = computed((): ProcessedWidget[] => {
name: widget.name,
type: widget.type,
value: widget.value,
label: widget.label,
options: widget.options,
callback: widget.callback
}

View File

@@ -7,7 +7,7 @@
v-if="!dotOnly"
class="whitespace-nowrap text-sm font-normal dark-theme:text-slate-200 text-stone-200 lod-toggle"
>
{{ slotData.name || `Output ${index}` }}
{{ slotData.localized_name || slotData.name || `Output ${index}` }}
</span>
<LODFallback />
</div>

View File

@@ -6,7 +6,7 @@ import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import LODFallback from '../../../components/LODFallback.vue'
defineProps<{
widget: Pick<SimplifiedWidget<string | number | undefined>, 'name'>
widget: Pick<SimplifiedWidget<string | number | undefined>, 'name' | 'label'>
}>()
</script>
@@ -19,7 +19,7 @@ defineProps<{
v-if="widget.name"
class="text-sm text-stone-200 dark-theme:text-slate-200 font-normal flex-1 truncate w-20 lod-toggle"
>
{{ widget.name }}
{{ widget.label || widget.name }}
</p>
<LODFallback />
</div>

View File

@@ -27,6 +27,9 @@ export interface SimplifiedWidget<
/** Current value of the widget */
value: T
/** Localized display label (falls back to name if not provided) */
label?: string
/** Widget options including filtered PrimeVue props */
options?: O