Expand description
Mobiler runtime — the developer-facing API.
Implement MobilerApp with your typed events, model, and view (built
from the builders). Mobiler wraps it in MobilerShell, a
Crux app speaking the fixed UI ABI (mobiler_ui); you never touch the wire
protocol. Device APIs are capabilities via Cx.
Re-exports§
pub use dialog::Confirm;pub use dialog::Picker;pub use format::Currency;pub use format::Locale;pub use format::Weekday;pub use http::HttpHeader;pub use http::HttpOutcome;pub use i18n::Catalog;pub use i18n::negotiate;pub use transfer::TransferEvent;
Modules§
- bunny
- Bunny.net Stream URL helpers — pure string builders, no I/O.
- dialog
- Labels for the built-in confirm dialog and date/time pickers, so an app can word the buttons in
its own language and say what they do (“Cancel booking” / “Keep it”) instead of a generic
OK / Cancel. Used with
Cx::confirm_with,Cx::pick_date_withandCx::pick_time_with. - format
- Locale-aware number, currency, and date formatting — pure, synchronous, dependency-light.
- http
- The HTTP capability’s payload types.
- i18n
- Tiny, dependency-free localization: pick a UI language from the device, then translate keys.
- transfer
- Streaming file transfers (
cx.upload/cx.download).
Structs§
- Button
Opts - Extra options for
button_with;ButtonOpts::default()is a plainbutton. - Caption
- One subtitle/caption track for a
Widget::Video.urlpoints at a WebVTT (.vtt) file,languageis a BCP-47 tag (e.g."en"),labelis the human-readable menu entry, anddefault_onselects it by default. Sidecar tracks work on web (<track>) and Android (Media3 subtitle configuration); on iOS only captions already embedded in an HLS manifest are selectable (AVPlayer can’t attach a sidecar VTT to an MP4 — a documented v1 gap). - Chart
Bracket - A right-side bracket annotation spanning
[y0, y1]with alabelnote (e.g. a ceiling band). - Chart
Legend Item - One legend entry (swatch + name) for a
Widget::RegionChart. - Chart
RefLine - A horizontal reference line across a
Widget::RegionChartatvalue, with a right-edgelabelchip.dasheddraws it dashed (e.g. a “max insured” ceiling) vs solid (a target). - Chart
Region - One rectangle in a
Widget::RegionChart, spanning[x0, x1]horizontally and[y0, y1]vertically in the chart’s domain.labelis centered inside (empty = none);verticalrotates it 90° for narrow columns.coloroverrides the auto-assigned palette slot. - Chart
Series - One named data series in a
Widget::Chart. Cartesian styles plotvaluesacross the chart’s x-axislabels; circular styles (pie/donut/rings/gauge) collapse the series to a single magnitude (valuessummed).coloroverrides the auto-assigned palette slot;goalis the denominator forRings/Gaugeprogress (ignored by the other styles). - Chart
Tick - An x-axis tick on a
Widget::RegionChartat domain positionat, labelledlabel. Ticks are irregular (the app places them), so shells position them by fraction, not even spacing. - Cx
- Effects an app requests during
update, generic over the app event type so continuations stay fully typed. - Fab
- A floating action button anchored over the scaffold body (the raised primary action).
- MapMarker
- A pin on a
Widget::Map.idis echoed back when the marker is tapped (Action::Input { id: "{map_id}.marker", value: Text(marker.id) }). - Mobiler
Shell - Crux adapter: turns a
MobilerAppinto an app speaking the fixed ABI. - Nav
- A navigation stack the app holds in its
Model. The core owns the stack (single source of truth); the framework reads itsroute/depthto drive the shell’s push/pop transitions and back button. - Plugin
Call - Plugin
Notify - Plugin
Response - A plugin’s reply.
outputis raw bytes: the HTTP capability puts a bincodeHttpOutcomehere, while most plugins put UTF-8 text (usePluginResponse::textto build one andas_textto read it). - Plugin
Stream Call - A streaming plugin subscription (powers
Effect::PluginStream). LikePluginCallbut carries a caller-chosenkeyso the subscription can be torn down (Cx::unsubscribe) — the shell registers the native source underkey. - Rgb
- A 24-bit RGB color. Used for a theme’s brand/seed color — the one place an app supplies an arbitrary color (everything else is intent tokens).
- Segment
- One option in a
Widget::Segmentedcontrol (mirrorsTab).selectedmarks the active segment; tapping sendson_select. - Sheet
- A modal bottom sheet anchored over the scaffold body (a scrim behind, a panel rising from
the bottom). Present (
Some) ⇒ open; tapping the scrim/handle sendson_dismiss. - Shell
Labels - Text the shells draw themselves (back buttons, web list controls, dialog/picker defaults), in the
app’s language. Set once on the scaffold with
with_labels; every field is optional and falls back to the shell’s built-in English. A label passed to a specific call (confirm_with,Picker) still wins over these. - Swipe
Button - One revealed action in a
SwipeActionrow (swipe to reveal, tap to fire). - Tab
- A bottom-navigation tab.
selectedmarks the active one; tapping sendson_select.icon(optional) renders above the label for an icon tab bar. - Theme
- App branding as data — the visual twin of
dark_mode. Set on aWidget::Scaffold(theme: None= the framework defaults, i.e. no visual change). The shell maps these to its native theming:seed→ the brand/primary color (Android M3 scheme / iOS tint / web--primary), plus a global corner, spacing, and font choice.
Enums§
- A11y
Role - Accessibility role for
Widget::A11y— the control type announced to a screen reader. Maps best-effort per platform: iOS accessibility traits, Android semantics role /heading(), web ARIA role. - Action
- What the shell sends back to the core. Fixed across all apps.
- BoxAlign
- Button
Style - Button emphasis.
Tonalis the quieter filled secondary (M3 filled-tonal). - Card
Style - Chart
Style - How a
Chartdraws its series. - Corner
- Global corner-radius scale.
Medium≈ the current (un-themed) look. - Density
- Global density.
Comfortable≈ the current (un-themed) look;Compacttightens spacing.Largeis for hurried / wet / gloved hands: bigger controls (56 buttons & segmented, 48 chips & calendar days, 56 icon-button targets), 16 control labels, ≥ 12 between adjacent tappables. Body text stays on the platform’s font-scale setting. - Effect
- Built-in capabilities the generic shell fulfils.
- Effect
Ffi - Field
Kind - What a
Widget::TextFieldaccepts — selects the on-screen keyboard, secure (masked) entry, and single- vs multi-line layout in one axis. - Font
Family - A finite, cross-platform font family (maps to each platform’s nearest system
font design — no bundled font files).
System≈ the current look. - Icon
- A finite icon set (maps to Material icons / SF Symbols / web glyphs per shell). Grouped: editing, navigation/chrome, content, and domain icons.
- Image
Ratio - Image
Shape - Input
Value - A value produced by an input widget at runtime.
- Project
Color - Project-identity colors (distinct from semantic
Tone). Concrete RGB decided in the render layer. - Spacing
- Text
Style - Tone
- Semantic status color (distinct from brand/identity color).
- Widget
- The app-agnostic widget tree the shell renders. Fixed across all apps.
Traits§
- Mobiler
App - What a Mobiler app implements. Write typed domain events; Mobiler serializes them into opaque tokens behind the scenes.
Functions§
- a11y
- Wrap
childso a screen reader (VoiceOver / TalkBack) announces the subtree as ONE element namedlabel— gives an unlabeledicon_button/imagea name, or groups a card’s children into one announced element. Addwith_a11y_hint/with_a11y_rolefor the activation hint + control type. - avatar
- A circular avatar image.
- avatar_
status - A circular avatar image with a colored status dot.
- badge
- bar_
chart - A bar chart of
values(normalized to the max), with optional per-valuelabels. Single-series, no axis or legend — for richer charts usechart. - button
- button_
with - A button with a
ButtonOptstone, leading icon, and/or full width. - calendar
- An inline month calendar for
year/month(1–12), US English (Sunday-first).on_day(d)builds the tap event for each dayd;selectedhighlights a day. Seecalendar_infor a localized calendar with per-day markers. - calendar_
in - A localized inline month calendar: the title, weekday header and week start follow
locale(e.g.Locale::SrLatn→ “Septembar 2026”, Monday-firstP U S Č P S N).markersis one busy-level per day (markers[d-1],0..=3, drawn as that many dots;0= none) — pass&[]for no markers. Shorter slices pad with0; levels above 3 clamp to 3. - caption
- card
- card_
button - A tappable card carrying a typed press event.
- chart
- A multi-series chart in the given
style, with optional x-axislabels, y-axisgridlines/ ticks (cartesian styles), and a serieslegend. The general builder behind the convenience constructors below. - checkbox
- chip
- color_
dot - A small colored identity dot.
- column
- decimal_
field - A decimal keypad field (
FieldKind::Decimal). - divider
- donut_
chart - A donut chart (pie with a center hole). Legend on.
- email_
field - An email-keyboard field (
FieldKind::Email). - emphasis
- field
- A text field with full control over
FieldKindand an optional inline validationerror. The kind-specific helpers below (secure_field,email_field, …) wrap this for the common cases. - gauge_
chart - A single radial gauge — the first series’
value / goalwith the number in the center. - grid
- icon_
button - image
- lazy_
list - A scrollable list for long/paged feeds that fires
on_load_morewhen the user scrolls near the end. The app owns the state: append tochildrenon each load-more event, setloadingtrue while the page loads (the shell shows a spinner and won’t re-fire), andhas_more=falsewhen the feed is exhausted. Add pull-to-refresh at the top withwith_refresh. Give it room — aLazyListnested in a scrollable body needs a bounded height to scroll on its own. - lazy_
list_ static - A scrollable list with no load-more and no refresh — a plain virtualized list of
children. - line_
chart - A line chart of
values(normalized to the max), with optional per-valuelabels. Single-series, no axis or legend — for richer charts usechart. - map
- An interactive map centered at (
center_lat,center_lng) with the givenzoom(≈ MapLibre/Google zoom levels: ~2 world, ~14 city, ~17 street). iOS MapKit / Android MapLibre / web MapLibre-GL — no API key. Add pins withwith_markers, a vector style withwith_map_style. Taps arrive inMobilerApp::inputasInput { id: "{id}.tap", Text("lat,lng") }/{ "{id}.marker", Text(id) }. Give it a height (a sized container or card). - marker
- A map pin at (
lat,lng);idis echoed on tap. Add a title withmarker_titled. - marker_
titled - A titled map pin (the title shows in the marker’s callout/popup).
- multiline_
field - A growable multi-line text area (
FieldKind::Multiline). - nav_
scaffold - Scaffold driven by a
Navstack: fillsroute(from the current route’s serialization) anddepth(stack depth) so the shell animates transitions, and shows a back affordance (top-bar arrow + system back button) firingon_backwhenever the stack can pop. - number_
field - A whole-number keypad field (
FieldKind::Number). - pct_
stacked_ bar_ chart - Bars where each x-slot fills to 100% — series as proportions. Legend on, no value axis.
- pdf_
view - An in-app PDF viewer for the document at
url(remote https URL or local file URI) — rendered natively per platform (PDFKit /PdfRenderer/<iframe>). The app just supplies the URL, e.g. a backend-generated report. Give it room (place in a sized container or a scroller). - phone_
field - A phone-keypad field (
FieldKind::Phone). - pie_
chart - A pie chart — each series is one wedge sized by its magnitude. Legend on.
- progress
- A progress bar (
Some(0.0..=1.0)) or an indeterminate spinner (None). - rating
- A read-only star rating.
valueis in tenths (e.g.48= 4.8 ofmaxstars). - rating_
input - A tappable star rating —
on_ratecarries one event per star (star i fireson_rate[i]). - region_
chart - A variable-width stacked-region (“coverage-gap” / Marimekko) chart.
regionsare rectangles in the[0, x_max] × [0, y_max]plane (build withChartRegion::new);tickslabel the irregular x-axis;ref_linesare horizontal target/max lines (ChartRefLine::target/::max);legendnames the colors. Add a right-side bracket annotation withwith_bracket. - rings_
chart - Concentric progress rings — one per series, swept by
sum(values) / goal. Legend on. Give each series a goal viaChartSeries::with_goal. - row
- scaffold
- App shell: top bar + bottom-nav
tabs+ scrollablebody.dark_modeis theme-as-data (the shell themes the whole app from it). - scaffold_
back - Like
scaffold, but the top bar (and the system back button) navigate back viaback— e.g. a detail screen pushed over a tab (treated as depth 2). For multi-level stacks, drive navigation withNav+nav_scaffold. - scroller
- Horizontally scrolling row of children (a carousel / chip rail).
- scroller_
hinted - A
scrollerwhose trailing edge fades out — a hint that it scrolls. - search_
field - A search input (leading magnifier, pill); emits
Input { id, Text }liketext_field. - secure_
field - A masked password field (
FieldKind::Secure). - segment
- One option in a
segmentedcontrol, carrying a typed selection event. - segmented
- A single-choice segmented control (exclusive options in a pill).
- skeleton
- A shimmer placeholder shown while content loads.
- slider
- spacer
- split
- A two-pane master-detail layout (
Widget::Split). Side-by-side on a wide screen (tablet / landscape); one pane on a phone —primaryuntilshow_detail(the app sets it on selection), thendetailwith a back chevron firingon_back. On wide,detailshould show a placeholder until a row is selected. - stack
- Z-stack/overlay (the
Boxwidget). Withscrim, the first child is a darkened background and the rest render on top. - stacked_
bar_ chart - Bars stacked to a total per x-slot. Axis + legend on by default.
- stepper
- styled
- subtitle
- swipe_
action - A list row that reveals trailing
actions(label, tone, event) on horizontal swipe; each is tappable. On web the actions render inline (no gesture). - tab
- A bottom-nav tab carrying a typed selection event (label-only).
- tab_
icon - A bottom-nav tab with a leading icon (icon tab bar).
- text
- text_
field - title
- toggle
- url_
field - A URL-keyboard field (
FieldKind::Url). - video_
player - A controllable native video player for
url(remote MP4/HLS or a local file URI), rendered with the native player per platform (AVPlayer / Media3 ExoPlayer /<video>).idroutes the ~once-per-second position intoinput(id, InputValue::Int(position_ms)); build it fresh each render with the currentplaying(play/pause) +seek_to_ms(the shell jumps when this CHANGES;-1= no seek).on_endedfires when the clip finishes. Defaults: controls shown, not looping/muted, no poster, no resume offset, no captions, rate 1.0, full volume, single clip (no playlist), PiP off — tune withwith_loop/with_muted/without_controls/with_poster/with_start_at/with_captions/with_rate/with_volume/with_pip(orvideo_playlistfor a queue). Give it room. - video_
playlist - A controllable native video player over a playlist of
urls(auto-advances gaplessly; the shell reports the current track viainput("{id}.index", InputValue::Int(i))).start_indexis the first clip; build it fresh each render with the currentplaying. Force-jump to a track by pairing this withwith_seek_index.on_endedfires when the LAST clip finishes. Same cosmetic modifiers asvideo_player. Emptyurlsrenders nothing useful — usevideo_playerfor one clip. - web_
view - A native web view showing the page / embedded player at
url(WKWebView/ AndroidWebView/<iframe>). General-purpose: docs, dashboards, or a hosted player embed (e.g. a Bunny.net / YouTube embed URL). NOT the default video player — usevideo_playerfor that. Give it room (a sized container or a card). - with_
a11y_ hint - Set the accessibility activation hint (e.g. “Opens your bookings”); wraps
widgetif it isn’t ana11ywrapper yet. - with_
a11y_ role - Set the accessibility role / control type; wraps
widgetif it isn’t ana11ywrapper yet. - with_
bracket - Attach a right-side bracket annotation to a
region_chart(no-op on any other widget). - with_
captions - Attach subtitle/caption tracks to a
video_player(seeCaption). No-op on non-Video widgets. - with_
end_ label - Text shown at the end of an exhausted paged list (a
lazy_listwhosehas_moreis false) — e.g. “You’re all caught up”, in the app’s language. Without it nothing is shown there. Combines withwith_refreshin either order. No-op on other widgets. - with_
error - Attach an inline validation message to a
Widget::TextField, marking it invalid. No-op on any other widget. - with_
fab - Anchor a floating action button over a scaffold’s body (the raised primary action).
No-op on any other widget:
with_fab(scaffold(...), Icon::Add, Msg::New). - with_
labels - Set the app-wide shell text (see
ShellLabels) on a scaffold — e.g.with_labels(root, ShellLabels::new().back("Nazad").ok("U redu").cancel("Otkaži"))also puts those words on a plaincx.confirm. Combines with the other scaffold helpers in any order. No-op on other widgets. - with_
long_ press - Attach a long-press (press-and-hold) event to a
Card. No-op on any other widget. Combines withcard/card_button— a card can carry both a tap and a long-press. - with_
loop - Loop a
video_player(restart on end). No-op on non-Video widgets. - with_
map_ style - Set the MapLibre vector-style URL (Android + web; iOS MapKit ignores it). None → a free default.
- with_
markers - Add/replace the pins on a
map(no-op on any other widget). - with_
muted - Start a
video_playermuted (needed for reliable autoplay). No-op on non-Video widgets. - with_
pip - Enable Picture-in-Picture on a
video_player(the shell adds a PiP affordance). No-op otherwise. - with_
poster - Show
poster(an image URL) before the first play / while idle. No-op on non-Video widgets. - with_
rate - Set playback speed (
1.0= normal) on avideo_player. No-op on non-Video widgets. - with_
refresh - Enable pull-to-refresh on a scaffold’s body: the body becomes pull-refreshable and fires
on_refreshon pull.refreshingis app-owned — set it true when the pull fires and clear it when the async reload completes (the shell shows a spinner while true). No-op on other widgets. - with_
seek_ index - Force a playlist
video_playlistto jump to trackindexwhen this CHANGES. No-op otherwise. - with_
sheet - Open a modal bottom sheet over a scaffold’s body. No-op on any other widget — drive it from
the model:
with_sheet(scaffold(...), title, sheet_body, Msg::CloseSheet). - with_
start_ at - Resume a
video_playeratstart_at_ms(applied once on load). No-op on non-Video widgets. - with_
theme - Apply a
Themeto a scaffold (brand color, corner, density, font). No-op on any other widget. Lets an app brand its UI without new scaffold builder overloads:with_theme(nav_scaffold(...), Theme { seed, ..Default::default() }). - with_
volume - Set the volume (
0.0–1.0) on avideo_player. No-op on non-Video widgets. - without_
controls - Hide the native transport controls on a
video_player(the app drives it). No-op otherwise.