From 82db16d318ae6925e893fba09c06ac89ad525555 Mon Sep 17 00:00:00 2001 From: Ben Berman Date: Fri, 29 Dec 2017 23:23:10 -0500 Subject: [PATCH] Just playin --- examples/component/Cargo.toml | 7 ++++ examples/component/src/main.rs | 41 ++++++++++++++++++ examples/component/src/my_component.rs | 57 ++++++++++++++++++++++++++ src/component.rs | 7 ++++ src/lib.rs | 2 +- src/macros.rs | 2 +- src/virtual_dom/vtag.rs | 2 - 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 examples/component/Cargo.toml create mode 100644 examples/component/src/main.rs create mode 100644 examples/component/src/my_component.rs create mode 100644 src/component.rs diff --git a/examples/component/Cargo.toml b/examples/component/Cargo.toml new file mode 100644 index 00000000000..d31274a678a --- /dev/null +++ b/examples/component/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "component" +version = "0.1.0" +authors = ["Ben Berman "] + +[dependencies] +yew = { path = "../.." } diff --git a/examples/component/src/main.rs b/examples/component/src/main.rs new file mode 100644 index 00000000000..95a293bccd1 --- /dev/null +++ b/examples/component/src/main.rs @@ -0,0 +1,41 @@ +#[macro_use] +extern crate yew; + +mod my_component; + +use yew::html::*; +use my_component::MyComponent; + +struct Model { + name: String, +} + +enum Msg { + ChangeName(String), +} + +fn update(_: &mut Context, model: &mut Model, msg: Msg) { + match msg { + Msg::ChangeName(new_name) => { + model.name = new_name; + } + } +} + +fn view(model: &Model) -> Html { + html! { +
+ + { model.name.clone() } + +
+ } +} + +fn main() { + let model = Model { + name: "River".to_owned(), + }; + + program(model, update, view); +} diff --git a/examples/component/src/my_component.rs b/examples/component/src/my_component.rs new file mode 100644 index 00000000000..f3edeb92d5b --- /dev/null +++ b/examples/component/src/my_component.rs @@ -0,0 +1,57 @@ +use yew::html::*; +use yew::component::*; +use yew::services::console::ConsoleService; + +pub struct MyComponent; + +pub struct MyModel { + pub counter: i32, +} + +// I'm thinking this could be included and used by the macro, but not by the user +// so it could have to always be called "Props" so the macro knows what to use +#[derive(PartialEq, Eq)] +pub struct Props { + // bad example, probably, because it would imply this is controlled while it's not + pub initial_value: i32, +} + +enum MyMsg { + Increment, + Decrement, + Noop, +} + +impl Component for MyComponent { + fn get_initial_model(&self, props: Props) -> MyModel { + MyModel { counter: props.initial_value } + } + + // other lifecycle hooks could definitely exist + + // I guess view would be called after every update, regardless of if it + // updated the model or the view + fn update(&self, context: &mut Context, model: &mut MyModel, msg: Option) { + match msg.unwrap_or(MyMsg::Noop) { + MyMsg::Increment => { + model.counter = model.counter + 1; + } + MyMsg::Decrement => { + model.counter = model.counter - 1; + } + MyMsg::Noop => { + context.get_console().info("Maybe a lifecycle hook got called or something"); + } + } + } + + fn view(&self, _: &Props, model: &MyModel) -> Html { + html! { +
+

{ "Counter:" } { model.counter }

+ + +
+ } + } +} diff --git a/src/component.rs b/src/component.rs new file mode 100644 index 00000000000..252ca59e901 --- /dev/null +++ b/src/component.rs @@ -0,0 +1,7 @@ +use html::{Context, Html}; + +pub trait Component { + fn get_initial_model(&self, props: Props) -> Model; + fn update(&self, context: &mut Context, model: &mut Model, msg: Option); + fn view(&self, props: &Props, model: &Model) -> Html; +} diff --git a/src/lib.rs b/src/lib.rs index 2b6cbf50101..f9e2b2666bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,4 +10,4 @@ pub mod macros; pub mod html; pub mod services; pub mod virtual_dom; - +pub mod component; diff --git a/src/macros.rs b/src/macros.rs index ab9922bf124..c3efc773a60 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -2,7 +2,7 @@ use virtual_dom::{VTag, VNode, Listener}; #[macro_export] macro_rules! html_impl { - // Start of openging tag + // Start of opening tag ($stack:ident (< $starttag:ident $($tail:tt)*)) => { let node = $crate::virtual_dom::VTag::new(stringify!($starttag)); $stack.push(node); diff --git a/src/virtual_dom/vtag.rs b/src/virtual_dom/vtag.rs index 1c5a295e491..1f1a9529016 100644 --- a/src/virtual_dom/vtag.rs +++ b/src/virtual_dom/vtag.rs @@ -155,9 +155,7 @@ impl VTag { (&None, None) => None, } } -} -impl VTag { pub fn render(&mut self, subject: &Element, mut opposite: Option, messages: Messages) { // TODO Replace self if tagName differs