pub fn IndexedStack<State: 'static, M>(
index: Option<usize>,
children: impl ViewSeq<State, M>,
) -> IndexedStackView<State>Expand description
Keep every child of children mounted and show only the one at index.
children is any ViewSeq: a Vec/array of views, a tuple of mixed view
types (positional, up to 12 and nestable), an Option (None drops the
slot), or views(iter) for an iterator. Every element is erased once, here.
An index that is None or out of range selects nothing: the stack paints
nothing, routes no input and exposes no accessibility node, while every child
stays mounted.
§Reach follows the selection (R23)
Only the selected child is reachable. Input events go to it alone, the
accessibility tree contains it alone, and a navigator anywhere inside an
unselected child reports
back_interest == false, the
same rule that silences a navigator on a covered navigator page. The stack
does this by installing one page-reach cell per child, true only for the
selected child, and only while the stack itself is reachable. A stack built
on a navigator page that later gets covered therefore leaves every tab
navigator unreachable, at any nesting depth. Cells are rewritten on every
rebuild, before the children are reconciled, so a nested navigator always
reads the value for the selection it is being rebuilt under.
Broadcast events (housekeeping, overlay and drop-end notifications) are not user input and go to every child, as they do for the navigator’s pages: a navigator in an unselected tab may hold a queued pop result that must still flush on the frame that produced it.
§Page-switch contract
When the selected index changes, the outgoing child is handled the way a
navigator handles a covered page, in this order: an in-flight pointer
capture receives a synthetic Cancel (so it never fires on a later Up),
its focus flag is cleared, and, if that child held focus on the live focus
chain, the next paint publishes a cleared IME surface so the platform
keyboard hides. A child that never held focus publishes nothing, so a text
field elsewhere in the tree keeps its session. The incoming child is not
focused automatically.
§Layout
Every child is laid out under the stack’s loosened constraints at the stack
origin, and the stack takes the size of its largest child, clamped to its
constraints. This matches Flutter’s IndexedStack: the stack does not
change size when the selection changes.
use frust_widgets::{IndexedStack, IndexedStackView, Stack, indexed_stack, text};
// Mixed child types: a tuple, no `any(..)` needed.
let tabs = IndexedStack(Some(1), (text("home"), Stack((text("feed"), text("badge")))));
// The fluent form.
let fluent = indexed_stack(Some(0)).child(text("home")).child(text("search"));