mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-26 01:34:07 +00:00
* refactor: v3 ui slots connection dots * fix: use the new useTemplateRef * fix: slot dark-theme border and hover styles --------- Co-authored-by: Christian Byrne <cbyrne@comfy.org>
120 lines
2.9 KiB
Vue
120 lines
2.9 KiB
Vue
<template>
|
||
<div v-if="renderError" class="node-error p-1 text-red-500 text-xs">⚠️</div>
|
||
<div
|
||
v-else
|
||
class="lg-slot lg-slot--input flex items-center cursor-crosshair group rounded-r-lg"
|
||
:class="{
|
||
'opacity-70': readonly,
|
||
'lg-slot--connected': connected,
|
||
'lg-slot--compatible': compatible,
|
||
'lg-slot--dot-only': dotOnly,
|
||
'pr-6 hover:bg-black/5 hover:dark:bg-white/5': !dotOnly
|
||
}"
|
||
:style="{
|
||
height: slotHeight + 'px'
|
||
}"
|
||
@pointerdown="handleClick"
|
||
>
|
||
<!-- Connection Dot -->
|
||
<SlotConnectionDot
|
||
ref="connectionDotRef"
|
||
:color="slotColor"
|
||
class="-translate-x-1/2"
|
||
/>
|
||
|
||
<!-- Slot Name -->
|
||
<span
|
||
v-if="!dotOnly"
|
||
class="whitespace-nowrap text-sm font-normal dark-theme:text-[#9FA2BD] text-[#888682]"
|
||
>
|
||
{{ slotData.localized_name || slotData.name || `Input ${index}` }}
|
||
</span>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { type Ref, computed, inject, onErrorCaptured, ref, watch } from 'vue'
|
||
|
||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||
import { getSlotColor } from '@/constants/slotColors'
|
||
import {
|
||
COMFY_VUE_NODE_DIMENSIONS,
|
||
INodeSlot,
|
||
LGraphNode
|
||
} from '@/lib/litegraph/src/litegraph'
|
||
// DOM-based slot registration for arbitrary positioning
|
||
import {
|
||
type TransformState,
|
||
useDomSlotRegistration
|
||
} from '@/renderer/core/layout/slots/useDomSlotRegistration'
|
||
|
||
import SlotConnectionDot from './SlotConnectionDot.vue'
|
||
|
||
interface InputSlotProps {
|
||
node?: LGraphNode
|
||
nodeId?: string
|
||
slotData: INodeSlot
|
||
index: number
|
||
connected?: boolean
|
||
compatible?: boolean
|
||
readonly?: boolean
|
||
dotOnly?: boolean
|
||
}
|
||
|
||
const props = defineProps<InputSlotProps>()
|
||
|
||
const emit = defineEmits<{
|
||
'slot-click': [event: PointerEvent]
|
||
}>()
|
||
|
||
// Error boundary implementation
|
||
const renderError = ref<string | null>(null)
|
||
const { toastErrorHandler } = useErrorHandling()
|
||
|
||
onErrorCaptured((error) => {
|
||
renderError.value = error.message
|
||
toastErrorHandler(error)
|
||
return false
|
||
})
|
||
|
||
// Get slot color based on type
|
||
const slotColor = computed(() => getSlotColor(props.slotData.type))
|
||
|
||
// Get slot height from litegraph constants
|
||
const slotHeight = COMFY_VUE_NODE_DIMENSIONS.components.SLOT_HEIGHT
|
||
|
||
// Handle click events
|
||
const handleClick = (event: PointerEvent) => {
|
||
if (!props.readonly) {
|
||
emit('slot-click', event)
|
||
}
|
||
}
|
||
|
||
const transformState = inject<TransformState | undefined>(
|
||
'transformState',
|
||
undefined
|
||
)
|
||
|
||
const connectionDotRef = ref<{ slotElRef: Ref<HTMLElement> }>()
|
||
const slotElRef = ref<HTMLElement | null>(null)
|
||
|
||
// Watch for connection dot ref changes and sync the element ref
|
||
watch(
|
||
connectionDotRef,
|
||
(newValue) => {
|
||
if (newValue?.slotElRef) {
|
||
slotElRef.value = newValue.slotElRef.value
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
)
|
||
|
||
useDomSlotRegistration({
|
||
nodeId: props.nodeId ?? '',
|
||
slotIndex: props.index,
|
||
isInput: true,
|
||
element: slotElRef,
|
||
transform: transformState
|
||
})
|
||
</script>
|