freya/_docs/
components_and_props.rs

1//! # Components
2//!
3//! Freya apps are composed of components, these are structs that implement the [Render](freya_core::prelude::Render) trait.
4//!
5//! > You can learn more about how the UI is defined in the [UI](crate::_docs::ui) chapter.
6//!
7//! For convenience the root component can be a `Fn() -> Element` instead of a struct that implements `Render`.
8//!
9//! ### `fn() -> Element`
10//!
11//! ```rust
12//! # use freya::prelude::*;
13//! fn app() -> impl IntoElement {
14//!     "Hello, World!"
15//! }
16//! ```
17//!
18//!  ### `Render` trait
19//!
20//! ```rust
21//! # use freya::prelude::*;
22//! #[derive(PartialEq)]
23//! struct App;
24//!
25//! impl Render for App {
26//!     fn render(&self) -> impl IntoElement {
27//!         "Hello, World!"
28//!     }
29//! }
30//! ```
31//!
32//! To separate the UI of our app you may create more components.
33//!
34//! ```rust
35//! # use freya::prelude::*;
36//! # use std::borrow::Cow;
37//!
38//! // Reusable component that we might call as many times we want
39//! #[derive(PartialEq)]
40//! struct TextLabel(Cow<'static, str>);
41//! impl Render for TextLabel {
42//!     fn render(&self) -> impl IntoElement {
43//!         label().text(self.0.clone())
44//!     }
45//! }
46//!
47//! fn app() -> impl IntoElement {
48//!     rect()
49//!         .child(TextLabel("Number 1".into()))
50//!         .child("Number 2")
51//!         .child(TextLabel("Number 3".into()))
52//! }
53//! ```
54//!
55//! ## Renders
56//!
57//! "Components renders" are simply when the component's `render` function runs, this can happen in multiple scanarios:
58//!
59//! 1. The component just got instanciated for the first time (also called mounted in other UI libraries)
60//! 2. A state that this component is reading (thus subscribed to), got written
61//! 3. The component data changed (this is why `PartialEq` is required)
62//!
63//! > **Note:** The naming of `render` might give you the impression that it means the window canvas will effectively rerender again, it has nothing to do with it, in fact, a component might render (run its function) a thousand times but generate the exact same UI, if that was the case Freya would not render the canvas again.
64//!
65//! Consider this simple component:
66//!
67//! ```rust
68//! # use freya::prelude::*;
69//! #[derive(PartialEq)]
70//! struct CoolComp;
71//! impl Render for CoolComp {
72//!     // One run of this function is the same saying as one render of this component
73//!     fn render(&self) -> impl IntoElement {
74//!         let mut count = use_state(|| 0);
75//!
76//!         label()
77//!             .on_mouse_up(move |_| *count.write() += 1)
78//!             .text(format!("Increase {}", count.read()))
79//!     }
80//! }
81//! ```