Skip to main content

Elements

Struct Elements 

Source
pub struct Elements { /* private fields */ }
Expand description

A list of component descriptions for declarative tree building.

Elements is what view functions return and what the framework reconciles against the existing component tree. Build one with the element! macro or the imperative API:

// With the element! macro (preferred):
fn my_view(state: &MyState) -> Elements {
    element! {
        "Hello"
        #(if state.loading {
            Spinner(key: "spinner", label: "Loading...")
        })
    }
}

// Imperative API:
fn my_view(state: &MyState) -> Elements {
    let mut els = Elements::new();
    els.add(TextBlock::new().unstyled("Hello"));
    if state.loading {
        els.add(Spinner::new("Loading...")).key("spinner");
    }
    els
}

Implementations§

Source§

impl Elements

Source

pub fn new() -> Self

Create an empty element list.

Examples found in repository?
examples/lifecycle.rs (line 113)
112fn task_view(state: &AppState) -> Elements {
113    let mut els = Elements::new();
114
115    els.add(
116        TextBlock::new().line(
117            format!("Tasks ({})", state.tasks.len()),
118            Style::default()
119                .fg(Color::White)
120                .add_modifier(Modifier::BOLD),
121        ),
122    );
123
124    for task in &state.tasks {
125        els.add(StatusLog::new(task)).key(task.clone());
126    }
127
128    if state.processing {
129        els.add(Spinner::new("Processing...")).key("spinner");
130    }
131
132    els.add(TextBlock::new().line("---", Style::default().fg(Color::DarkGray)));
133
134    els
135}
More examples
Hide additional examples
examples/declarative.rs (line 42)
41fn chat_view(state: &AppState) -> Elements {
42    let mut els = Elements::new();
43
44    // Render all messages with stable keys
45    for (i, msg) in state.messages.iter().enumerate() {
46        els.add(Markdown::new(msg)).key(format!("msg-{i}"));
47    }
48
49    // Show thinking spinner if active (auto-animates via tick registration)
50    if state.thinking {
51        els.add(Spinner::new("Thinking...")).key("thinking");
52    }
53
54    // Show tool call spinner if active (auto-animates via tick registration)
55    if let Some(ref tool) = state.tool_running {
56        els.add(Spinner::new(format!("Running {}...", tool)))
57            .key("tool");
58    }
59
60    // Separator at the bottom
61    if !state.messages.is_empty() || state.thinking || state.tool_running.is_some() {
62        els.add(TextBlock::new().line("---", Style::default().fg(Color::DarkGray)));
63    }
64
65    els
66}
examples/chat.rs (line 226)
225fn chat_view(state: &AppState) -> Elements {
226    let mut els = Elements::new();
227
228    for msg in &state.messages {
229        let key = format!("msg-{}", msg.id);
230        match &msg.kind {
231            MessageKind::User(text) => {
232                els.add(
233                    TextBlock::new().line(
234                        format!("> {}", text),
235                        Style::default()
236                            .fg(Color::Cyan)
237                            .add_modifier(Modifier::BOLD),
238                    ),
239                )
240                .key(key);
241            }
242            MessageKind::Assistant { content, done } => {
243                if *done {
244                    els.add(Markdown::new(content)).key(key);
245                } else if content.is_empty() {
246                    els.add(StreamingDots).key(key);
247                } else {
248                    // Show content with a blinking cursor
249                    els.add(Markdown::new(format!("{}▌", content))).key(key);
250                }
251            }
252        }
253    }
254
255    // Separator
256    els.add(TextBlock::new());
257
258    // Input box
259    els.add(InputBox {
260        text: state.input.clone(),
261        cursor: state.cursor,
262        prompt: "You".into(),
263    })
264    .key("input");
265
266    els
267}
Source

pub fn add<C: Component>(&mut self, component: C) -> ElementHandle<'_>

Add a component to the list.

Returns an ElementHandle that can be used to set a key for stable identity across rebuilds.

