feat: add glow edge system with directional selection animation
Custom bezier edges with gradient glow for the flow editor: - Default: subtle white/gray gradient with soft glow - Downstream (cyan): animated flowing dashes from selected node through subtree - Upstream (amber): animated flow from selected node back to root - Cross-reference: dashed cyan with arrow markers - SVG gradient + filter defs for performant rendering Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,10 +12,10 @@ import {
|
||||
PanOnScrollMode,
|
||||
type NodeMouseHandler,
|
||||
} from '@xyflow/react'
|
||||
import '@xyflow/react/dist/style.css'
|
||||
|
||||
import { FlowCanvasNode, NODE_TYPE_CONFIG } from './FlowCanvasNode'
|
||||
import { FlowCanvasAnswerNode } from './FlowCanvasAnswerNode'
|
||||
import { GlowEdge, GlowEdgeDefs } from './GlowEdge'
|
||||
import { useTreeLayout } from './useTreeLayout'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Map as MapIcon, MapPinOff } from 'lucide-react'
|
||||
@@ -27,6 +27,10 @@ const nodeTypes = {
|
||||
answerStub: FlowCanvasAnswerNode,
|
||||
}
|
||||
|
||||
const edgeTypes = {
|
||||
glowEdge: GlowEdge,
|
||||
}
|
||||
|
||||
interface FlowCanvasProps {
|
||||
selectedNodeId: string | null
|
||||
onNodeSelect: (nodeId: string | null) => void
|
||||
@@ -36,7 +40,7 @@ interface FlowCanvasProps {
|
||||
|
||||
function FlowCanvasInner({ selectedNodeId, onNodeSelect, onSelectAnswerType, onNodeContextMenu }: FlowCanvasProps) {
|
||||
const { fitView, setCenter } = useReactFlow()
|
||||
const { nodes: layoutNodes, edges: layoutEdges, collapsedNodeIds, toggleCollapse, onNodesMeasured } = useTreeLayout()
|
||||
const { nodes: layoutNodes, edges: layoutEdges, collapsedNodeIds, toggleCollapse, onNodesMeasured } = useTreeLayout(selectedNodeId)
|
||||
const [minimapVisible, setMinimapVisible] = useState(true)
|
||||
|
||||
// Inject callbacks into node data (because useTreeLayout creates placeholder functions)
|
||||
@@ -124,6 +128,7 @@ function FlowCanvasInner({ selectedNodeId, onNodeSelect, onSelectAnswerType, onN
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
nodeTypes={nodeTypes}
|
||||
edgeTypes={edgeTypes}
|
||||
onNodeClick={handleNodeClick}
|
||||
onPaneClick={handlePaneClick}
|
||||
fitView
|
||||
@@ -139,6 +144,7 @@ function FlowCanvasInner({ selectedNodeId, onNodeSelect, onSelectAnswerType, onN
|
||||
proOptions={{ hideAttribution: true }}
|
||||
className="dark bg-accent/30"
|
||||
>
|
||||
<GlowEdgeDefs />
|
||||
<Background variant={BackgroundVariant.Dots} gap={20} size={1.5} color="oklch(0.63 0.02 260 / 0.25)" />
|
||||
<Controls showInteractive={false} className="bg-card! border-border! shadow-lg!" />
|
||||
{minimapVisible && (
|
||||
|
||||
Reference in New Issue
Block a user