Improve graphfx-ui node UX

This commit is contained in:
2026-06-19 00:22:36 +02:00
parent 9c92ef42a1
commit 80916cb945
5 changed files with 381 additions and 68 deletions

View File

@@ -7,45 +7,64 @@ const props = defineProps<{
data: GraphFxNodeData
}>()
function typeClass(port: GraphFxPort) {
return `io-type-${port.type.toLowerCase()}`
}
function valuePreview(port: GraphFxPort) {
if (port.output) return 'connected'
if (port.value === null || port.value === undefined) return 'empty'
if (typeof port.value === 'string') return port.value.length > 28 ? `${port.value.slice(0, 28)}` : port.value
if (port.output) return ''
if (port.value === null || port.value === undefined) return ''
if (typeof port.value === 'string') return port.value.length > 24 ? `${port.value.slice(0, 24)}` : port.value
if (typeof port.value === 'number' || typeof port.value === 'boolean') return String(port.value)
if (typeof port.value === 'object') return 'object'
return String(port.value)
}
function hasCustomLabel(port: GraphFxPort) {
return port.label && port.label !== port.name
}
</script>
<template>
<article class="graphfx-node">
<header class="graphfx-node__header">
<p class="graphfx-node__kind">GraphFX</p>
<h3>{{ data.name }}</h3>
<small>{{ data.id }}</small>
</header>
<section class="graphfx-node__ports" :class="{ 'graphfx-node__ports--empty': !data.inputs.length && !data.outputs.length }">
<div class="graphfx-node__column">
<p class="graphfx-node__column-title">Inputs</p>
<div v-if="!data.inputs.length" class="graphfx-node__empty">none</div>
<div v-for="port in data.inputs" :key="port.name" class="graphfx-node__port graphfx-node__port--input">
<div class="graphfx-node__column graphfx-node__column--inputs">
<div v-if="!data.inputs.length" class="graphfx-node__empty">no inputs</div>
<div
v-for="port in data.inputs"
:key="port.name"
class="graphfx-node__port graphfx-node__port--input"
:class="[typeClass(port), { 'graphfx-node__port--connected': port.output, 'graphfx-node__port--labeled': hasCustomLabel(port) }]"
:title="`${port.name} · ${port.type}${port.output ? ` · ${port.output}` : ''}`"
>
<Handle
type="target"
:id="getInputHandleId(data.id, port.name)"
:position="Position.Left"
class="graphfx-node__handle graphfx-node__handle--input"
/>
<span class="graphfx-node__port-label">{{ port.label }}</span>
<span class="graphfx-node__port-value" :title="String(port.value ?? '')">{{ valuePreview(port) }}</span>
<span class="graphfx-node__port-name">{{ port.name }}</span>
<span v-if="hasCustomLabel(port)" class="graphfx-node__port-label">{{ port.label }}</span>
<span v-if="valuePreview(port)" class="graphfx-node__port-value">{{ valuePreview(port) }}</span>
</div>
</div>
<div class="graphfx-node__column graphfx-node__column--outputs">
<p class="graphfx-node__column-title">Outputs</p>
<div v-if="!data.outputs.length" class="graphfx-node__empty">none</div>
<div v-for="port in data.outputs" :key="port.name" class="graphfx-node__port graphfx-node__port--output">
<span class="graphfx-node__port-label">{{ port.label }}</span>
<div v-if="!data.outputs.length" class="graphfx-node__empty">no outputs</div>
<div
v-for="port in data.outputs"
:key="port.name"
class="graphfx-node__port graphfx-node__port--output"
:class="[typeClass(port), { 'graphfx-node__port--labeled': hasCustomLabel(port) }]"
:title="`${port.name} · ${port.type}`"
>
<span class="graphfx-node__port-name">{{ port.name }}</span>
<span v-if="hasCustomLabel(port)" class="graphfx-node__port-label">{{ port.label }}</span>
<Handle
type="source"
:id="getOutputHandleId(data.id, port.name)"