ParentView

Trait ParentView 

Source
pub trait ParentView: HasViewId + Sized {
    // Provided methods
    fn scope(&self) -> Option<Scope> { ... }
    fn child(self, child: impl IntoView + 'static) -> Self { ... }
    fn children(self, children: impl IntoViewIter + 'static) -> Self { ... }
    fn derived_children<CF, C>(self, children_fn: CF) -> Self
       where CF: Fn() -> C + 'static,
             C: IntoViewIter + 'static { ... }
    fn stateful_child<S, SF, CF, V>(self, state_fn: SF, child_fn: CF) -> Self
       where SF: Fn() -> S + 'static,
             CF: Fn(S) -> V + 'static,
             V: IntoView + 'static,
             S: 'static { ... }
    fn keyed_children<IF, I, T, K, KF, VF, V>(
        self,
        items_fn: IF,
        key_fn: KF,
        view_fn: VF,
    ) -> Self
       where IF: Fn() -> I + 'static,
             I: IntoIterator<Item = T>,
             KF: Fn(&T) -> K + 'static,
             K: Eq + Hash + 'static,
             VF: Fn(T) -> V + 'static,
             V: IntoView + 'static,
             T: 'static { ... }
    fn derived_child<CF, V>(self, child_fn: CF) -> Self
       where CF: Fn() -> V + 'static,
             V: IntoView + 'static { ... }
}
Expand description

A trait for views that can accept children.

This provides a builder-pattern API for adding children to views, similar to GPUI’s ParentElement trait. Both methods append to existing children rather than replacing them.

Views opt-in to this trait by implementing it. Not all views should have children (e.g., Label, TextInput), so there is no blanket implementation.

§Example

Stack::empty()
    .child(text("Header"))
    .children((0..5).map(|i| text(format!("Item {i}"))))
    .child(text("Footer"))

Provided Methods§

Source

fn scope(&self) -> Option<Scope>

Returns the scope associated with this view, if any.

Views that need to provide context to children should:

  1. Create a scope in their constructor: Scope::new() or Scope::current().create_child()
  2. Provide context in that scope: scope.provide_context(...)
  3. Override this method to return that scope

When this returns Some(scope), the scope is stored on the view (via set_scope()) so that descendants can find it via ViewId::find_scope().

Source

fn child(self, child: impl IntoView + 'static) -> Self

Adds a single child to this view.

The child is constructed lazily during the update cycle. The scope is resolved at build time by walking up the view hierarchy to find the nearest ancestor with a scope (via ViewId::find_scope()).

Source

fn children(self, children: impl IntoViewIter + 'static) -> Self

Adds multiple children to this view.

Accepts arrays, tuples, vectors, and iterators of views. The children are constructed lazily during the update cycle. The scope is resolved at build time by walking up the view hierarchy to find the nearest ancestor with a scope (via ViewId::find_scope()).

Source

fn derived_children<CF, C>(self, children_fn: CF) -> Self
where CF: Fn() -> C + 'static, C: IntoViewIter + 'static,

Adds reactive children that update when signals change.

The children function is called initially and re-called whenever its reactive dependencies change, replacing all children.

The scope is resolved at build time by walking up the view hierarchy to find the nearest ancestor with a scope (via ViewId::find_scope()).

§Example
use floem::prelude::*;
use floem::views::Stem;

let items = RwSignal::new(vec!["a", "b", "c"]);

Stem::new().derived_children(move || {
    items.get().into_iter().map(|item| text(item))
});
Source

fn stateful_child<S, SF, CF, V>(self, state_fn: SF, child_fn: CF) -> Self
where SF: Fn() -> S + 'static, CF: Fn(S) -> V + 'static, V: IntoView + 'static, S: 'static,

Adds a single reactive child with explicit state tracking.

Takes two closures: one that tracks reactive dependencies and returns state, and another that builds a view from that state. When the state changes, only the managed child is replaced while preserving any other siblings. This allows mixing static children with a reactive child.

For a simpler API where a single closure both tracks deps and returns a view, use derived_child instead.

The scope is resolved at build time by walking up the view hierarchy to find the nearest ancestor with a scope (via ViewId::find_scope()).

§Example
use floem::prelude::*;
use floem::views::Stem;

#[derive(Clone)]
enum ViewType { One, Two }

let view_type = RwSignal::new(ViewType::One);

Stem::new().stateful_child(
    move || view_type.get(),
    |value| match value {
        ViewType::One => text("One"),
        ViewType::Two => text("Two"),
    }
);
Source

fn keyed_children<IF, I, T, K, KF, VF, V>( self, items_fn: IF, key_fn: KF, view_fn: VF, ) -> Self
where IF: Fn() -> I + 'static, I: IntoIterator<Item = T>, KF: Fn(&T) -> K + 'static, K: Eq + Hash + 'static, VF: Fn(T) -> V + 'static, V: IntoView + 'static, T: 'static,

Adds keyed reactive children that efficiently update when signals change.

Unlike derived_children which recreates all children on every update, keyed_children uses keys to identify items and only creates/removes children that actually changed. Views for unchanged items are reused.

The scope is resolved at build time by walking up the view hierarchy to find the nearest ancestor with a scope (via ViewId::find_scope()).

§Arguments
  • items_fn: A function that returns an iterator of items
  • key_fn: A function that extracts a unique key from each item
  • view_fn: A function that creates a view from an item
§Example
use floem::prelude::*;
use floem::views::Stem;

let items = RwSignal::new(vec!["a", "b", "c"]);

Stem::new().keyed_children(
    move || items.get(),
    |item| *item,  // key by the item itself
    |item| text(item),
);
Source

fn derived_child<CF, V>(self, child_fn: CF) -> Self
where CF: Fn() -> V + 'static, V: IntoView + 'static,

Adds a single reactive child that updates when signals change.

The closure both tracks reactive dependencies and returns a view. When any tracked dependency changes, only the managed child is replaced while preserving any other siblings. This allows mixing static children with a reactive child.

This is consistent with derived_children which also takes a single closure. For explicit state tracking with separate closures, use stateful_child instead.

The scope is resolved at build time by walking up the view hierarchy to find the nearest ancestor with a scope (via ViewId::find_scope()).

§Example
use floem::prelude::*;
use floem::views::Stem;

#[derive(Clone)]
enum ViewType { One, Two }

let view_type = RwSignal::new(ViewType::One);

Stem::new().derived_child(move || {
    match view_type.get() {  // tracking happens here
        ViewType::One => text("One").into_any(),
        ViewType::Two => text("Two").into_any(),
    }
});

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§