The ~MOB sigil for declarative native UI.
Compiles a tag template to a Mob.Renderer-compatible node map at compile
time using NimbleParsec. Expressions in {...} are evaluated in the
caller's scope at runtime.
Use ~MOB(...) for single nodes or ~MOB"""...""" for nested layouts.
Examples
import Mob.Sigil
# Self-closing
~MOB(<Text text="Hello" />)
#=> %{type: :text, props: %{text: "Hello"}, children: []}
# Nested layout
~MOB"""
<Column padding={:space_md}>
<Text text="Title" text_size={:xl} />
<Button text="OK" on_tap={{self(), :ok}} />
</Column>
"""
# Expression child — inject any node map or list of maps
~MOB"""
<Column>
{Enum.map(items, fn i -> ~MOB(<Text text={i} />) end)}
</Column>
"""Tag whitelist
Tags are validated against priv/tags/ios.txt and priv/tags/android.txt at
compile time. Unknown tags emit a warning but still pass through — the type
atom is derived by converting PascalCase to snake_case (e.g. TabBar →
:tab_bar). This allows new native tags to be used before the whitelist is
updated.
Summary
Functions
Parses the given binary as brace_content.
Parses the given binary as node.
Parses the given binary as parse_template.
Compiles a ~MOB(...) or ~MOB"""...""" template into a native UI node map.
Parsed at compile time; {expr} values evaluated at runtime in the caller's scope.
Functions
@spec brace_content(binary(), keyword()) :: {:ok, [term()], rest, context, line, byte_offset} | {:error, reason, rest, context, line, byte_offset} when line: {pos_integer(), byte_offset}, byte_offset: non_neg_integer(), rest: binary(), reason: String.t(), context: map()
Parses the given binary as brace_content.
Returns {:ok, [token], rest, context, position, byte_offset} or
{:error, reason, rest, context, line, byte_offset} where position
describes the location of the brace_content (start position) as {line, offset_to_start_of_line}.
To column where the error occurred can be inferred from byte_offset - offset_to_start_of_line.
Options
:byte_offset- the byte offset for the whole binary, defaults to 0:line- the line and the byte offset into that line, defaults to{1, byte_offset}:context- the initial context value. It will be converted to a map
@spec node(binary(), keyword()) :: {:ok, [term()], rest, context, line, byte_offset} | {:error, reason, rest, context, line, byte_offset} when line: {pos_integer(), byte_offset}, byte_offset: non_neg_integer(), rest: binary(), reason: String.t(), context: map()
Parses the given binary as node.
Returns {:ok, [token], rest, context, position, byte_offset} or
{:error, reason, rest, context, line, byte_offset} where position
describes the location of the node (start position) as {line, offset_to_start_of_line}.
To column where the error occurred can be inferred from byte_offset - offset_to_start_of_line.
Options
:byte_offset- the byte offset for the whole binary, defaults to 0:line- the line and the byte offset into that line, defaults to{1, byte_offset}:context- the initial context value. It will be converted to a map
@spec parse_template(binary(), keyword()) :: {:ok, [term()], rest, context, line, byte_offset} | {:error, reason, rest, context, line, byte_offset} when line: {pos_integer(), byte_offset}, byte_offset: non_neg_integer(), rest: binary(), reason: String.t(), context: map()
Parses the given binary as parse_template.
Returns {:ok, [token], rest, context, position, byte_offset} or
{:error, reason, rest, context, line, byte_offset} where position
describes the location of the parse_template (start position) as {line, offset_to_start_of_line}.
To column where the error occurred can be inferred from byte_offset - offset_to_start_of_line.
Options
:byte_offset- the byte offset for the whole binary, defaults to 0:line- the line and the byte offset into that line, defaults to{1, byte_offset}:context- the initial context value. It will be converted to a map
Compiles a ~MOB(...) or ~MOB"""...""" template into a native UI node map.
Parsed at compile time; {expr} values evaluated at runtime in the caller's scope.