An experimental front end library which relies on rustwasm.
Very lightweight and does not support much of the HTML Standard. More work needs to be done to truly make this a viable option for creating client side front-ends with rustwasm.
A working example can be found here rust-fel-example
``` use crate::maincomponent::Main; use wasmbindgen::prelude::; extern crate rustfel;
// invoked when the wasm module is instantiated
pub fn main() -> Result<(), JsValue> { let main = Main::create(); let app = rust_fel::App::new(main); app.mount("root");
Ok(()) } ```
Arust_fel
struct component implements rust_fel::Component
``` use crate::action::Action; use crate::handle; use crate::mainchild::{ChildProps, MainChild}; use std::cell::RefCell; use std::rc::Rc; use wasmbindgen::JsCast;
pub struct MainState { count: i32, }
pub enum Actions { Counter(Action), }
pub struct Main {
child: handle::Handle
impl Main {
pub fn create() -> handle::Handle
impl rust_fel::Component for handle::Handle
fn addprops(&mut self, props: Self::Properties) { self.0.borrowmut().props = props; }
fn reducestate(&mut self, message: Actions) { match message { Actions::Counter(Action::Increment) => self.0.borrowmut().state.count += 100, Actions::Counter(Action::Decrement) => self.0.borrowmut().state.count -= 100, } rustfel::re_render(self.render(), Some(self.0.borrow().id.clone())); }
fn render(&self) -> rustfel::Element { let mut cloneforpropsclosure = self.clone(); let mut cloneforinc = self.clone(); let mut borrow = self.0.borrowmut(); let state = borrow.state.clone(); let propsclosure = Rc::new(RefCell::new(move || { cloneforpropsclosure.reducestate(Actions::Counter(Action::Decrement)) }));
let child_props = ChildProps {
counter_props: state.count.to_string(),
closure: Some(props_closure),
};
borrow.child.add_props(child_props);
let main_text = rust_fel::html(format!(
"<span | data-cy=main-text| >Main {}</span>",
state.count.to_string()
));
let inc_button_text = rust_fel::Element::new(
"TEXT_ELEMENT".to_owned(),
rust_fel::Props {
text: Some("Increment".to_owned()),
..Default::default()
},
);
let inc_button = rust_fel::Element::new(
"button".to_owned(),
rust_fel::Props {
on_click: Some(Box::new(move || {
clone_for_inc.reduce_state(Actions::Counter(Action::Increment))
})),
data_cy: Some("increment-main".to_owned()),
children: Some(vec![inc_button_text]),
..Default::default()
},
);
let main_el = rust_fel::Element::new(
"div".to_owned(),
rust_fel::Props {
class_name: Some("main-el".to_owned()),
children: Some(vec![main_text, inc_button, input_wrapper]),
..Default::default()
},
);
let child_wrapper = rust_fel::Element::new(
"div".to_owned(),
rust_fel::Props {
class_name: Some("child-wrapper".to_owned()),
children: Some(vec![borrow.child.render()]),
..Default::default()
},
);
rust_fel::Element::new(
"div".to_owned(),
rust_fel::Props {
id: Some(borrow.id.clone()),
class_name: Some("main".to_owned()),
children: Some(vec![main_el, child_wrapper]),
..Default::default()
},
)
}
} ```
A rust_fel
functional component with rust_fel::html.
``` pub fn themeswitcher(onclick: rustfel::ClosureProp, title: String) -> rustfel::Element { let text = rust_fel::html(format!( "", title ));
let themebutton = rustfel::Element::new( "button".toowned(), rustfel::Props { onclick: Some(onclick), typeattr: Some("button".toowned()), classname: Some("theme-switcher-button".toowned()), children: Some(vec![text]), data_cy: Some(title), ..Default::default() }, );
rustfel::Element::new( "li".toowned(), rustfel::Props { children: Some(vec![themebutton]), ..Default::default() }, ) } ```