Packages
mob
0.5.14
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.26
0.6.25
0.6.24
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.2
0.6.1
0.6.0
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.11
0.5.10
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
BEAM-on-device mobile framework for Elixir
Current section
Files
Jump to
Current section
Files
lib/mob/ui.ex
defmodule Mob.UI do
@moduledoc """
UI component constructors for the Mob framework.
Each function returns a node map compatible with `Mob.Renderer`. These can
be used directly, via the `~MOB` sigil, or mixed freely — they produce the
same map format.
# Native map literal
%{type: :text, props: %{text: "Hello"}, children: []}
# Component function (keyword list or map)
Mob.UI.text(text: "Hello")
# Sigil (import Mob.Sigil or use Mob.Screen)
~MOB(<Text text="Hello" />)
All three forms produce identical output and are accepted by `Mob.Renderer`.
"""
@text_props [:text, :text_color, :text_size]
@doc """
Returns a `:text` leaf node.
## Props
* `:text` — the string to display (required)
* `:text_color` — color value passed to `set_text_color/2` in the NIF
* `:text_size` — font size in sp passed to `set_text_size/2` in the NIF
## Examples
Mob.UI.text(text: "Hello")
#=> %{type: :text, props: %{text: "Hello"}, children: []}
Mob.UI.text(text: "Hello", text_color: "#ffffff", text_size: 18)
#=> %{type: :text, props: %{text: "Hello", text_color: "#ffffff", text_size: 18}, children: []}
"""
@spec text(keyword() | map()) :: map()
def text(props) when is_list(props), do: text(Map.new(props))
def text(%{} = props) do
%{
type: :text,
props: Map.take(props, @text_props),
children: []
}
end
@doc """
Returns a `:webview` component node. Renders a native web view inline.
The JS bridge is injected automatically — the page can call `window.mob.send(data)`
to deliver messages to `handle_info({:webview, :message, data}, socket)`, and
Elixir can push to JS via `Mob.WebView.post_message/2`.
Props:
* `:url` — URL to load (required)
* `:allow` — list of URL prefixes that navigation is permitted to (default: allow all).
Blocked attempts arrive as `{:webview, :blocked, url}` in `handle_info`.
* `:show_url` — show a native URL label above the WebView (default: false)
* `:title` — static title label above the WebView; overrides `:show_url`
* `:width`, `:height` — dimensions in dp/pts; omit to fill parent
"""
@spec webview(keyword() | map()) :: map()
def webview(props \\ [])
def webview(props) when is_list(props), do: webview(Map.new(props))
def webview(%{} = props) do
allow_str = (props[:allow] || []) |> Enum.join(",")
node_props =
%{url: props[:url] || "", allow: allow_str, show_url: props[:show_url] || false}
|> then(fn p -> if props[:title], do: Map.put(p, :title, props[:title]), else: p end)
|> then(fn p -> if props[:width], do: Map.put(p, :width, props[:width]), else: p end)
|> then(fn p -> if props[:height], do: Map.put(p, :height, props[:height]), else: p end)
%{type: :web_view, props: node_props, children: []}
end
@doc """
Returns a `:camera_preview` component node. Renders a live camera feed inline.
Call `Mob.Camera.start_preview/2` before mounting this component, and
`Mob.Camera.stop_preview/1` when done.
Props:
* `:facing` — `:back` (default) or `:front`
* `:width`, `:height` — dimensions in dp/pts; omit to fill parent
"""
@spec camera_preview(keyword() | map()) :: map()
def camera_preview(props \\ [])
def camera_preview(props) when is_list(props), do: camera_preview(Map.new(props))
def camera_preview(%{} = props) do
%{
type: :camera_preview,
props: Map.take(props, [:facing, :width, :height]),
children: []
}
end
@doc """
Returns a `:native_view` node that renders a platform-native component.
`module` must implement the `Mob.Component` behaviour and be registered
on the native side via `MobNativeViewRegistry`. The `:id` must be unique
per screen — a duplicate raises at render time.
All other props are passed to `mount/2` and `update/2` on the component.
## Example
Mob.UI.native_view(MyApp.ChartComponent, id: :revenue_chart, data: @points)
"""
@spec native_view(module(), keyword() | map()) :: map()
def native_view(module, props \\ [])
def native_view(module, props) when is_list(props), do: native_view(module, Map.new(props))
def native_view(module, %{} = props) when is_atom(module) do
%{type: :native_view, props: Map.put(props, :module, module), children: []}
end
end