Dala.Ui.Renderer (dala v0.3.2)

Copy Markdown View Source

Serializes a component tree to a binary command stream and passes it to the platform NIF in a single call. Compose (Android) and SwiftUI (iOS) handle diffing and rendering internally.

Node format

%{
  type: :column,
  props: %{padding: :space_md, background: :surface},
  children: [
    %{type: :text,   props: %{text: "Hello", text_size: :xl, text_color: :on_surface}, children: []},
    %{type: :button, props: %{text: "Tap", on_tap: self()},    children: []}
  ]
}

Token resolution

Atom values for color props, spacing props, radius props, and text sizes are resolved at render time through the active Dala.Theme and the base palette.

Color props (:background, :text_color, :border_color, :color, :placeholder_color): resolved via theme semantic tokens first, then the base palette. E.g. :primary → theme's primary → :blue_5000xFF2196F3.

Spacing props (:padding, :padding_top, etc., :gap): accept spacing tokens (:space_xs, :space_sm, :space_md, :space_lg, :space_xl) that are scaled by theme.space_scale.

Radius props (:corner_radius): accept :radius_sm, :radius_md, :radius_lg, :radius_pill from the active theme.

Border (currently honored on :box only): set both :border_color (a color token like :primary or :border) and :border_width (an integer pt/dp value, e.g. 1). When width is 0 or color is unset, no border draws.

Text size props (:text_size, :font_size): token atoms (:xl, :lg, etc.) are multiplied by theme.type_scale.

Component defaults

When a component's props omit styling keys, the renderer injects sensible defaults from the active theme. Explicit props always win over defaults.

# Gets primary background, white text, medium radius automatically:
%{type: :button, props: %{text: "Save", on_tap: {self(), :save}}, children: []}

Style structs

A %Dala.Ui.Style{} value under the :style key is merged into the node's own props before serialisation. Inline props override style values.

Platform blocks

Props scoped to one platform are silently ignored on the other:

props: %{padding: 12, ios: %{padding: 20}}
# iOS sees padding: 20; Android sees padding: 12

Injecting a mock NIF

Dala.Ui.Renderer.render(tree, :android, MockNIF)

Summary

Functions

Return the full color palette map (token → ARGB integer).

Compute the layout hash for a node. Delegates to Dala.Node.compute_layout_hash/1.

Encode patches to binary frame format for the native side (v3)

Encode a PATCH_NODE command with field mask

Encode a REGISTER_STRING command

Encode a SET_STYLE command for style-only updates

Encode a SET_TEXT command

Encode a full Dala.Node tree to binary format (v3)

Encode tree with tap handles for render_fast

Hash a node ID to a stable u64. Delegates to Dala.Node.stable_id/1.

Render a component tree for the given platform.

Return the text-size scale map (token → float sp).

Functions

colors()

@spec colors() :: %{required(atom()) => non_neg_integer()}

Return the full color palette map (token → ARGB integer).

compute_layout_hash(node)

@spec compute_layout_hash(Dala.Node.t()) :: non_neg_integer()

Compute the layout hash for a node. Delegates to Dala.Node.compute_layout_hash/1.

encode_event(target_id, event_type, timestamp, payload)

@spec encode_event(
  String.t() | atom(),
  non_neg_integer(),
  non_neg_integer(),
  binary()
) :: binary()

Encode an EVENT command

encode_frame(patches)

Encode patches to binary frame format for the native side (v3)

encode_patch_node(id, field_mask, changed_props)

@spec encode_patch_node(String.t() | atom(), non_neg_integer(), map()) :: binary()

Encode a PATCH_NODE command with field mask

encode_register_string(string_id, text)

@spec encode_register_string(non_neg_integer(), binary()) :: binary()

Encode a REGISTER_STRING command

encode_set_style(id, props)

@spec encode_set_style(String.t() | atom(), map()) :: binary()

Encode a SET_STYLE command for style-only updates

encode_set_text(id, text)

@spec encode_set_text(String.t() | atom(), binary()) :: binary()

Encode a SET_TEXT command

encode_tree(node)

Encode a full Dala.Node tree to binary format (v3)

encode_tree_with_taps(node, nif, platform, ctx)

Encode tree with tap handles for render_fast

hash_id(id)

@spec hash_id(String.t() | atom()) :: non_neg_integer()

Hash a node ID to a stable u64. Delegates to Dala.Node.stable_id/1.

render(tree, platform, nif \\ Dala.Platform.Native, transition \\ :none)

@spec render(map(), atom(), module() | atom(), atom()) ::
  {:ok, :binary_tree} | {:error, term()}

Render a component tree for the given platform.

Loads the active Dala.Theme, clears the tap registry, serialises the tree to a binary command stream, and calls set_root_binary/1 on the NIF. Returns {:ok, :binary_tree}.

transition is an atom (:push, :pop, :reset, :none) for the nav animation. Defaults to :none (instant swap).

render_fast(tree, platform, nif \\ Dala.Platform.Native, transition \\ :none)

@spec render_fast(Dala.Node.t() | map(), atom(), module(), atom()) ::
  {:ok, :binary_tree}

Fast render path for simple updates.

Optimized version that batches tap registrations with the binary encoding. Otherwise identical to render/4 — loads the active theme, serialises the tree to binary, and calls set_root_binary/1 on the NIF.

render_patches(old_tree, new_tree, platform, nif \\ Dala.Platform.Native, transition \\ :none)

@spec render_patches(
  Dala.Node.t() | map() | nil,
  Dala.Node.t() | map(),
  atom(),
  module(),
  atom()
) :: {:ok, [Dala.Ui.Diff.patch()]}

Render using incremental patches instead of full tree.

Compares old_tree with new_tree, computes the diff, and sends only the patches to native. Falls back to full render on first call (when old_tree is nil).

new_tree can be either a map (from Dala.Ui.Widgets functions) or a Dala.Node struct. If it's a map, it will be converted to a Dala.Node first.

Returns {:ok, patches} where patches is the list of patch tuples.

text_sizes()

@spec text_sizes() :: %{required(atom()) => float()}

Return the text-size scale map (token → float sp).