feat(group): add 4 side handles for edge connections

Group nodes can now be source/target of edges via snap points on
each side (top/right/bottom/left). Each side exposes a source handle
plus an invisible target overlay, matching the pattern used by
BaseNode.
This commit is contained in:
Pouzor
2026-05-15 21:12:10 +02:00
parent 14719a5c39
commit 14597ab86f
3 changed files with 111 additions and 1 deletions
@@ -1,11 +1,15 @@
import { useState } from 'react'
import { type NodeProps, type Node, NodeResizer } from '@xyflow/react'
import { type NodeProps, type Node, NodeResizer, Handle, Position } from '@xyflow/react'
import { Layers, Pencil, Check, X } from 'lucide-react'
import { useCanvasStore } from '@/stores/canvasStore'
import { useThemeStore } from '@/stores/themeStore'
import { THEMES } from '@/utils/themes'
import { STATUS_COLORS, type NodeData } from '@/types'
export function GroupNode({ id, data, selected }: NodeProps<Node<NodeData>>) {
const { nodes, updateNode, snapshotHistory } = useCanvasStore()
const activeTheme = useThemeStore((s) => s.activeTheme)
const theme = THEMES[activeTheme]
const showBorder = data.custom_colors?.show_border !== false
const isVisible = showBorder || selected
@@ -49,6 +53,29 @@ export function GroupNode({ id, data, selected }: NodeProps<Node<NodeData>>) {
handleStyle={{ fill: '#00d4ff', stroke: '#0d1117', width: 8, height: 8, borderRadius: 2 }}
/>
{/* 4 snap-point handles — one per side. Source + invisible target overlay for each. */}
{([
['group-top', Position.Top],
['group-right', Position.Right],
['group-bottom', Position.Bottom],
['group-left', Position.Left],
] as const).map(([hid, pos]) => (
<span key={hid}>
<Handle
type="source"
position={pos}
id={hid}
style={{ background: theme.colors.handleBackground, borderColor: theme.colors.handleBorder }}
/>
<Handle
type="target"
position={pos}
id={`${hid}-t`}
style={{ opacity: 0, width: 12, height: 12 }}
/>
</span>
))}
{/* Header */}
{isVisible && (
<div