JoyDom

fun JoyDom(spec: <Error class: unknown class>, modifier: Modifier = Modifier, components: JoyDomComponentsConfig = JoyDomComponentsConfig.Empty, painterFactory: JoyDomPainterFactory = CoilPainterFactory, onEvent: JoyDomEventHandler? = null)

Render a joy-dom Spec into Compose UI.

components (built with the components DSL) registers a renderer for any node type. A registered type wins over the built-in renderer, so it can override the built-ins (div, span, p, h1h6, img) too. painterFactory resolves img.src strings to a androidx.compose.ui.graphics.painter.Painter; defaults to CoilPainterFactory, which loads each src through Coil 3 (a factory returning null renders an empty Box). onEvent is the single callback invoked whenever a node event binding fires (onclick/onfocus/onblur/onchange); it receives the full EventPayload and the host switches on name to decide what to do. When null (the default) a bound node is still interactive (clickable/focusable) — the dispatch is just dropped.

The composable wraps its content in BoxWithConstraints so width-based breakpoints re-evaluate when the parent's constraints change.

Known v1 limits (documented also in the module's README):

  • align-content is not modelled in the serialization schema, so multi-line flex containers stack lines from the cross-axis start (cross gap between lines).

  • CSS margin collapsing is not implemented (margin renders as outer padding).

  • onchange is parsed and carried but has no native trigger for built-ins (the subset has no form inputs); only custom components can dispatch it (via emit).


fun JoyDom(view: <Error class: unknown class>, initialState: <Error class: unknown class> = JsonObject(emptyMap()), modifier: Modifier = Modifier, components: JoyDomComponentsConfig = JoyDomComponentsConfig.Empty, painterFactory: JoyDomPainterFactory = CoilPainterFactory, onEvent: JoyDomHostEventHandler? = null, onError: JoyDomStoreErrorHandler? = null)

Render a view template — a document carrying state, defs and handlers alongside layout — with the logic layer wired up.

This is the store-backed entry: a com.j0y.joy.dom.mutation.JoyStore owns the state, every binding that fires is dispatched into it, a bound handler mutates state and the document re-resolves and recomposes. The view never writes; it only fires.

onEvent differs from the Spec overload's on purpose: it receives an com.j0y.joy.dom.mutation.EmittedEvent, and only for what the document did not consume — a binding whose name matches no handler (delivered exactly as the plain overload would) or an event action a handler reached. onError reports an interaction that stopped early; unlike a resolve failure this is not a rollback, so whatever the interaction applied before the failing step is already committed.

A document with no handlers region is inert: every binding flows straight out to onEvent and nothing else happens, which is precisely the plain overload's behaviour.

JoyDom(view = template, initialState = seed, onEvent = { host ->
when (host.name) {
"saveRequested" -> save() // the outbound half of the effect loop
}
})

Hoist the store with rememberJoyDomStore instead when the host needs to read the state, inspect the session log, or drive undo through rewind.


fun JoyDom(store: JoyDomStore, modifier: Modifier = Modifier, components: JoyDomComponentsConfig = JoyDomComponentsConfig.Empty, painterFactory: JoyDomPainterFactory = CoilPainterFactory)

Render a hoisted JoyDomStore. The store's callbacks were fixed when it was created (see rememberJoyDomStore); this overload only draws it and feeds every fired binding back in.


fun JoyDom(resolved: <Error class: unknown class>, modifier: Modifier = Modifier, components: JoyDomComponentsConfig = JoyDomComponentsConfig.Empty, painterFactory: JoyDomPainterFactory = CoilPainterFactory, onEvent: JoyDomEventHandler? = null)

Lower-level entry: render a pre-resolved ResolvedSpec without re-running cascade / breakpoint evaluation. Useful when the caller already has the resolved tree (e.g. from a test fixture or a memoised resolution) and wants to skip viewport probing.