You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -46,19 +46,36 @@ Cell legend: **✅** = documented out-of-the-box · **❌** = not supported / no
46
46
-**A uniform 8-verb imperative handle** (`getMap` / `flyTo` / `easeTo` / `jumpTo` / `fitBounds` / `getCenter` / `getZoom` / `resize`) grabbed with each framework's native ref — versus "however this wrapper happens to expose the `Map`" (a hook, a service, a ref, a directive input).
47
47
-**`getMap()` is always one hop from the raw engine**, so the full MapLibre API is reachable on any target when the curated surface doesn't cover something.
48
48
49
+
## Declarative `<Source>` / `<Layer>` children — now supported {#declarative-children}
50
+
51
+
Declarative `<Source>` / `<Layer>` children are **now supported on all six targets, alongside the `:sources` / `:layers` config-array props** — the authoring shape the big-framework wrappers (`react-map-gl`, `vue-maplibre-gl`, `svelte-maplibre-gl`, `ngx-maplibre-gl`) are known for.
52
+
53
+
```html
54
+
<MapLibre:center="[0, 0]":zoom="2">
55
+
<Sourceid="pts":spec="geojson">
56
+
<Layerid="circles"type="circle":paint="paint" />
57
+
</Source>
58
+
<Layerid="bg"type="background":paint="bgPaint" />
59
+
</MapLibre>
60
+
```
61
+
62
+
-**Nested `<Source><Layer/></Source>` auto-binds** the layer to its parent source via injected context — no `source` attr needed.
63
+
-**Flat `<Layer source="id" />`** directly under `<MapLibre>` also works, for background layers (no source) and cross-source references.
64
+
-**Both shapes coexist with `:sources` / `:layers`.** When a consumer supplies both a config array and declarative children, both feed the **same id-keyed registry**; on an id collision the declarative child wins (last-writer-wins, matching the engine's own reconcile). It is the **same `addSource` / `addLayer` runtime** and the same style-load-gated reconcile — the children just register into it.
65
+
66
+
This was built by dogfooding Rozie's own cross-component context primitive (`$provide` / `$inject`): the map provides an id-keyed registry, and each `<Source>` / `<Layer>` child injects it, registers on mount, updates on prop change, and unregisters on unmount. Verified behaviorally across all six targets (including the Angular real-build).
67
+
49
68
## What Rozie defers {#what-rozie-defers}
50
69
51
70
This page concedes where the standalone wrappers are genuinely ahead — that's what keeps the comparison credible, and it doubles as Rozie's own roadmap.
52
71
53
-
-**Declarative `<Source>` / `<Layer>`*children*.**`react-map-gl`, `vue-maplibre-gl`, `svelte-maplibre-gl`, and `ngx-maplibre-gl` all let you compose data sources and styled layers as **child components / directives** inside the map — `<Source><Layer /></Source>` and friends. Rozie v1 takes a different authoring shape: the **`:sources` / `:layers` config props** (MapLibre's own source / layer specs, reconciled into the live style after load). It is the **same `addSource` / `addLayer` runtime** and reaches the same result, but the authoring model is a config array, not nested children. True declarative source / layer children need a **cross-component context primitive** (a parent map providing context to descendant `<Source>` / `<Layer>` elements) that Rozie deliberately defers — it's a meaningful compiler primitive, not a quick wrapper feature. Until then, `:sources` / `:layers` cover the same ground in config form.
54
-
55
72
-**Big-framework depth on the home framework.**`react-map-gl` (vis.gl, OpenJS-foundation-backed), `vue-maplibre-gl`, `svelte-maplibre-gl` (MIERUNE), and the official `ngx-maplibre-gl` are mature, multi-year libraries with deep component catalogs (terrain, globe / projection, geocoding integrations, draw plugins, and the full declarative children model). On their own framework, they expose more surface than Rozie's curated prop set. Rozie's value is **not** "more than react-map-gl on React" — it's the **same idiomatic component on all six frameworks from one source**, with the underserved **Solid and Lit** getting a first-class wrapper they otherwise lack. For anything outside the curated surface, `getMap()` hands you the raw engine on every target.
56
73
57
74
-**`@rozie-ui/maplibre` is `0.1.0`.** The surface (25 props / 20 events / 8-verb handle / `marker` + `popup` reactive slots + `control` mount-once slot) is stable and gate-verified, but it is younger than the multi-year incumbents.
58
75
59
76
## Try it
60
77
61
-
The [`@rozie-ui/maplibre` showcase + API reference](/guide/maplibre) documents the `@rozie-ui/maplibre-*` packages — one pre-compiled, per-framework install (`npm i @rozie-ui/maplibre-react maplibre-gl`, etc.), plus the `import 'maplibre-gl/dist/maplibre-gl.css'` the engine DOM needs. The showcase walks the four two-way camera bindings, the 20-event surface, the imperative handle, the `:sources` / `:layers` passthroughs, and the per-target recipe for the `marker` / `popup` / `control` portal slots.
78
+
The [`@rozie-ui/maplibre` showcase + API reference](/guide/maplibre) documents the `@rozie-ui/maplibre-*` packages — one pre-compiled, per-framework install (`npm i @rozie-ui/maplibre-react maplibre-gl`, etc.), plus the `import 'maplibre-gl/dist/maplibre-gl.css'` the engine DOM needs. The showcase walks the four two-way camera bindings, the 20-event surface, the imperative handle, both the `<Source>` / `<Layer>` declarative children and the `:sources` / `:layers` config-array passthroughs, and the per-target recipe for the `marker` / `popup` / `control` portal slots.
@@ -50,11 +51,36 @@ Cell legend: **✅** = documented out-of-the-box · **❌** = not supported / no
50
51
-**A uniform 12-verb imperative handle** (`getEditor` / `getArea` / `addNode` / `removeNode` / `addConnection` / `removeConnection` / `clear` / `zoomToFit` / `zoomTo` / `getNodes` / `getConnections` / `getTransform`) grabbed with each framework's native ref — versus "however this library happens to expose its instance" (a hook, a service, a ref).
51
52
-**`getEditor()` / `getArea()` are always one hop from the raw engine**, so the full Rete API (custom plugins, `rete-engine` dataflow, `rete-auto-arrange-plugin`, …) is reachable on any target when the curated surface doesn't cover something.
52
53
54
+
## Declarative `<FlowNode>` / `<Handle>` / `<Connection>` children — now supported {#declarative-children}
55
+
56
+
Declarative graph children are **now supported on all six targets, alongside the `:nodes` / `:connections` config-array props**. The vocabulary follows Rete's own model, not React Flow's: `<FlowNode>` is a node, `<Handle>` is a **port / socket** (nested inside its node), and `<Connection>` is an **edge** (a flat child of the canvas, since an edge spans two nodes and can't nest inside one).
-**`<Handle>` nests inside `<FlowNode>`** and auto-binds to its node via injected context (no `nodeId` to wire by hand).
73
+
-**`<Connection>` is a flat child** of `<FlowCanvas>` referencing source / target node ids + handle keys.
74
+
-**Both shapes coexist with `:nodes` / `:connections`.** A config array and declarative children feed the **same id-keyed registry**; on an id collision the declarative child wins (last-writer-wins). It is the **same `addNode` / `addConnection` runtime** — children just register into the engine's existing reconcile.
75
+
76
+
**Why the node body is a named `#body` slot, not bare children.** A FlowNode's visual body has to *teleport* into the node element the Rete engine creates — it doesn't render in the normal component tree. Rozie mounts that body through a portal (`$portals.body`), which gives it a fresh framework render-root inside the engine-owned host. But a portal render-root has no tree ancestor, so context-consuming children placed inside it would not resolve their `$inject` on five of six targets (context is tree-scoped on React/Vue/Svelte/Solid/Lit). Separating the teleported body (`<template #body>`) from the context-consuming config children (`<Handle>` / `<Connection>`, which stay in the normal child position) is therefore the robust cross-framework shape: the body teleports, the config children keep their tree scope and inject correctly. Verified behaviorally across all six targets (including the Angular real-build).
77
+
78
+
This was built by dogfooding Rozie's own cross-component context primitive (`$provide` / `$inject`): the canvas provides an id-keyed registry, and each child injects it. (A general `$portals.default` capability also exists for default-slot portals — but `<FlowNode>` deliberately uses the named `#body` slot for the tree-scope reason above; it does **not** rely on the bare default slot.)
79
+
53
80
## What Rozie defers {#what-rozie-defers}
54
81
55
82
This page concedes where the standalone libraries are genuinely ahead — that's what keeps the comparison credible, and it doubles as Rozie's roadmap.
56
83
57
-
-**Declarative `<Node>` / `<Edge>`*children*.** React Flow et al. let you compose a graph as JSX/children with per-type node components registered up front. Rozie v1 takes a different authoring shape: the **`:nodes` / `:connections` config-array props** (reconciled into the live editor), with per-node bodies supplied through the `node` slot. It is the **same `addNode` / `addConnection` runtime** and reaches the same result, but the authoring model is a config array, not nested children. True declarative graph children — deeply-nested `<Node>`/`<Handle>` elements reading shared graph state (selection, viewport, neighbors) without prop-drilling — need a **cross-component context primitive** that Rozie deliberately defers (the same primitive MapLibre's `:sources` / `:layers` deferral is waiting on). The wrap-a-vanilla-engine strategy sidesteps it entirely: the **engine** owns the store, and node bodies reach it through portal scope.
58
84
-**MiniMap / Background variants / NodeToolbar / NodeResizer.** React Flow ships these as first-class components. `FlowCanvas` v1 covers the canvas + nodes + sockets + connections + a dotted background; the second-tier chrome is on the roadmap (config-prop first, the MapLibre stance).
59
85
-**Big-framework depth on the home framework.** React Flow (Zustand store, deep node/edge-type catalogs, helper hooks, layouting integrations) is a mature, multi-year library; on React it exposes more surface than Rozie's curated set. Rozie's value is **not** "more than React Flow on React" — it's the **same idiomatic editor on all six frameworks from one source**, with the unserved **Solid and Lit** finally covered.
60
86
-**`@rozie-ui/rete` is `0.1.0`.** The surface (13 props / 7 events / 12-verb handle / `node` reactive slot) is stable and gate-verified (behavioral parity across all six targets), but it is younger than the incumbents.
0 commit comments