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;