Skip to content

feat(edges): render edge labels as HTML with labelHtml - #82

Open
webard wants to merge 1 commit into
getartisanflow:devfrom
webard:feat/edge-label-html
Open

feat(edges): render edge labels as HTML with labelHtml#82
webard wants to merge 1 commit into
getartisanflow:devfrom
webard:feat/edge-label-html

Conversation

@webard

@webard webard commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What

An edge can now ask for its labels to be rendered as HTML:

{ id: 'e1', source: 'a', target: 'b', label: 'over the limit<br><em>and no manager on shift</em>', labelHtml: true }

Why

ensureLabel writes label text with textContent, so anything but plain text shows as the tags themselves. A label that wants a line break, a small icon, or a piece of emphasis has no way to ask for one — white-space: pre-wrap on .flow-edge-label only reaches newlines that were actually typed, and the label div is already an HTML element, so the capability is there, just not reachable.

Where this came from: a workflow editor where the line between two nodes carries the reason the branch exists ("over the credit limit / and no manager on shift"). Two short lines read far better than one long one, and the editor writes those labels itself.

Shape

  • labelHtml?: boolean on FlowEdge, default off — nothing renders differently until an edge asks.
  • It covers all three positions (label, labelStart, labelEnd): one decision about one edge, not three flags.
  • The value goes to innerHTML unchanged and is trusted the way any framework trusts HTML it is handed. The docstring on the type and the labels page both say to sanitise user input first.
  • Both branches skip the write when the DOM already holds the string, so the label block still costs nothing on effect re-runs that don't change it.

Tests

Three cases in src/plugin/directives/flow-edge.test.ts (the existing mountEdges harness, with the container marked as the viewport so labels have somewhere to land):

  • the default still writes text, so markup shows as tags;
  • labelHtml: true renders real elements;
  • the flag reaches labelStart / labelEnd too.

The two HTML cases fail against dev without the source change.

npm run test — 187 files, 3035 tests, all passing.

dist/ is not rebuilt here — source and docs only, so the diff stays reviewable. I had pushed a rebuild commit and have since dropped it (force-push); the build is yours to cut at release time.

Not included

No version bump, no CHANGELOG.md entry, no dist/ rebuild, no new dependencies — the changelog has no Unreleased section and releases are cut by the maintainer, so I left that to the release commit. Happy to add an entry if you'd rather have it in the PR.

Edge labels are written with `textContent`, so anything but plain text shows
as the tags themselves — a label that wants a line break, an icon or a piece
of emphasis has no way to ask for one, and `white-space: pre-wrap` on
`.flow-edge-label` only reaches newlines that were typed.

`labelHtml: true` on an edge switches its labels to `innerHTML`. It covers all
three positions (`label`, `labelStart`, `labelEnd`), because they are one
decision about one edge, and defaults to off, so nothing renders differently
until an edge asks. The value is trusted the way any framework trusts HTML it
is handed; the type's docstring and the labels page both say to sanitise user
input first.

Both branches skip a write when the DOM already holds the string, so the label
block still costs nothing on the effect re-runs that don't change it.
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