Switcher
Switcher — a container that shows exactly one child page at a time.
Public functions
Switcher
| Returns | Function |
|---|---|
| Constructors | |
Self | new(selected: Signal<usize>) |
| Builder methods | |
Self | capture_child_ids_into(out: Rc<RefCell<Vec<WidgetId>>>) |
Self | child(widget: impl teksilo_core::IntoTeksiChild) |
Self | child_opt(widget: Option<impl teksilo_core::IntoTeksiChild>) |
Self | children(iter: impl IntoIterator<Item = impl teksilo_core::IntoTeksiChild>) |
Detailed description
Switcher is the fundamental tab/wizard/step primitive: it owns N child
pages and exposes only the one whose index matches the Signal<usize> it
was constructed with. Switching is a signal write — the framework responds
with a relayout that shows the new page and dormantizes all others (excluded
from focus traversal, accessibility tree, hit-test, and paint).
Lazy mount. Pages added via child /
children / child
stay unconstructed until their index is selected for the first time. Once
mounted, the page's subtree persists for the Switcher's lifetime — switching
away then back finds it in the exact state the user left it (focus, scroll
offsets, text-input contents, signal subscriptions). Pages added via
child are pre-mounted by the caller and treated
eagerly.
The Switcher itself reports the maximum natural size across every
currently-mounted page and stretches each placed page to its own bounds —
all pages share the same slot, so the container size never jumps on a switch.
#![allow(unused)] fn main() { use teksilo_widgets::primitives::{Switcher, TextWidget}; use teksilo_core::signal::Signal; use teksilo_i18n::lit; let page = Signal::new(0_usize); let _w = Switcher::new(page.clone()) .child(TextWidget::new(lit!("Step 1"))) // built at startup (index 0 is default) .child(TextWidget::new(lit!("Step 2"))) // built on first page.set(1) .child(TextWidget::new(lit!("Step 3"))); // built on first page.set(2) }
API reference
📖 Full rustdoc API for this module
pub struct Switcher
Import: use teksilo::widgets::Switcher;
A container that shows exactly one child at a time, driven by a
Signal<usize> index.
Lazy mount. A page added via Self::child / Self::child
/ Self::children stays unconstructed until its index is first
selected. Once mounted, the page's subtree persists for the
Switcher's lifetime — switching away then back finds it in the
state the user left it (focus, scroll, text-input contents, …).
Pages added via Self::child are pre-mounted by the caller
and treated eagerly: no lazy benefit, no semantic change.
The Switcher itself reports the maximum natural size across every
currently-mounted page and stretches each placed child to its own
bounds (top-leading, RTL-aware). Hidden pages keep their subtree
laid out but invisible via per-page visible_when bindings.
#![allow(unused)] fn main() { use teksilo_widgets::primitives::{Switcher, TextWidget}; use teksilo_core::signal::Signal; use teksilo_i18n::lit; let page = Signal::new(0_usize); let _w = Switcher::new(page.clone()) .child(TextWidget::new(lit!("Page 0"))) // built at startup .child(TextWidget::new(lit!("Page 1"))) // built when page.set(1) .child(TextWidget::new(lit!("Page 2"))); // built when page.set(2) }
#![allow(unused)] fn main() { pub struct Switcher { /* fields */ } }
Methods
pub fn new(selected: Signal<usize>) -> Self
Create a Switcher driven by selected. The initially selected index
is selected.get() at build time; page 0 is mounted immediately if that
is the starting value (the most common case).
pub fn capture_child_ids_into(mut self, out: Rc<RefCell<Vec<WidgetId>>>) -> Self (default: None)
Capture each mounted page's WidgetId into an externally owned
buffer during build(). Use when the caller needs to reference
pages after they're added to the arena — e.g. for accessibility
relations like Tab → TabPanel.
The buffer reflects the currently-mounted set, not every
declared page. With lazy mount, a page added via child(...)
only appears in the buffer once it has been selected for the
first time. Callers that need every id up front should pass
pre-mounted ids via Self::child instead — those are
eagerly recorded.
pub fn child(mut self, widget: impl teksilo_core::IntoTeksiChild) -> Self
Add a child page. An impl Widget stays Boxed until its index is
selected for the first time, then is mounted into the arena
and kept alive across selection changes. A WidgetId (an
already-mounted page) is pre-mounted immediately instead, built
eagerly regardless of the selected index — see Slot::PreMounted.
pub fn child_opt(self, widget: Option<impl teksilo_core::IntoTeksiChild>) -> Self
Attach widget when it is Some, and do nothing when it is None.
The conditional-child form. teksu!'s if without an else lowers to
this, and it is what cond.then(|| w) is for in a builder chain. None
adds no arena node, so nothing is laid out, painted, or published to the
accessibility tree, and a stack applies no spacing around it.
pub fn children( self, iter: impl IntoIterator<Item = impl teksilo_core::IntoTeksiChild>, ) -> Self
Add multiple child pages from an iterator (lazy, same as
Self::child).