Skip to main content

ferroui_view/
lib.rs

1//! ferroui-view
2//!
3//! A declarative way to write FerroUI user interfaces in Rust, without XAML:
4//! elements built with chained setters (`button().content("Add").on_click(..)`)
5//! or with the [`rsx!`] macro, state held in signals that the properties of
6//! controls follow, and children that follow state.
7//!
8//! The pieces (`docs/declarative-ui.md` has the design):
9//!
10//! - [`Element`]: a description of controls, their property values,
11//!   handlers and children. It is data, compared by value, so that a later
12//!   reconciler can compare two trees and patch controls; mounting makes the
13//!   controls ([`Element::mount`]).
14//! - Builders: a function per control class (`button()`, `stack_panel()`)
15//!   and a trait per class with a setter per property and a handler per routed
16//!   event, generated from the sources (`scripts/generate_view_builders.py`).
17//! - Reactivity: [`Signal`], [`Memo`], [`effect`], owned by an [`Owner`].
18//!   A setter given a signal or a closure makes the property follow it.
19//! - Children that follow state: [`for_each`] (keyed), [`show`], [`dynamic`].
20//! - With the feature `desktop`: [`launch`] runs an application whose main
21//!   window is an element.
22//!
23//! ```ignore
24//! use ferroui_view::prelude::*;
25//!
26//! fn counter() -> Element {
27//!     let count = signal(0);
28//!     stack_panel()
29//!         .spacing(8.0)
30//!         .child(text_block().text(move || format!("Count: {}", count.get())))
31//!         .child(button().content("Increment").on_click(move |_| count.update(|c| *c += 1)))
32//!         .into()
33//! }
34//! ```
35
36// The expansions of the macros name the crate; its own tests use them too.
37extern crate self as ferroui_view;
38
39pub mod builder;
40mod control_flow;
41mod conversions;
42pub mod element;
43mod extras;
44pub mod reactive;
45
46#[cfg(feature = "desktop")]
47mod app;
48
49/// The generated builders (see the module documentation).
50pub mod generated {
51    pub mod builders;
52}
53
54pub use builder::{Bind, Builder, El, ElementBuilder, FromValue, IntoProp, IntoValue, TypedProperty, ViewClass};
55pub use control_flow::{dynamic, for_each, show, show_else, NodeRef};
56pub use element::{Element, IntoChild, IntoChildren, IntoElement, Key};
57pub use extras::GridDefinitions;
58pub use reactive::{batch, effect, memo, on_cleanup, signal, untrack, Memo, Owner, Signal, TwoWay};
59
60#[cfg(feature = "desktop")]
61pub use app::{launch, launch_themed, launch_with, mount_window, open_window};
62
63pub use ferroui_view_macros::{component, rsx};
64
65/// Everything an application written with the builders or the macro uses.
66pub mod prelude {
67    pub use crate::generated::builders::*;
68    pub use crate::{
69        batch, component, dynamic, effect, for_each, memo, on_cleanup, rsx, show, show_else, signal, untrack, Bind, El,
70        Element, ElementBuilder, GridDefinitions, IntoChild, IntoChildren, IntoElement, Key, Memo, NodeRef, Owner,
71        Signal, TwoWay,
72    };
73    #[cfg(feature = "desktop")]
74    pub use crate::{launch, launch_themed, launch_with, mount_window, open_window};
75}
76
77#[cfg(test)]
78mod tests;