ReviewOS

craft-native/craft

feat(native): an SVG delivered as a string cannot render — there is no DOM to inject it into

#338
Closed glennmichael123 opened this 9 days ago ·
9 days ago

The gap

A native screen can render Svg, G and SvgText nodes — that part works, and it is why charts already draw on native iOS screens. What it cannot do is render an SVG delivered as a string, because there is no DOM to inject it into.

What it blocks

Anything the server draws and sends as markup. In HQ.training, resources/views/a/[id]/index.stx renders a recorded activity's route and elevation profile this way:

const mapSvg = data?.map?.svg ?? ''
const profileSvg = data?.profile?.svg ?? ''
<figure …>
  {!! mapSvg !!}

The server rasterises the GPS track to SVG and hands the page a string. On a native screen has nothing to write into, so the route and the elevation profile disappear.

This is worth separating from "Craft needs a Map primitive", which is what I assumed before reading the code. We do not need an interactive map view — no tiles, no panning, no gestures. We need the SVG we already produce to reach the screen.

What would be enough

Either direction would do, and they trade off differently:

  1. Parse an SVG string into native shapes at the host — the most direct fix, and it makes every server-rendered drawing work without the producing code changing. The cost is an SVG parser in each host, which is the duplication craft-native/craft#334 is about.
  2. Parse it once, off the hosts — have the compiler or the runtime turn the string into the Svg/G/SvgText nodes the hosts already render, so the hosts gain nothing new. This keeps the native side unchanged and puts the work where there is one implementation instead of two.

(2) looks better from the outside for exactly the reason (1) is expensive, but I have not tried either.

Scope

Only affects SVG arriving as markup. SVG authored as stx nodes already renders natively, on iOS. On Android it does not render at all — the native host has zero SVG support, which is a separate gap and a larger one, since it is every chart rather than one screen.

9 days ago

The stx-side native implementation is now on main in b8b524e. Runtime SVG markup strings are parsed into the same native SVG nodes/geometry as inline SVG, and reactive replacement removes and recreates the native subtree. Verified by native/svg.test.ts, including path, circle, and replacement behavior.

Sign in to comment on this issue.