Expand description
The app-facing api feature: builders
returning impl View<State> compositions over the platform-agnostic
controls/runtime/events machinery crate already carries — the
facade-glue half of this crate that sanctions depending on frust.
§Feature-gated, not the crate’s default shape
Everything under this module compiles ONLY behind the default-on
frust-api feature — cargo check -p frust-native-widgets --no-default-features must still hold the platform-plugin charter line
(frust-plugin + FFI crates only, docs/ARCHITECTURE.md’s Module
Structure): no frust/frust-core dependency reaches the crate at all
with the feature off. See Cargo.toml’s comment on why this crate keeps
frust-core alongside frust under the same gate (a downstream View
impl needs BuildCtx/ChangeFlags, which the frust facade does not
re-export).
§The internal NativeWidget trait is still not the public one
Every builder in [builders] is a plain data struct implementing
frust_core::Component (frust-core’s retained-local-state seam) —
never the crate’s own pub(crate) [crate::runtime::NativeWidget] trait,
which stays internal permanently.
The public form is a different trait entirely:
crate::component::NativeComponent, with &self methods, already-typed
Props the app constructs directly, no decode_props step and no Result
returns. The eleven builders here keep riding the internal trait’s wire
(params_json in, EventPayload callbacks out) unchanged — bridging the
public trait onto the same runtime (crate::component::Bridge) is what let
that stay true.
§Two builder families, one slot shape
The eleven built-in controls above are one family (native_segmented/
native_stepper on iOS/macOS only and native_tab_bar on iOS only — a
compile-time refusal banner elsewhere; native_date_picker on all three
arms, reporting a CivilDate); native_component is
the generic one, mounting any registered
NativeComponent (another plugin’s
included — an app crate cannot implement one; see that trait’s own doc)
into the same single platform_view slot, reusing the eight’s
own factory constant, slot counter, sizing rule and refusal placeholder.
It is what closes define → register → mount; the eight are deliberately
not rewritten to route through it (see src/api/mount.rs’s module doc).
§One platform_view slot per control
Each builder composes exactly one frust::platform_view slot resolving to
this crate’s one Android factory
(dev.frust.nativewidgets.FrustNativeControlFactory)
— N controls = N slots, within the differ’s design envelope (a
shared-container optimization is future work).
§Native presentations — not a slot
show_native_alert / show_native_alert_into and
show_native_sheet / show_native_sheet_into are the app-facing
front door to crate::present: an alert or a sheet is an imperative
request answered by one outcome, never a platform_view slot (nor does a
sheet host one — its content is a constrained native schema). The _into
forms write that outcome into an RwSignal, the same events-as-signals
idiom the builders’ on_... callbacks follow, spawned on
frust::spawn_local.
§Theme ladder L2
Each builder’s Component::build reads the active theme
(use_context::<Theme>()) and folds it, via [theme::resolve], into the
same params_json body every other property already rides — see
[theme]’s module doc for the mapping table and crate::android::theme
for L1 (the night-qualified Context control creation builds against).
Structs§
- Civil
Date - The date value
native_date_pickershows and reports — defined beside the control (crate::controls::date_picker) because the platform-agnostic event vocabulary carries it too, and re-exported here as the builder’s public vocabulary. A calendar date — year, month, day — with no time of day and no time zone: what a native date picker shows and what its change handler reports. - Native
Button View - A real
android.widget.Buttonrendered from pure Rust — see the module docs. Build one withnative_button. - Native
Component View - One mounted
NativeComponent— build it withnative_component. - Native
Date Picker View - A real DATE-mode picker (no time) rendered from pure Rust —
android.widget.DatePicker,UIDatePicker,NSDatePicker. Controlled, likeNativeSwitchView: the app ownsdate, and a pick only ever arrives throughSelf::on_changeas a requestedCivilDatethe app confirms by feeding it back. Build one withnative_date_picker. - Native
Image View - A real
android.widget.ImageViewrendered from pure Rust, showing app-supplied encoded bytes (PNG/JPEG/WebP — whateverBitmapFactoryreads). Display-only (no listener, no.interactive()). Build one withnative_image. - Native
Label View - A real
android.widget.TextViewrendered from pure Rust — display-only (no listener, no.interactive()). Build one withnative_label. - Native
Progress View - A real
android.widget.ProgressBarrendered from pure Rust — display-only (no listener, no.interactive()). Build one withnative_progress. - Native
Segmented View - A real segmented control rendered from pure Rust —
UISegmentedControlon iOS/iPadOS,NSSegmentedControlon macOS, and a frust-drawn refusal banner everywhere else (Android included: see [SEGMENTED_ARM]). A controlled component, likeNativeSwitchView: the app ownsselected, and a tap only ever arrives throughSelf::on_selectas a requested index. Build one withnative_segmented. - Native
Slider View - A real
android.widget.SeekBarrendered from pure Rust — controlled, likeNativeSwitchView: the app ownsvalue, and a drag only ever arrives throughSelf::on_changeas a requested value. Build one withnative_slider. - Native
Spinner View - A real indeterminate activity indicator rendered from pure Rust —
display-only (no listener, no
.interactive()). Build one withnative_spinner. - Native
Stepper View - A real increment/decrement control rendered from pure Rust —
UIStepperon iOS/iPadOS,NSStepperon macOS, and a frust-drawn refusal banner everywhere else (Android included: see [STEPPER_ARM]). A controlled component, likeNativeSliderView: the app ownsvalue, and a tap on either button only ever arrives throughSelf::on_changeas a requested value. Build one withnative_stepper. - Native
Switch View - A real
android.widget.Switchrendered from pure Rust — a controlled component (docs/CODE_STANDARDS.md’s Interaction Semantics): the app ownschecked, and a user toggle only ever arrives throughSelf::on_toggleas a requested value. Build one withnative_switch. - Native
TabBar View - A real, bare
UITabBaron iOS/iPadOS — a controlled bottom tab bar that never navigates by itself: a tap reports the requestedTabIdthroughSelf::on_select, the app routes (typicallyRouteNavigator::go) and feeds the confirmed id back asselectedon the next build. A tap on the tab already showing reports throughSelf::on_reselectinstead (“scroll to top / pop to root”). macOS and Android (and every host target) render a frust-drawn refusal banner. Build one withnative_tab_bar. - TabId
- A tab’s stable, app-chosen identity — what
native_tab_bar’sselectednames and whatNativeTabBarView::on_select/NativeTabBarView::on_reselectreport. Never an index: reordering or inserting items keeps every id meaning the same tab. - TabItem
- One tab of a
native_tab_bar: a stableTabId, a title, an icon, and optionally a selected-state icon, a badge and a disabled state.
Enums§
- Native
Date Picker Style - How
NativeDatePickerViewpresents itself — the public mirror ofcrate::controls::date_picker::DatePickerStyle, which stayspub(crate). - Native
Image Fit - How a
NativeImageViewscales its bytes into the slot’s box — the public mirror ofcrate::controls::image::Fit, which stayspub(crate). - Native
Spinner Size - How large the spinner renders — the public mirror of
crate::controls::spinner::SizeClass, which stayspub(crate). iOS has no distinct small style (UIActivityIndicatorView.Styleoffers only.medium/.large), soSelf::Smallrenders the same asSelf::Mediumon that one arm — seecrate::controls::spinner’s module doc. - TabIcon
- A tab’s icon: encoded image bytes, or an Apple SF Symbol name — never an arbitrary string passed off as a cross-platform icon (the bar is iOS-only, and a symbol name means nothing anywhere else).
Functions§
- ensure_
native_ factory_ registered - Make sure this build’s platform factory exists before the host can look it up — optional: every builder already does this for you.
- live_
slot_ count - The number of native controls this crate’s internal runtime currently
retains — the leak bar
registry::Registry::live_count’s own doc comment describes (“the number the leak bar every create/dispose cycle must return to0”), surfaced app-side for exactly one reason: a device-gate harness (a mount/unmount cycler plus a 50-slot stress toggle,examples/native-widgets-demo/src/pages/stress.rs’s GATE HARNESS section) needs an in-app readout to prove the teardown-retire path disposes promptly rather than waiting out the differ’s missing-streak backstop (crate::registry’s module doc’s Idle-deferred dispose finding). - native_
button - A native
Buttoncaptionedtext— seeNativeButtonView. - native_
component - Mount the registered
NativeComponentCas one native slot, driven byprops. - native_
date_ picker - A native date picker showing
date— seeNativeDatePickerView. - native_
image - A native
Imageshowingbytes— seeNativeImageView. - native_
label - A native
Labelshowingtext— seeNativeLabelView. - native_
progress - A native
ProgressBaratvalue, ranging over[min, max]— seeNativeProgressView. - native_
segmented - A native segmented control over
labels, with the app-ownedselectedsegment — seeNativeSegmentedView. An out-of-rangeselectedshows no selection rather than failing; at most 64 segments are shown (crate::controls::segmented::MAX_SEGMENTS). - native_
slider - A native
Slideratvalue, ranging over[min, max]— seeNativeSliderView. - native_
spinner - A native spinner, animating or not — see
NativeSpinnerView. - native_
stepper - A native
Stepperatvalue, ranging over[min, max]— seeNativeStepperView. - native_
switch - A native
Switchat the app-ownedcheckedstate — seeNativeSwitchView. - native_
tab_ bar - A native bottom tab bar over
items, with the app-ownedselectedtab — seeNativeTabBarView. Aselectedid no item carries shows no selection; duplicate ids resolve to the first item carrying them; at most 16 items are shown (crate::controls::tab_bar::MAX_ITEMS). - show_
native_ alert - The app-facing native-presentation entry points over
crate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. Present a native alert and await its one outcome. - show_
native_ alert_ into - The app-facing native-presentation entry points over
crate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. Present a native alert and write its one outcome intosignalasSome(outcome)— the no-asyncform (module doc’s Controlled). - show_
native_ sheet - The app-facing native-presentation entry points over
crate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. Present a native sheet and await its one outcome. - show_
native_ sheet_ into - The app-facing native-presentation entry points over
crate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. The app-facing native-presentation entry points overcrate::present: for an alert and for a sheet, an awaitable form and an events-as-signals form — see thepresentsubmodule doc. Present a native sheet and write its one outcome intosignalasSome(outcome)— the no-asyncform, with exactlyshow_native_alert_into’s contract (module doc’s Controlled): synchronous refusals come back asErrand never touchsignal; a later platform error is logged, not written.