Examples found in repository?
examples/lifecycle.rs (lines 115-122)
112fn task_view(state: &AppState) -> Elements {
113    let mut els = Elements::new();
114
115    els.add(
116        TextBlock::new().line(
117            format!("Tasks ({})", state.tasks.len()),
118            Style::default()
119                .fg(Color::White)
120                .add_modifier(Modifier::BOLD),
121        ),
122    );
123
124    for task in &state.tasks {
125        els.add(StatusLog::new(task)).key(task.clone());
126    }
127
128    if state.processing {
129        els.add(Spinner::new("Processing...")).key("spinner");
130    }
131
132    els.add(TextBlock::new().line("---", Style::default().fg(Color::DarkGray)));
133
134    els
135}
More examples
Hide additional examples
examples/declarative.rs (line 46)
41fn chat_view(state: &AppState) -> Elements {
42    let mut els = Elements::new();
43
44    // Render all messages with stable keys
45    for (i, msg) in state.messages.iter().enumerate() {
46        els.add(Markdown::new(msg)).key(format!("msg-{i}"));
47    }
48
49    // Show thinking spinner if active (auto-animates via tick registration)
50    if state.thinking {
51        els.add(Spinner::new("Thinking...")).key("thinking");
52    }
53
54    // Show tool call spinner if active (auto-animates via tick registration)
55    if let Some(ref tool) = state.tool_running {
56        els.add(Spinner::new(format!("Running {}...", tool)))
57            .key("tool");
58    }
59
60    // Separator at the bottom
61    if !state.messages.is_empty() || state.thinking || state.tool_running.is_some() {
62        els.add(TextBlock::new().line("---", Style::default().fg(Color::DarkGray)));
63    }
64
65    els
66}
examples/chat.rs (lines 232-239)
225fn chat_view(state: &AppState) -> Elements {
226    let mut els = Elements::new();
227
228    for msg in &state.messages {
229        let key = format!("msg-{}", msg.id);
230        match &msg.kind {
231            MessageKind::User(text) => {
232                els.add(
233                    TextBlock::new().line(
234                        format!("> {}", text),
235                        Style::default()
236                            .fg(Color::Cyan)
237                            .add_modifier(Modifier::BOLD),
238                    ),
239                )
240                .key(key);
241            }
242            MessageKind::Assistant { content, done } => {
243                if *done {
244                    els.add(Markdown::new(content)).key(key);
245                } else if content.is_empty() {
246                    els.add(StreamingDots).key(key);
247                } else {
248                    // Show content with a blinking cursor
249                    els.add(Markdown::new(format!("{}▌", content))).key(key);
250                }
251            }
252        }
253    }
254
255    // Separator
256    els.add(TextBlock::new());
257
258    // Input box
259    els.add(InputBox {
260        text: state.input.clone(),
261        cursor: state.cursor,
262        prompt: "You".into(),
263    })
264    .key("input");
265
266    els
267}
Source

pub fn add_with_children<C: Component>( &mut self, component: C, children: Elements, ) -> ElementHandle<'_>

Add a component with nested children.

The component is created first, then children are built as its descendants. The component’s children() method receives these as the slot parameter.

Source

pub fn group(&mut self, children: Elements) -> ElementHandle<'_>

Add a VStack wrapper around the given children.

Equivalent to add_with_children(VStack, children).

Source

pub fn hstack(&mut self, children: Elements) -> ElementHandle<'_>

Add an HStack wrapper around the given children.

Children default to WidthConstraint::Fill. Use .width(WidthConstraint::Fixed(n)) for fixed-width children.

Source

pub fn splice(&mut self, other: Elements)

Splice another Elements list into this one.

All entries from other are appended to this list. This is used by the element! macro’s #(expr) syntax to interpolate pre-built Elements inline.

Trait Implementations§

Source§

impl<C: Component> AddTo<Elements> for ComponentWithSlot<C>

Source§

type Handle<'a> = ElementHandle<'a>

Handle returned after adding. Supports .key() / .width() chaining.
Source§

fn add_to(self, els: &mut Elements) -> ElementHandle<'_>

Add this value to the collector, returning a handle for chaining .key() and .width().
Source§

impl Default for Elements

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl SpliceInto<Elements> for Elements

Source§

fn splice_into(self, collector: &mut Elements)

Splice all entries from this value into the collector.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<C> AddTo<Elements> for C
where C: Component,

Source§

type Handle<'a> = ElementHandle<'a>

Handle returned after adding. Supports .key() / .width() chaining.
Source§

fn add_to(self, els: &mut Elements) -> ElementHandle<'_>

Add this value to the collector, returning a handle for chaining .key() and .width().
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.