Skip to content

fix(edge): respect handle.style left/top offset when computing edge endpoints#3

Open
pshoukry wants to merge 1 commit intorocket4ce:mainfrom
pshoukry:fix/handle-style-offset-edge-endpoints
Open

fix(edge): respect handle.style left/top offset when computing edge endpoints#3
pshoukry wants to merge 1 commit intorocket4ce:mainfrom
pshoukry:fix/handle-style-offset-edge-endpoints

Conversation

@pshoukry
Copy link
Copy Markdown

@pshoukry pshoukry commented Apr 17, 2026

Summary

Problem: Adding multiple handles on the same side ( example: conditional with more than 3 / 4 options like a case ) is impossible since each side positions its handle at a 50% marker.

Solution: Allow adding multiple handles and distributing them evenly on the side.

When a handle carries a left (top/bottom handles) or top (left/right handles) percentage in its style map, the handle element is rendered at that visual offset by the browser — but the SVG edge endpoint was still computed from the centre of the side. Result: the edge line doesn't meet the handle circle, leaving a visible gap on branching nodes that spread their source handles (e.g. Condition / Switch / ForEach patterns where `true` and `false` handles sit at 25% and 75% of the bottom edge).

`LiveFlow.Handle` already exposes a public `:style` field intended for "Custom inline styles" — this change makes edge rendering consistent with that field instead of silently ignoring it.

Behaviour

  • Handle on `:top` or `:bottom` with `style: %{"left" => "25%"}` → edge endpoint x = `node.x + node.width * 0.25`.
  • Handle on `:left` or `:right` with `style: %{"top" => "20%"}` → edge endpoint y = `node.y + node.height * 0.20`.
  • Handle with no style, empty style, or a non-parseable value → falls back to the previous centred behaviour.
  • Atom keys (`%{left: "25%"}`) are also accepted alongside string keys.

Test plan

Five new component tests in `test/live_flow/components/edge_test.exs` covering:

  • Source handle on `:bottom` with `style.left = "25%"` on a 200px-wide node at x=0 → edge starts at x=50.
  • Source handle on `:bottom` with `style.left = "75%"` on a 200px-wide node at x=100 → edge starts at x=250.
  • Source handle on `:bottom` with empty style → edge starts at x=100 (centre, pre-existing behaviour).
  • Source handle on `:bottom` with `style.left = "garbage"` → falls back to centre.
  • Source handle on `:right` with `style.top = "20%"` on a 100px-tall node → edge starts at y=20.

Full suite: 194 tests, 0 failures.

When a handle carries a `left` (for top/bottom handles) or `top` (for
left/right handles) percentage in its `style` map, the handle element
is rendered at that offset by the browser but the SVG edge was still
computed from the centre of the side. Result: the edge line didn't
meet the handle circle — a visible gap on branching nodes that spread
their source handles (Condition/Switch/ForEach patterns).

Edge now parses the percentage from `handle.style` and shifts the
endpoint along the axis the handle sits on. Non-matching / absent /
invalid values fall back to the previous centred behaviour.

Adds five component tests exercising spread source handles on top,
bottom, and right sides, plus the fallback paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant