Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Switcher

Switcher — a container that shows exactly one child page at a time.

Public functions

Switcher

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).