rust_fel/
lib.rs

1//! A Rust Front-End Library.  
2//!
3//! Experimental.  
4//!
5//! Relies on [rustwasm](https://github.com/rustwasm).  
6//!
7//! Very lightweight and does not support much of the [HTML Standard](https://html.spec.whatwg.org/). More work needs to be done to truly make this a viable option
8//! for creating client side front-ends with [rustwasm](https://github.com/rustwasm).  
9//! ### Features
10//! * State Management
11//! * [JSX](https://github.com/facebook/jsx) -like syntax
12//! * [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) construction from a Virtual [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction).
13//!
14//! # Use
15//! ```ignore
16//! use crate::main_component::Main;
17//! use wasm_bindgen::prelude::*;
18//! extern crate rust_fel;
19//!
20//! // invoked when the wasm module is instantiated
21//! #[wasm_bindgen(start)]
22//! pub fn main() -> Result<(), JsValue> {
23//!     let main = Main::create();
24//!     let app = rust_fel::App::new(main);
25//!     app.mount("root");
26//!
27//!     Ok(())
28//!
29//! ```
30//! # Examples
31//! A ```rust_fel``` [struct](https://doc.rust-lang.org/std/keyword.struct.html) component implements [rust_fel::Component](../rust_fel/trait.Component.html)
32//!```ignore
33//!use crate::action::Action;
34//!use crate::handle;
35//!use crate::main_child::{ChildProps, MainChild};
36//!use std::cell::RefCell;
37//!use std::rc::Rc;
38//!
39//!#[derive(Debug, Default, Clone)]
40//!pub struct MainState {
41//!    count: i32,
42//!}
43//!
44//!pub enum Actions {
45//!    Counter(Action),
46//!}
47//!
48//!#[derive(Debug, Default, Clone)]
49//!pub struct Main {
50//!    child: handle::Handle<MainChild>,
51//!    id: String,
52//!    state: MainState,
53//!    props: String,
54//!}
55//!
56//!impl Main {
57//!    pub fn create() -> handle::Handle<Self> {
58//!        let main = Main {
59//!            id: "main".to_owned(),
60//!            state: MainState {
61//!                count: 0,
62//!            },
63//!            child: MainChild::create(),
64//!            ..Default::default()
65//!        };
66//!        handle::Handle(Rc::new(RefCell::new(main)))
67//!    }
68//!}
69//!
70//!impl rust_fel::Component for handle::Handle<Main> {
71//!    type Properties = String;
72//!    type Message = Actions;
73//!    type State = MainState;
74//!
75//!    fn add_props(&mut self, props: Self::Properties) {
76//!        self.0.borrow_mut().props = props;
77//!    }
78//!
79//!    fn reduce_state(&mut self, message: Actions) {
80//!        match message {
81//!            Actions::Counter(Action::Increment) => self.0.borrow_mut().state.count += 100,
82//!            Actions::Counter(Action::Decrement) => self.0.borrow_mut().state.count -= 100,
83//!        }
84//!
85//!        rust_fel::re_render(self.render(), Some(self.0.borrow().id.clone()));
86//!    }
87//!
88//!    fn render(&self) -> rust_fel::Element {
89//!        let mut clone_for_props_closure = self.clone();
90//!        let mut clone_for_inc = self.clone();
91//!        let mut borrow = self.0.borrow_mut();
92//!        let state = borrow.state.clone();
93//!        let props_closure = Rc::new(RefCell::new(move || {
94//!            clone_for_props_closure.reduce_state(Actions::Counter(Action::Decrement))
95//!        }));
96//!
97//!        let child_props = ChildProps {
98//!            counter_props: state.count.to_string(),
99//!            closure: Some(props_closure),
100//!        };
101//!
102//!        borrow.child.add_props(child_props);
103//!
104//!        let main_text = rust_fel::html(format!(
105//!            "<span | data-cy=main-text| >Main {}</span>",
106//!            state.count.to_string()
107//!        ));
108//!
109//!        let inc_button = rust_fel::Element::new(
110//!            "button".to_owned(),
111//!            rust_fel::Props {
112//!                text: Some("Increment".to_owned()),
113//!                on_click: Some(Box::new(move || {
114//!                    clone_for_inc.reduce_state(Actions::Counter(Action::Increment))
115//!                })),
116//!                data_cy: Some("increment-main".to_owned()),
117//!                children: Some(vec![inc_button_text]),
118//!                ..Default::default()
119//!            },
120//!        );
121//!
122//!        let main_el = rust_fel::Element::new(
123//!            "div".to_owned(),
124//!            rust_fel::Props {
125//!                class_name: Some("main-el".to_owned()),
126//!                children: Some(vec![main_text, inc_button, input_wrapper]),
127//!                ..Default::default()
128//!            },
129//!        );
130//!
131//!        let child_wrapper = rust_fel::Element::new(
132//!            "div".to_owned(),
133//!            rust_fel::Props {
134//!                class_name: Some("child-wrapper".to_owned()),
135//!                children: Some(vec![borrow.child.render()]),
136//!                ..Default::default()
137//!            },
138//!        );
139//!
140//!        rust_fel::Element::new(
141//!            "div".to_owned(),
142//!            rust_fel::Props {
143//!                id: Some(borrow.id.clone()),
144//!                class_name: Some("main".to_owned()),
145//!                children: Some(vec![main_el, child_wrapper]),
146//!                ..Default::default()
147//!            },
148//!        )
149//!    }
150//!}
151//!
152//!```
153//!  A ```rust_fel``` functional component with [rust_fel::html](../rust_fel/rsx/fn.html.html)
154//!```ignore
155//!pub fn theme_switcher(on_click: rust_fel::ClosureProp, title: String) -> rust_fel::Element {
156//!    let text = rust_fel::html(format!(
157//!        "<span |class=theme-switcher-text|>{}</span>",
158//!        title
159//!    ));
160//!
161//!    let theme_button = rust_fel::Element::new(
162//!        "button".to_owned(),
163//!        rust_fel::Props {
164//!            on_click: Some(on_click),
165//!            type_attr: Some("button".to_owned()),
166//!            class_name: Some("theme-switcher-button".to_owned()),
167//!            children: Some(vec![text]),
168//!            data_cy: Some(title),
169//!            ..Default::default()
170//!        },
171//!    );
172//!
173//!    rust_fel::Element::new(
174//!        "li".to_owned(),
175//!        rust_fel::Props {
176//!            children: Some(vec![theme_button]),
177//!            ..Default::default()
178//!        },
179//!    )
180//!}
181//!```
182
183#![doc(html_root_url = "https://docs.rs/rust-fel/0.1.2")] // Must be kept in sync with Cargo.toml
184#![allow(clippy::single_match)]
185/// Module containing the [rust_fel::App](../rust_fel/struct.App.html) [struct](https://doc.rust-lang.org/std/keyword.struct.html) which mounts your ```App``` to the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction).
186pub mod app;
187/// Module containing the [rust_fel::Component](../rust_fel/trait.Component.html) trait. Necessary for state management at the [struct](https://doc.rust-lang.org/std/keyword.struct.html) level.
188pub mod component;
189/// Module containing the [rust_fel::Element](../rust_fel/struct.Element.html) [struct](https://doc.rust-lang.org/std/keyword.struct.html) which acts as a Virtual [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction).
190pub mod element;
191/// Module containing the [rust_fel::Props](../rust_fel/struct.Props.html) [struct](https://doc.rust-lang.org/std/keyword.struct.html) which allows an [rust_fel::Element](../rust_fel/struct.Element.html) to have ```properties``` and ```children```.
192pub mod props;
193/// Module containing the functions to ```render``` and [rust_fel::re_render](../rust_fel/fn.re_render.html) the [rust_fel::App](../rust_fel/struct.App.html).
194pub mod render;
195/// Module containing all the functions needed for the [rust_fel::html](../rust_fel/fn.html.html) function to create [rust_fel::Element](../rust_fel/struct.Element.html) from strings of [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML).
196pub mod rsx;
197
198#[doc(inline)]
199pub use crate::app::App;
200#[doc(inline)]
201pub use crate::component::Component;
202#[doc(inline)]
203pub use crate::element::Element;
204#[doc(inline)]
205pub use crate::props::{ClosureProp, Props};
206#[doc(inline)]
207pub use crate::render::re_render;
208#[doc(inline)]
209pub use crate::rsx::html;