UI component constructors for the Dala framework.
Each function returns a node map compatible with Dala.Renderer. These can
be used directly, via the ~dala 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)
Dala.UI.text(text: "Hello")
# Sigil (import Dala.Sigil or use Dala.Screen)
~dala(<Text text="Hello" />)All three forms produce identical output and are accepted by Dala.Renderer.
Summary
Functions
Returns an :activity_indicator leaf node. Displays a circular loading spinner.
Returns a :box container node. Children are stacked on top of each other (ZStack).
Returns a :button leaf node.
Returns a :camera_preview component node. Renders a live camera feed inline.
Returns a :column container node. Children are laid out vertically (VStack).
Returns a :divider leaf node. A horizontal or vertical divider line.
Returns an :icon leaf node. Displays a platform-native icon.
Returns an :image leaf node. Displays an image from a URL or local asset.
Returns a :list node. A data-driven list (FlatList equivalent).
Returns a :modal container node. Presents content above the enclosing view.
Returns a :native_view node that renders a platform-native component.
Returns a :pressable container node. A pressable wrapper.
Returns a :progress_bar leaf node. Displays a progress bar.
Returns a :refresh_control leaf node. Adds pull-to-refresh to ScrollView.
Returns a :row container node. Children are laid out horizontally (HStack).
Returns a :safe_area container node. Applies safe area insets.
Returns a :scroll container node. A scrollable view (ScrollView equivalent).
Returns a :slider leaf node. A continuous range slider.
Returns a :spacer leaf node. Flexible or fixed space.
Returns a :status_bar leaf node. Controls the status bar appearance.
Returns a :switch leaf node. A boolean toggle switch.
Returns a :tab_bar container node. A tab navigation bar.
Returns a :text leaf node.
Returns a :text_field leaf node. A single-line text input.
Returns a :toggle leaf node. A boolean toggle switch.
Returns a :video leaf node. An inline video player.
Returns a :webview component node. Renders a native web view inline.
Functions
Returns an :activity_indicator leaf node. Displays a circular loading spinner.
Props
:size—:smallor:large(default::small):color— spinner color (default: theme primary):animating— whether spinner is animating (default: true)
Returns a :box container node. Children are stacked on top of each other (ZStack).
Same props as column/2. Useful for overlays, badges, and absolute positioning.
Returns a :button leaf node.
Props
:text— button label (required). Also accepts:titlefor backward compatibility.:on_tap—{pid, tag}tuple; fired when button is pressed:disabled— boolean, disables the button (default: false):text_color— label color (accepts color tokens):text_size— font size:font_weight—"regular","medium","semibold","bold","light","thin":background— button background color (accepts color tokens):padding,:padding_top,:padding_right,:padding_bottom,:padding_left:corner_radius— rounded corners:fill_width— boolean, stretch to fill parent width (default: true from component defaults):accessibility_id— test identifier
Examples
Dala.UI.button(text: "Submit", on_tap: {self(), :submit})
Dala.UI.button(title: "OK", on_tap: {self(), :ok}, background: :primary)
Returns a :camera_preview component node. Renders a live camera feed inline.
Call Dala.Camera.start_preview/2 before mounting this component, and
Dala.Camera.stop_preview/1 when done.
Props
:facing—:back(default) or:front:width,:height— dimensions in dp/pts; omit to fill parent
Returns a :column container node. Children are laid out vertically (VStack).
Props
:gap— spacing between children (accepts spacing tokens like:space_md):padding,:padding_top,:padding_right,:padding_bottom,:padding_left:background— background color (accepts color tokens):border_color,:border_width— optional border:corner_radius— rounded corners:fill_width— boolean, stretch to fill parent width:on_tap,:on_long_press,:on_double_tap,:on_swipe*— gesture handlers:accessibility_id— test identifier
Examples
Dala.UI.column([padding: :space_md, gap: :space_sm], [
Dala.UI.text(text: "Title"),
Dala.UI.text(text: "Subtitle")
])
Returns a :divider leaf node. A horizontal or vertical divider line.
Props
:thickness— line thickness in pt (default: 1.0):color— divider color (accepts color tokens, default::border):padding— padding around the divider
Examples
Dala.UI.divider()
Dala.UI.divider(thickness: 2, color: :primary)
Returns an :icon leaf node. Displays a platform-native icon.
Logical icon names are resolved to SF Symbols on iOS and Material Symbols on
Android. Unknown names pass through verbatim (power users can use raw SF Symbol
identifiers like "globe.americas.fill").
Props
:name— logical icon name or raw identifier (required):text_size— glyph size in sp:text_color— glyph tint color (accepts color tokens):padding,:background— layout props:on_tap,:on_long_press— gesture handlers:accessibility_id— test identifier (also used as accessibility label)
Logical icon names
settings, back, forward, close, add, remove, edit, check,
chevron_right, chevron_left, chevron_up, chevron_down, info,
warning, error, search, trash, share, more, menu, refresh,
favorite, favorite_filled, star, star_filled, user, home
Examples
Dala.UI.icon(name: "settings", text_size: 24, text_color: :on_surface)
Dala.UI.icon(name: "chevron_right", on_tap: {self(), :navigate})
Returns an :image leaf node. Displays an image from a URL or local asset.
Props
:src— URL or local asset name (required):resize_mode—:cover(default),:contain,:stretch,:repeat:width,:height— dimensions in dp/pts; omit to auto-size:corner_radius— optional rounded corners:placeholder_color— color shown while loading:accessibility_id— test identifier
Examples
Dala.UI.image(src: "https://example.com/photo.jpg", resize_mode: :cover, corner_radius: 12)
Returns a :list node. A data-driven list (FlatList equivalent).
Leverages Dala.List for rendering. Requires an :id prop to identify the list
for selection events and custom renderers.
Props
:data— enumerable of items to render (mapped to:items):id— atom identifier for the list (required for selection events):on_end_reached—{pid, tag}tuple; fired when list reaches end:scroll— boolean, enables scrolling (default: true)
For custom item rendering, register a renderer via Dala.List.put_renderer/3 in mount/3.
Examples
Dala.UI.list(id: :my_list, data: assigns.items)
# With custom renderer in mount/3:
# Dala.List.put_renderer(socket, :my_list, fn item -> ... end)
Returns a :modal container node. Presents content above the enclosing view.
Props
:visible— boolean, controls whether modal is shown (default: false):on_dismiss—{pid, tag}tuple; fired when user dismisses modal:presentation_style—:full_screen(default) or:page_sheet
Examples
Dala.UI.modal([visible: true, on_dismiss: {self(), :dismissed}], [
Dala.UI.text(text: "Modal content")
])
Returns a :native_view node that renders a platform-native component.
module must implement the Dala.Component behaviour and be registered
on the native side via dalaNativeViewRegistry. 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
Dala.UI.native_view(MyApp.ChartComponent, id: :revenue_chart, data: @points)
Returns a :pressable container node. A pressable wrapper.
Props
:on_press—{pid, tag}tuple; fired when pressed:on_long_press—{pid, tag}tuple; fired on long press
Examples
Dala.UI.pressable([on_press: {self(), :card_tapped}], [
Dala.UI.text(text: "Tap me")
])
Returns a :progress_bar leaf node. Displays a progress bar.
Props
:progress— float 0.0 to 1.0, current progress (default: 0.0):indeterminate— boolean, shows indeterminate spinner (default: false):color— progress bar color
Returns a :refresh_control leaf node. Adds pull-to-refresh to ScrollView.
Attach as a child of :scroll node. The scroll node handles the refresh gesture.
Props
:on_refresh—{pid, tag}tuple; fired when user pulls to refresh:refreshing— boolean, true while refresh is in progress:tint_color— color of the refresh spinner
Returns a :row container node. Children are laid out horizontally (HStack).
Same props as column/2.
Returns a :safe_area container node. Applies safe area insets.
Renders children within the safe area boundaries (avoiding notches, status bar, etc.).
Returns a :scroll container node. A scrollable view (ScrollView equivalent).
Props
:horizontal— boolean, enables horizontal scrolling (default: false):show_indicator— boolean, show scroll indicator (default: true):on_end_reached—{pid, tag}tuple; fired when scroll reaches bottom/end:on_scroll—{pid, tag}tuple; fired during scrolling with scroll position:padding,:background— layout props
Examples
Dala.UI.scroll([padding: :space_md], [
Dala.UI.text(text: "Long content...")
])
Returns a :slider leaf node. A continuous range slider.
Props
:value— current value (default: 0.0):min_value— minimum value (default: 0.0):max_value— maximum value (default: 1.0):on_change—{pid, tag}tuple; fired with new float value on drag:color— slider tint color:accessibility_id— test identifier
Examples
Dala.UI.slider(value: 0.5, min_value: 0, max_value: 100, on_change: {self(), :volume_changed})
Returns a :spacer leaf node. Flexible or fixed space.
Props
:size— fixed size in pt (omit for flexible spacer that fills available space)
Examples
Dala.UI.spacer() # flexible — fills available space
Dala.UI.spacer(size: 20) # fixed 20pt gap
Returns a :status_bar leaf node. Controls the status bar appearance.
Props
:bar_style—:default(dark text) or:light_content(light text):hidden— boolean, hides the status bar (default: false)
Returns a :switch leaf node. A boolean toggle switch.
Prefer toggle/1 for new code — it uses :on_change consistent with other
value widgets. This function is kept for backward compatibility.
Props
:value— boolean, on/off state (default: false):on_toggle—{pid, tag}tuple; fires{:toggle, tag, new_value}to handler:track_color— color when switch is on:thumb_color— color of the draggable thumb
Returns a :tab_bar container node. A tab navigation bar.
Props
:tabs— list of tab definitions, each a map with:id,:label, and optional:icon:active_tab— the id of the currently selected tab:on_tab_select—{pid, tag}tuple; fired with selected tab id string:accessibility_id— test identifier
Examples
Dala.UI.tab_bar(
tabs: [
%{id: "home", label: "Home", icon: "home"},
%{id: "settings", label: "Settings", icon: "settings"}
],
active_tab: "home",
on_tab_select: {self(), :tab_changed}
)
Returns a :text leaf node.
Props
:text— the string to display (required):text_color— color value (accepts color tokens like:on_surface):text_size— font size (accepts size tokens like:xlor numeric sp):font_weight—"regular","medium","semibold","bold","light","thin":font_family— custom font family name (nil = system font):text_align—:left,:center,:right:italic— boolean:line_height— multiplier (e.g.1.5for 150% line height):letter_spacing— extra spacing in pt:padding,:padding_top,:padding_right,:padding_bottom,:padding_left:background— background color:corner_radius— rounded corners:fill_width— boolean, stretch to fill parent width:on_tap,:on_long_press,:on_double_tap— gesture handlers:accessibility_id— test identifier
Examples
Dala.UI.text(text: "Hello")
Dala.UI.text(text: "Title", text_size: :xl, font_weight: "bold", text_color: :on_surface)
Returns a :text_field leaf node. A single-line text input.
Props
:text— initial/current text value:placeholder— placeholder text when empty:on_change—{pid, tag}tuple; fired on every text change with new value:on_focus—{pid, tag}tuple; fired when field gains focus:on_blur—{pid, tag}tuple; fired when field loses focus:on_submit—{pid, tag}tuple; fired when return key is pressed:on_compose—{pid, tag}tuple; IME composition events (CJK, etc.):keyboard_type—:default,:number,:decimal,:email,:phone,:url:return_key—:done,:next,:go,:search,:send:text_color,:text_size— typography:background,:padding,:corner_radius— layout:accessibility_id— test identifier
Examples
Dala.UI.text_field(placeholder: "Enter name", on_change: {self(), :name_changed})
Dala.UI.text_field(keyboard_type: :email, return_key: :next, on_submit: {self(), :next_field})
Returns a :toggle leaf node. A boolean toggle switch.
Props
:value— boolean, on/off state (default: false):on_change—{pid, tag}tuple; fired with new boolean value on toggle:text— optional label text displayed beside the switch:track_color— color when switch is on:thumb_color— color of the draggable thumb:accessibility_id— test identifier
Examples
Dala.UI.toggle(value: true, on_change: {self(), :notifications_toggled}, text: "Notifications")
Returns a :video leaf node. An inline video player.
Props
:src— video URL (required):autoplay— boolean, start playing immediately (default: false):loop— boolean, loop playback (default: false):controls— boolean, show playback controls (default: true):width,:height— dimensions in dp/pts; omit to fill parent
Examples
Dala.UI.video(src: "https://example.com/clip.mp4", autoplay: true, loop: true)
Returns a :webview component node. Renders a native web view inline.
The JS bridge is injected automatically — the page can call window.dala.send(data)
to deliver messages to handle_info({:webview, :message, data}, socket), and
Elixir can push to JS via Dala.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}inhandle_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