mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-04 05:02:17 +00:00
[feat] Add tooltip support for Vue nodes (#5577)
## Summary Added tooltip support for Vue node components using PrimeVue's v-tooltip directive with proper data integration and container scoping. https://github.com/user-attachments/assets/d1af31e6-ef6a-4df8-8de4-5098aa4490a1 ## Changes - **What**: Implemented tooltip functionality for Vue node headers, input/output slots, and widgets using [PrimeVue v-tooltip](https://primevue.org/tooltip/) directive - **Dependencies**: Leverages existing PrimeVue tooltip system, no new dependencies ## Review Focus Container scoping implementation via provide/inject pattern for tooltip positioning, proper TypeScript interfaces eliminating `as any` casts, and integration with existing settings store for tooltip delays and enable/disable functionality. ```mermaid graph TD A[LGraphNode Container] --> B[provide tooltipContainer] B --> C[NodeHeader inject] B --> D[InputSlot inject] B --> E[OutputSlot inject] B --> F[NodeWidgets inject] G[useNodeTooltips composable] --> H[NodeDefStore lookup] G --> I[Settings integration] G --> J[i18n fallback] C --> G D --> G E --> G F --> G style A fill:#f9f9f9,stroke:#333,color:#000 style G fill:#e8f4fd,stroke:#0066cc,color:#000 ``` --------- Co-authored-by: DrJKL <DrJKL@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
120
src/renderer/extensions/vueNodes/composables/useNodeTooltips.ts
Normal file
120
src/renderer/extensions/vueNodes/composables/useNodeTooltips.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { type MaybeRef, type Ref, computed, unref } from 'vue'
|
||||
|
||||
import type { SafeWidgetData } from '@/composables/graph/useGraphNodeManager'
|
||||
import { st } from '@/i18n'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import { normalizeI18nKey } from '@/utils/formatUtil'
|
||||
|
||||
/**
|
||||
* Composable for managing Vue node tooltips
|
||||
* Provides tooltip text for node headers, slots, and widgets
|
||||
*/
|
||||
export function useNodeTooltips(
|
||||
nodeType: MaybeRef<string>,
|
||||
containerRef?: Ref<HTMLElement | undefined>
|
||||
) {
|
||||
const nodeDefStore = useNodeDefStore()
|
||||
const settingsStore = useSettingStore()
|
||||
|
||||
// Check if tooltips are globally enabled
|
||||
const tooltipsEnabled = computed(() =>
|
||||
settingsStore.get('Comfy.EnableTooltips')
|
||||
)
|
||||
|
||||
// Get node definition for tooltip data
|
||||
const nodeDef = computed(() => nodeDefStore.nodeDefsByName[unref(nodeType)])
|
||||
|
||||
/**
|
||||
* Get tooltip text for node description (header hover)
|
||||
*/
|
||||
const getNodeDescription = computed(() => {
|
||||
if (!tooltipsEnabled.value || !nodeDef.value) return ''
|
||||
|
||||
const key = `nodeDefs.${normalizeI18nKey(unref(nodeType))}.description`
|
||||
return st(key, nodeDef.value.description || '')
|
||||
})
|
||||
|
||||
/**
|
||||
* Get tooltip text for input slots
|
||||
*/
|
||||
const getInputSlotTooltip = (slotName: string) => {
|
||||
if (!tooltipsEnabled.value || !nodeDef.value) return ''
|
||||
|
||||
const key = `nodeDefs.${normalizeI18nKey(unref(nodeType))}.inputs.${normalizeI18nKey(slotName)}.tooltip`
|
||||
const inputTooltip = nodeDef.value.inputs?.[slotName]?.tooltip ?? ''
|
||||
return st(key, inputTooltip)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tooltip text for output slots
|
||||
*/
|
||||
const getOutputSlotTooltip = (slotIndex: number) => {
|
||||
if (!tooltipsEnabled.value || !nodeDef.value) return ''
|
||||
|
||||
const key = `nodeDefs.${normalizeI18nKey(unref(nodeType))}.outputs.${slotIndex}.tooltip`
|
||||
const outputTooltip = nodeDef.value.outputs?.[slotIndex]?.tooltip ?? ''
|
||||
return st(key, outputTooltip)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tooltip text for widgets
|
||||
*/
|
||||
const getWidgetTooltip = (widget: SafeWidgetData) => {
|
||||
if (!tooltipsEnabled.value || !nodeDef.value) return ''
|
||||
|
||||
// First try widget-specific tooltip
|
||||
const widgetTooltip = (widget as { tooltip?: string }).tooltip
|
||||
if (widgetTooltip) return widgetTooltip
|
||||
|
||||
// Then try input-based tooltip lookup
|
||||
const key = `nodeDefs.${normalizeI18nKey(unref(nodeType))}.inputs.${normalizeI18nKey(widget.name)}.tooltip`
|
||||
const inputTooltip = nodeDef.value.inputs?.[widget.name]?.tooltip ?? ''
|
||||
return st(key, inputTooltip)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create tooltip configuration object for v-tooltip directive
|
||||
*/
|
||||
const createTooltipConfig = (text: string) => {
|
||||
const tooltipDelay = settingsStore.get('LiteGraph.Node.TooltipDelay')
|
||||
const tooltipText = text || ''
|
||||
|
||||
const config: {
|
||||
value: string
|
||||
showDelay: number
|
||||
disabled: boolean
|
||||
appendTo?: HTMLElement
|
||||
pt?: any
|
||||
} = {
|
||||
value: tooltipText,
|
||||
showDelay: tooltipDelay as number,
|
||||
disabled: !tooltipsEnabled.value || !tooltipText,
|
||||
pt: {
|
||||
text: {
|
||||
class:
|
||||
'bg-charcoal-100 border border-slate-300 rounded-md px-4 py-2 text-white text-sm font-normal leading-tight max-w-75 shadow-none'
|
||||
},
|
||||
arrow: {
|
||||
class: 'before:border-charcoal-100'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a container reference, append tooltips to it
|
||||
if (containerRef?.value) {
|
||||
config.appendTo = containerRef.value
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
return {
|
||||
tooltipsEnabled,
|
||||
getNodeDescription,
|
||||
getInputSlotTooltip,
|
||||
getOutputSlotTooltip,
|
||||
getWidgetTooltip,
|
||||
createTooltipConfig
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user