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;