Skip to content

Commit

Permalink
Merge #271
Browse files Browse the repository at this point in the history
271: Support passing a struct instance as properties r=DenisKolodin a=limira

If we have
```rust
#[derive(Debug, Default, Eq, PartialEq)]
pub struct MyProps {
    val: i32,
}

impl Component<Context> for MyComp {
    type Message = Msg;
    type Properties = MyProps;
}
```
then if we have an instance of `MyProps`, we can pass it directly to its Component:
```rust
let my_props = MyProps {val: 64 };
html! {
    <MyComp: props=my_props, />
}
```
Is there a better syntax for this?
If this is merged as is, any `struct` that is used for a Component's properties will not allowed to contain a field named `props`!

Edit: I you merge this, please squash all commits. While working on this, I got stuck by an error I don't know how to solve, just commit to get back to the original working code (from master).

Co-authored-by: Limira <20672976+limira@users.noreply.github.com>
  • Loading branch information
bors[bot] and limira committed Jun 7, 2018
2 parents 19515cc + e22b0ec commit 7f72c71
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ macro_rules! html_impl {
let mut pair = $crate::virtual_dom::VComp::lazy::<$comp>();
html_impl! { @vcomp $stack pair ($($tail)*) }
};
// Set a whole struct as a properties
(@vcomp $stack:ident $pair:ident (with $props:ident, $($tail:tt)*)) => {
$pair.0 = $props;
html_impl! { @vcomp $stack $pair ($($tail)*) }
};
// Set a specific field as a property.
// It uses `Transformer` trait to convert a type used in template to a type of the field.
(@vcomp $stack:ident $pair:ident ($attr:ident = $val:expr, $($tail:tt)*)) => {
// It cloned for ergonomics in templates. Attribute with
// `self.param` value could be reused and sholdn't be cloned
Expand Down
71 changes: 71 additions & 0 deletions tests/vcomp_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#[macro_use]
extern crate yew;

use yew::html::{Component, Env, Html, Renderable, ShouldRender};
use yew::virtual_dom::VNode;

type Ctx = ();

struct Comp;

#[derive(PartialEq, Clone)]
struct Props {
field_1: u32,
field_2: u32,
}

impl Default for Props {
fn default() -> Self {
Props {
field_1: 0,
field_2: 0,
}
}
}

impl Component<Ctx> for Comp {
type Message = ();
type Properties = Props;

fn create(_: Self::Properties, _: &mut Env<Ctx, Self>) -> Self {
Comp
}

fn update(&mut self, _: Self::Message, _: &mut Env<Ctx, Self>) -> ShouldRender {
unimplemented!();
}
}

impl Renderable<Ctx, Comp> for Comp {
fn view(&self) -> Html<Ctx, Self> {
unimplemented!();
}
}

#[test]
fn set_properties_to_component() {
let _: VNode<Ctx, Comp> = html! {
<Comp: />
};

let _: VNode<Ctx, Comp> = html! {
<Comp: field_1=1, />
};

let _: VNode<Ctx, Comp> = html! {
<Comp: field_2=2, />
};

let _: VNode<Ctx, Comp> = html! {
<Comp: field_1=1, field_2=2, />
};

let props = Props {
field_1: 1,
field_2: 1,
};

let _: VNode<Ctx, Comp> = html! {
<Comp: with props, field_2=2, />
};
}

0 comments on commit 7f72c71

Please sign in to comment.