mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-11 08:20:53 +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:
@@ -31,7 +31,7 @@
|
||||
type: widget.type,
|
||||
boundingRect: [0, 0, 0, 0]
|
||||
}"
|
||||
:node-id="nodeInfo?.id != null ? String(nodeInfo.id) : ''"
|
||||
:node-id="nodeData?.id != null ? String(nodeData.id) : ''"
|
||||
:index="getWidgetInputIndex(widget)"
|
||||
:readonly="readonly"
|
||||
:dot-only="true"
|
||||
@@ -40,6 +40,7 @@
|
||||
<!-- Widget Component -->
|
||||
<component
|
||||
:is="widget.vueComponent"
|
||||
v-tooltip.left="widget.tooltipConfig"
|
||||
:widget="widget.simplified"
|
||||
:model-value="widget.value"
|
||||
:readonly="readonly"
|
||||
@@ -51,15 +52,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onErrorCaptured, ref } from 'vue'
|
||||
import { type Ref, computed, inject, onErrorCaptured, ref } from 'vue'
|
||||
|
||||
import type {
|
||||
SafeWidgetData,
|
||||
VueNodeData
|
||||
} from '@/composables/graph/useGraphNodeManager'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
|
||||
import { useNodeTooltips } from '@/renderer/extensions/vueNodes/composables/useNodeTooltips'
|
||||
import { LODLevel } from '@/renderer/extensions/vueNodes/lod/useLOD'
|
||||
// Import widget components directly
|
||||
import WidgetInputText from '@/renderer/extensions/vueNodes/widgets/components/WidgetInputText.vue'
|
||||
@@ -74,13 +75,12 @@ import { cn } from '@/utils/tailwindUtil'
|
||||
import InputSlot from './InputSlot.vue'
|
||||
|
||||
interface NodeWidgetsProps {
|
||||
node?: LGraphNode
|
||||
nodeData?: VueNodeData
|
||||
readonly?: boolean
|
||||
lodLevel?: LODLevel
|
||||
}
|
||||
|
||||
const props = defineProps<NodeWidgetsProps>()
|
||||
const { nodeData, readonly, lodLevel } = defineProps<NodeWidgetsProps>()
|
||||
|
||||
const { shouldHandleNodePointerEvents, forwardEventToCanvas } =
|
||||
useCanvasInteractions()
|
||||
@@ -101,7 +101,13 @@ onErrorCaptured((error) => {
|
||||
return false
|
||||
})
|
||||
|
||||
const nodeInfo = computed(() => props.nodeData || props.node)
|
||||
const nodeType = computed(() => nodeData?.type || '')
|
||||
const tooltipContainer =
|
||||
inject<Ref<HTMLElement | undefined>>('tooltipContainer')
|
||||
const { getWidgetTooltip, createTooltipConfig } = useNodeTooltips(
|
||||
nodeType.value,
|
||||
tooltipContainer
|
||||
)
|
||||
|
||||
interface ProcessedWidget {
|
||||
name: string
|
||||
@@ -110,14 +116,13 @@ interface ProcessedWidget {
|
||||
simplified: SimplifiedWidget
|
||||
value: WidgetValue
|
||||
updateHandler: (value: unknown) => void
|
||||
tooltipConfig: any
|
||||
}
|
||||
|
||||
const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
const info = nodeInfo.value
|
||||
if (!info?.widgets) return []
|
||||
if (!nodeData?.widgets) return []
|
||||
|
||||
const widgets = info.widgets as SafeWidgetData[]
|
||||
const lodLevel = props.lodLevel
|
||||
const widgets = nodeData.widgets as SafeWidgetData[]
|
||||
const result: ProcessedWidget[] = []
|
||||
|
||||
if (lodLevel === LODLevel.MINIMAL) {
|
||||
@@ -148,13 +153,17 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
}
|
||||
}
|
||||
|
||||
const tooltipText = getWidgetTooltip(widget)
|
||||
const tooltipConfig = createTooltipConfig(tooltipText)
|
||||
|
||||
result.push({
|
||||
name: widget.name,
|
||||
type: widget.type,
|
||||
vueComponent,
|
||||
simplified,
|
||||
value: widget.value,
|
||||
updateHandler
|
||||
updateHandler,
|
||||
tooltipConfig
|
||||
})
|
||||
}
|
||||
|
||||
@@ -165,7 +174,7 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
// or restructuring data model to unify widgets and inputs
|
||||
// Map a widget to its corresponding input slot index
|
||||
const getWidgetInputIndex = (widget: ProcessedWidget): number => {
|
||||
const inputs = nodeInfo.value?.inputs
|
||||
const inputs = nodeData?.inputs
|
||||
if (!inputs) return 0
|
||||
|
||||
const idx = inputs.findIndex((input: any) => {
|
||||
|
||||
Reference in New Issue
Block a user