1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
//! # UI
//!
//! Freya uses a [declarative](https://en.wikipedia.org/wiki/Declarative_programming) model for the UI, in the form a semi-markup language using the `rsx!()` macro from Dioxus, it integrates very well with normal Rust syntax too.
//!
//! For example, this is how a simple component would look like in Freya:
//!
//! ```rust, no_run
//! # use freya::prelude::*;
//! fn app() -> Element {
//! rsx!(
//! rect {
//! background: "red",
//! width: "100%",
//! onclick: |_| println!("Clicked!"),
//! label {
//! "Hello, World!"
//! }
//! }
//! )
//! }
//! ```
//!
//! Notice that the `app` component is returning an [`Element`](dioxus_core::Element) created by the [`rsx!()`](dioxus_core_macro::rsx!()) macro. So, in other words, the [`Element`](dioxus_core::Element) contains the UI of that component.
//! Every time the component function reruns the [`rsx!()`](dioxus_core_macro::rsx!()) will be called again and thus generate a new UI.
//!
//! ### [`rsx!()`](dioxus_core_macro::rsx!())
//!
//! This macro is not a standalone language, it let define the structure, design and dynamism of the UI. It also integrates very well with Rust code.
//!
//! The structure for RSX looks like this:
//!
//! ```rust, no_run
//! # use freya::prelude::*;
//! # { rsx!(
//! // Element, always in lower case
//! rect {
//! // Attribute for the element `rect`
//! background: "red",
//! // Another attribute for the element `rect`
//! width: "100%",
//! // Event handler for the element `rect`, can be a function or a closure
//! onclick: |_| println!("Clicked!"),
//! // Element child of `rect`
//! label {
//! // Text Element for the element `label`
//! "Hello, World!"
//! }
//! // Component child of `rect`, always in PascalCase
//! CoolComp {
//! // Prop for the component `CoolComp`
//! prop: 123
//! }
//! }
//! # )};
//!
//! # #[component]
//! # fn CoolComp(prop: i32) -> Element { Ok(VNode::placeholder()) }
//! ```
//!
//! You can reference variables inside the RSX as well:
//!
//! ```rust, no_run
//! # use freya::prelude::*;
//! let onclick = |_| {
//! println!("Clicked");
//! };
//!
//! let width = "100%";
//! let name = "World";
//!
//! # {
//! rsx!(
//! rect {
//! background: "red",
//! width,
//! onclick,
//! label {
//! "Hello, {name}!"
//! }
//! label {
//! "{1 + 1} is 2"
//! }
//! }
//! )
//! # };
//! ```
//!
//! Or just use if, for-loops, etc... inside of the RSX:
//!
//! ```rust, no_run
//! # use freya::prelude::*;
//! let show_text = false;
//!
//! # {
//! rsx!(
//! rect {
//! for i in 0..5 {
//! label {
//! // Looped elements must have an unique ID specified through
//! // the `key` attribute so Dioxus is able to properly diff them
//! // between multiple reruns
//! key: "{i}",
//! "Value -> {i}"
//! }
//! }
//! // When this condition is not met the inner rsx will simply not be rendered
//! if show_text {
//! label {
//! "Hello, World!"
//! }
//! }
//! }
//! )
//! # };
//! ```