Juli4nG/elm-json-render/1.0.0

NOTE: the latest version is 3.0.0

JsonRender.Spec

The json-render flat Spec model and its fail-closed decoder, scoped to this package's component set and pinned to @json-render/core v0.19.0.

A Spec is the canonical flat form: { root, elements, state } where elements is a map keyed by id and children are referenced by string key (never nested inline).

Fail-closed by construction. The decoder rejects, rather than silently dropping:

  • an unknown / off-catalog component type (json-render's renderer is fail-open here — we are not);
  • props that don't match the strict per-component shape;
  • a dangling child key, a missing root, or a repeat element with no children (the structural floor validateSpec enforces).

A rejected manifest never produces a partial tree — the host shows an error stub.

Spec

type alias Spec =
{ root : String
, elements : Dict String UIElement
, state : Value
}

A flat json-render spec: a root element key, a keyed map of elements, and the host-owned initial state.

decoder : Decoder Spec

Decode a flat json-render Spec, fail-closed. See the module doc for what is rejected. On any structural or off-catalog error the decoder fails with a diagnostic message; the host renders an error stub rather than a partial tree.

Elements

type alias UIElement =
{ componentType : ComponentType
, props : Props
, children : List String
, on : Dict String (List ActionBinding)
, repeat : Maybe Repeat
}

One element: its (validated) component type, its strictly-decoded props, its child keys, its event bindings, and an optional repeat. Mirrors json-render's UIElement shape (type/props/children/on/repeat), minus the visible/watch siblings this renderer does not support.

= Card
| Stack
| Text
| Badge
| Button
| Checkbox
| FindingsTable

The allowlisted component types. Anything else fails the decode.

The component type's wire name, for diagnostics.

Props

type Props
= CardP CardProps
| StackP StackProps
| TextP TextProps
| BadgeP BadgeProps
| ButtonP ButtonProps
| CheckboxP CheckboxProps
| FindingsTableP FindingsTableProps

Strictly-decoded props, one variant per component type. The variant always agrees with the element's ComponentType (both come from a single read of the type field).

= Row
| Col

Stack layout direction.

type alias CardProps =
{ title : Maybe Expr }

Card props. title is optional and may be any expression.

type alias StackProps =
{ direction : Direction
, gap : Int
}

Stack props: a layout direction and a numeric gap.

type alias TextProps =
{ value : Expr }

Text props: the displayed value expression.

type alias BadgeProps =
{ value : Expr }

Badge props: the value expression (e.g. a status string mapped to a tone).

type alias ButtonProps =
{ label : Expr }

Button props: the label expression.

type alias CheckboxProps =
{ label : Maybe Expr
, checked : Maybe Expr
}

Checkbox props: an optional label and an optional checked binding (typically a two-way $bindState / $bindItem).

type alias FindingsTableProps =
{ bind : Expr
, groupBy : String
}

FindingsTable props: the bind expression pointing at the findings payload and a groupBy field name.

Actions & iteration

type alias ActionBinding =
{ action : String
, params : Value
, confirm : Maybe Confirm
}

An event binding: a named verb, its (unresolved) params, and an optional confirm dialog. The key is action/params per the pinned format — never a URL.

type alias Confirm =
{ title : Expr
, message : Expr
, confirmLabel : Maybe String
, cancelLabel : Maybe String
, variant : String
}

A confirm dialog shown by the renderer before an action emits. title and message may be expressions (the per-row Scan message is a $template).

type alias Repeat =
{ statePath : String
, key : Maybe String
}

Element-level iteration: statePath points at a state array, key is the optional stable-list item field.