pub mod yo_web_framework_example; #[xtask_wasm::run_example] fn run_app() { use yo_web_framework_example::prelude::*; log("Hello World!"); // Pure component pub struct MyComponentBuilder { value: Option, } impl MyComponentBuilder { pub fn set_attr_value(&mut self, value: T) -> &mut Self { self.value.replace(value.into()); self } pub fn finish(&mut self) -> VNode { VNode::from(VNodePureComponent::new(MyComponent { value: self.value.take().expect("missing property value"), })) } } #[derive(PartialEq, Clone)] pub struct MyComponent { value: T, } impl MyComponent { pub fn builder(_tag: &'static str) -> MyComponentBuilder { MyComponentBuilder { value: None } } } impl PureComponent for MyComponent { fn render(&self) -> VNode { html! {

{"My component"}

} } } // Stateful component pub struct CounterBuilder { min: Option, max: Option, } impl CounterBuilder { pub fn set_attr_min(&mut self, min: i32) -> &mut Self { self.min.replace(min); self } pub fn set_attr_max(&mut self, max: i32) -> &mut Self { self.max.replace(max); self } pub fn finish(&mut self) -> VNode { VNode::from(VNodeStatefulComponent::new(Counter { min: self.min, max: self.max, })) } } #[derive(PartialEq, Clone)] pub struct Counter { min: Option, max: Option, } impl Counter { pub fn builder(_tag: &'static str) -> CounterBuilder { CounterBuilder { min: None, max: None, } } } impl StatefulComponent for Counter { fn update(&mut self, other: Self) -> bool { let should_update = *self != other; *self = other; should_update } fn render(&self, context: &StatefulComponentHandler) -> VNode { let range: IString = match (self.min, self.max) { (Some(min), Some(max)) => format!("{min}-{max}").into(), (Some(min), _) => format!("{min}-").into(), (_, Some(max)) => format!("-{max}").into(), (None, None) => "-".into(), }; let value = context.with_state(|x: &i32| *x); let inc_callback = context.callback(|_, x: &mut i32, _: web_sys::Event| { log("click!"); *x += 1; }); let dec_callback = context.callback(|_, x: &mut i32, _: web_sys::Event| { log("click!"); *x -= 1; }); html! {

{"Counter ("}{range}{"): "}("{}", value)

} } } // main program for testing purpose fn render(name: impl Into, swap: bool) -> VNode { let mut text1 = html! { {"Hello"} }; let mut text2 = html! { {name.into()} }; if swap { std::mem::swap(&mut text1, &mut text2); } fn make_stuff(i: i32) -> VNode { html! {
  • {"Stuff #"}("{}", i)
  • } } let mut stuff1 = make_stuff(1); let mut stuff2 = make_stuff(2); if swap { std::mem::swap(&mut stuff1, &mut stuff2); } html! { <> <>{"Header"}
    <>{text1}
    {text2}{"!"}
      {stuff1} {stuff2}
    value=42 /> <>{"Footer"} } } // startup let window = web_sys::window().unwrap(); let document = window.document().unwrap(); let body = document.body().unwrap(); let app = render("World", false).create_dom(&body); // some updates for testing purpose let app = app.update(render("Q", true)); let _ = app.update(render("World", false)); }