diff --git a/crates/macro/src/lib.rs b/crates/macro/src/lib.rs index d83e9662c27..894e9a20a1f 100644 --- a/crates/macro/src/lib.rs +++ b/crates/macro/src/lib.rs @@ -31,6 +31,10 @@ //! # unimplemented!() //! # } //! # +//! # fn change(&mut self, props: Self::Properties) -> ShouldRender { +//! # unimplemented!() +//! # } +//! # //! # fn view(&self) -> Html { //! # //! // ... diff --git a/crates/macro/tests/macro/html-component-fail.rs b/crates/macro/tests/macro/html-component-fail.rs index 0a42e145740..fd7e2ba0969 100644 --- a/crates/macro/tests/macro/html-component-fail.rs +++ b/crates/macro/tests/macro/html-component-fail.rs @@ -21,6 +21,9 @@ impl Component for Child { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } @@ -42,6 +45,9 @@ impl Component for ChildContainer { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } @@ -61,6 +67,9 @@ impl Component for Generic { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } diff --git a/crates/macro/tests/macro/html-component-fail.stderr b/crates/macro/tests/macro/html-component-fail.stderr index af1fe913722..d16126cc9f2 100644 --- a/crates/macro/tests/macro/html-component-fail.stderr +++ b/crates/macro/tests/macro/html-component-fail.stderr @@ -1,178 +1,178 @@ error: this open tag has no corresponding close tag - --> $DIR/html-component-fail.rs:70:13 + --> $DIR/html-component-fail.rs:79:13 | -70 | html! { }; +79 | html! { }; | ^^^^^^^ error: expected identifier - --> $DIR/html-component-fail.rs:71:22 + --> $DIR/html-component-fail.rs:80:22 | -71 | html! { }; +80 | html! { }; | ^ error: unexpected end of input, expected identifier - --> $DIR/html-component-fail.rs:72:5 + --> $DIR/html-component-fail.rs:81:5 | -72 | html! { }; +81 | html! { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unexpected token - --> $DIR/html-component-fail.rs:73:20 + --> $DIR/html-component-fail.rs:82:20 | -73 | html! { }; +82 | html! { }; | ^^^^^ error: this open tag has no corresponding close tag - --> $DIR/html-component-fail.rs:74:13 + --> $DIR/html-component-fail.rs:83:13 | -74 | html! { }; +83 | html! { }; | ^^^^^^^^^^^^^^^^^^^ error: too many refs set - --> $DIR/html-component-fail.rs:75:38 + --> $DIR/html-component-fail.rs:84:38 | -75 | html! { }; +84 | html! { }; | ^^^ error: too many refs set - --> $DIR/html-component-fail.rs:76:38 + --> $DIR/html-component-fail.rs:85:38 | -76 | html! { }; +85 | html! { }; | ^^^ error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop - --> $DIR/html-component-fail.rs:77:38 + --> $DIR/html-component-fail.rs:86:38 | -77 | html! { }; +86 | html! { }; | ^^^^^ error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop - --> $DIR/html-component-fail.rs:78:31 + --> $DIR/html-component-fail.rs:87:31 | -78 | html! { }; +87 | html! { }; | ^^^^^ error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop - --> $DIR/html-component-fail.rs:79:28 + --> $DIR/html-component-fail.rs:88:28 | -79 | html! { }; +88 | html! { }; | ^^^^ error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop - --> $DIR/html-component-fail.rs:80:35 + --> $DIR/html-component-fail.rs:89:35 | -80 | html! { }; +89 | html! { }; | ^^^^ error: too many refs set - --> $DIR/html-component-fail.rs:81:27 + --> $DIR/html-component-fail.rs:90:27 | -81 | html! { }; +90 | html! { }; | ^^^ error: unexpected token - --> $DIR/html-component-fail.rs:83:31 + --> $DIR/html-component-fail.rs:92:31 | -83 | html! { }; +92 | html! { }; | ^^ error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop - --> $DIR/html-component-fail.rs:84:28 + --> $DIR/html-component-fail.rs:93:28 | -84 | html! { }; +93 | html! { }; | ^^^^ error: Using special syntax `with props` along with named prop is not allowed. This rule does not apply to special `ref` prop - --> $DIR/html-component-fail.rs:85:31 + --> $DIR/html-component-fail.rs:94:31 | -85 | html! { }; +94 | html! { }; | ^^^^^ error: expected identifier - --> $DIR/html-component-fail.rs:86:20 + --> $DIR/html-component-fail.rs:95:20 | -86 | html! { }; +95 | html! { }; | ^^^^ error: expected identifier - --> $DIR/html-component-fail.rs:87:20 + --> $DIR/html-component-fail.rs:96:20 | -87 | html! { }; +96 | html! { }; | ^^^^^^^^^^^^^^^^^ error: unexpected end of input, expected expression - --> $DIR/html-component-fail.rs:89:5 + --> $DIR/html-component-fail.rs:98:5 | -89 | html! { }; +98 | html! { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: too many refs set - --> $DIR/html-component-fail.rs:94:33 - | -94 | html! { }; - | ^^^ + --> $DIR/html-component-fail.rs:103:33 + | +103 | html! { }; + | ^^^ error: this close tag has no corresponding open tag - --> $DIR/html-component-fail.rs:97:13 - | -97 | html! { }; - | ^^^^^^^^ + --> $DIR/html-component-fail.rs:106:13 + | +106 | html! { }; + | ^^^^^^^^ error: this open tag has no corresponding close tag - --> $DIR/html-component-fail.rs:98:13 - | -98 | html! { }; - | ^^^^^^^ + --> $DIR/html-component-fail.rs:107:13 + | +107 | html! { }; + | ^^^^^^^ error: only one root html element allowed - --> $DIR/html-component-fail.rs:99:28 - | -99 | html! { }; - | ^^^^^^^^^^^^^^^ + --> $DIR/html-component-fail.rs:108:28 + | +108 | html! { }; + | ^^^^^^^^^^^^^^^ error: this close tag has no corresponding open tag - --> $DIR/html-component-fail.rs:108:30 + --> $DIR/html-component-fail.rs:117:30 | -108 | html! { > }; +117 | html! { > }; | ^^^^^^^^^^ error: this close tag has no corresponding open tag - --> $DIR/html-component-fail.rs:109:30 + --> $DIR/html-component-fail.rs:118:30 | -109 | html! { >>> }; +118 | html! { >>> }; | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0425]: cannot find value `blah` in this scope - --> $DIR/html-component-fail.rs:82:25 + --> $DIR/html-component-fail.rs:91:25 | -82 | html! { }; +91 | html! { }; | ^^^^ not found in this scope error[E0609]: no field `unknown` on type `ChildProperties` - --> $DIR/html-component-fail.rs:88:20 + --> $DIR/html-component-fail.rs:97:20 | -88 | html! { }; +97 | html! { }; | ^^^^^^^ unknown field | = note: available fields are: `string`, `int` error[E0599]: no method named `unknown` found for struct `ChildPropertiesBuilder` in the current scope - --> $DIR/html-component-fail.rs:88:20 + --> $DIR/html-component-fail.rs:97:20 | 6 | #[derive(Clone, Properties, PartialEq)] | ---------- method `unknown` not found for this ... -88 | html! { }; +97 | html! { }; | ^^^^^^^ method not found in `ChildPropertiesBuilder` error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer<(), std::string::String>` is not satisfied - --> $DIR/html-component-fail.rs:90:33 + --> $DIR/html-component-fail.rs:99:33 | -90 | html! { }; +99 | html! { }; | ^^ the trait `yew::virtual_dom::Transformer<(), std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp` | = help: the following implementations were found: @@ -184,84 +184,84 @@ error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom: = note: required by `yew::virtual_dom::Transformer::transform` error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer<{integer}, std::string::String>` is not satisfied - --> $DIR/html-component-fail.rs:91:33 - | -91 | html! { }; - | ^ the trait `yew::virtual_dom::Transformer<{integer}, std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp` - | - = help: the following implementations were found: - > - >> - >> - > - and 3 others - = note: required by `yew::virtual_dom::Transformer::transform` + --> $DIR/html-component-fail.rs:100:33 + | +100 | html! { }; + | ^ the trait `yew::virtual_dom::Transformer<{integer}, std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp` + | + = help: the following implementations were found: + > + >> + >> + > + and 3 others + = note: required by `yew::virtual_dom::Transformer::transform` error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer<{integer}, std::string::String>` is not satisfied - --> $DIR/html-component-fail.rs:92:33 - | -92 | html! { }; - | ^^^ the trait `yew::virtual_dom::Transformer<{integer}, std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp` - | - = help: the following implementations were found: - > - >> - >> - > - and 3 others - = note: required by `yew::virtual_dom::Transformer::transform` + --> $DIR/html-component-fail.rs:101:33 + | +101 | html! { }; + | ^^^ the trait `yew::virtual_dom::Transformer<{integer}, std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp` + | + = help: the following implementations were found: + > + >> + >> + > + and 3 others + = note: required by `yew::virtual_dom::Transformer::transform` error[E0308]: mismatched types - --> $DIR/html-component-fail.rs:93:30 - | -93 | html! { }; - | ^^ expected struct `yew::html::NodeRef`, found `()` + --> $DIR/html-component-fail.rs:102:30 + | +102 | html! { }; + | ^^ expected struct `yew::html::NodeRef`, found `()` error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer` is not satisfied - --> $DIR/html-component-fail.rs:95:24 - | -95 | html! { }; - | ^^^^ the trait `yew::virtual_dom::Transformer` is not implemented for `yew::virtual_dom::vcomp::VComp` - | - = help: the following implementations were found: - > - >> - >> - > - and 3 others - = note: required by `yew::virtual_dom::Transformer::transform` + --> $DIR/html-component-fail.rs:104:24 + | +104 | html! { }; + | ^^^^ the trait `yew::virtual_dom::Transformer` is not implemented for `yew::virtual_dom::vcomp::VComp` + | + = help: the following implementations were found: + > + >> + >> + > + and 3 others + = note: required by `yew::virtual_dom::Transformer::transform` error[E0599]: no method named `string` found for struct `ChildPropertiesBuilder` in the current scope - --> $DIR/html-component-fail.rs:96:20 - | -6 | #[derive(Clone, Properties, PartialEq)] - | ---------- method `string` not found for this + --> $DIR/html-component-fail.rs:105:20 + | +6 | #[derive(Clone, Properties, PartialEq)] + | ---------- method `string` not found for this ... -96 | html! { }; - | ^^^^^^ method not found in `ChildPropertiesBuilder` - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `string`, perhaps you need to implement it: - candidate #1: `proc_macro::bridge::server::Literal` +105 | html! { }; + | ^^^^^^ method not found in `ChildPropertiesBuilder` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `string`, perhaps you need to implement it: + candidate #1: `proc_macro::bridge::server::Literal` error[E0599]: no method named `children` found for struct `ChildPropertiesBuilder` in the current scope - --> $DIR/html-component-fail.rs:100:5 + --> $DIR/html-component-fail.rs:109:5 | 6 | #[derive(Clone, Properties, PartialEq)] | ---------- method `children` not found for this ... -100 | html! { { "Not allowed" } }; +109 | html! { { "Not allowed" } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `ChildPropertiesBuilder` | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0599]: no method named `build` found for struct `ChildContainerPropertiesBuilder` in the current scope - --> $DIR/html-component-fail.rs:102:5 + --> $DIR/html-component-fail.rs:111:5 | -29 | #[derive(Clone, Properties)] +32 | #[derive(Clone, Properties)] | ---------- method `build` not found for this ... -102 | html! { }; +111 | html! { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `ChildContainerPropertiesBuilder` | = help: items from traits can only be used if the trait is implemented and in scope @@ -270,12 +270,12 @@ error[E0599]: no method named `build` found for struct `ChildContainerProperties = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0599]: no method named `build` found for struct `ChildContainerPropertiesBuilder` in the current scope - --> $DIR/html-component-fail.rs:103:5 + --> $DIR/html-component-fail.rs:112:5 | -29 | #[derive(Clone, Properties)] +32 | #[derive(Clone, Properties)] | ---------- method `build` not found for this ... -103 | html! { }; +112 | html! { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `ChildContainerPropertiesBuilder` | = help: items from traits can only be used if the trait is implemented and in scope @@ -284,9 +284,9 @@ error[E0599]: no method named `build` found for struct `ChildContainerProperties = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0277]: the trait bound `yew::virtual_dom::vcomp::VChild: std::convert::From<&str>` is not satisfied - --> $DIR/html-component-fail.rs:104:5 + --> $DIR/html-component-fail.rs:113:5 | -104 | html! { { "Not allowed" } }; +113 | html! { { "Not allowed" } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `yew::virtual_dom::vcomp::VChild` | = note: required because of the requirements on the impl of `std::convert::Into>` for `&str` @@ -294,9 +294,9 @@ error[E0277]: the trait bound `yew::virtual_dom::vcomp::VChild: std::conv = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0277]: the trait bound `yew::virtual_dom::vcomp::VChild: std::convert::From` is not satisfied - --> $DIR/html-component-fail.rs:105:5 + --> $DIR/html-component-fail.rs:114:5 | -105 | html! { <> }; +114 | html! { <> }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From` is not implemented for `yew::virtual_dom::vcomp::VChild` | = note: required because of the requirements on the impl of `std::convert::Into>` for `yew::virtual_dom::vnode::VNode` @@ -304,9 +304,9 @@ error[E0277]: the trait bound `yew::virtual_dom::vcomp::VChild: std::conv = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error[E0277]: the trait bound `yew::virtual_dom::vcomp::VChild: std::convert::From` is not satisfied - --> $DIR/html-component-fail.rs:106:5 + --> $DIR/html-component-fail.rs:115:5 | -106 | html! { }; +115 | html! { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From` is not implemented for `yew::virtual_dom::vcomp::VChild` | = note: required because of the requirements on the impl of `std::convert::Into>` for `yew::virtual_dom::vnode::VNode` diff --git a/crates/macro/tests/macro/html-component-pass.rs b/crates/macro/tests/macro/html-component-pass.rs index cf70b1e3825..a0a4fd41901 100644 --- a/crates/macro/tests/macro/html-component-pass.rs +++ b/crates/macro/tests/macro/html-component-pass.rs @@ -19,6 +19,9 @@ impl Component for Generic { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } @@ -34,6 +37,9 @@ impl Component for Generic> { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } @@ -57,6 +63,9 @@ impl Component for Container { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } @@ -113,6 +122,9 @@ impl Component for Child { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } @@ -129,6 +141,9 @@ impl Component for AltChild { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } @@ -152,6 +167,9 @@ impl Component for ChildContainer { fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!() + } fn view(&self) -> Html { unimplemented!() } diff --git a/examples/crm/src/lib.rs b/examples/crm/src/lib.rs index 4a9fafe4ea8..10ae866a173 100644 --- a/examples/crm/src/lib.rs +++ b/examples/crm/src/lib.rs @@ -146,6 +146,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { match self.scene { Scene::ClientsList => html! { diff --git a/examples/custom_components/src/lib.rs b/examples/custom_components/src/lib.rs index 13525102910..ac87d2d4005 100644 --- a/examples/custom_components/src/lib.rs +++ b/examples/custom_components/src/lib.rs @@ -46,6 +46,10 @@ impl Component for Model { } } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { let counter = |x| { html! { diff --git a/examples/dashboard/src/lib.rs b/examples/dashboard/src/lib.rs index 6cac152ff84..c9971f60443 100644 --- a/examples/dashboard/src/lib.rs +++ b/examples/dashboard/src/lib.rs @@ -186,6 +186,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/fragments/src/lib.rs b/examples/fragments/src/lib.rs index 4475fdea540..9a6e0164271 100644 --- a/examples/fragments/src/lib.rs +++ b/examples/fragments/src/lib.rs @@ -34,6 +34,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! { <> diff --git a/examples/game_of_life/src/lib.rs b/examples/game_of_life/src/lib.rs index 8aee94cd0fb..61c74cbfc78 100644 --- a/examples/game_of_life/src/lib.rs +++ b/examples/game_of_life/src/lib.rs @@ -209,6 +209,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/large_table/src/lib.rs b/examples/large_table/src/lib.rs index 828c8acebae..f9c46c85028 100644 --- a/examples/large_table/src/lib.rs +++ b/examples/large_table/src/lib.rs @@ -33,6 +33,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! { diff --git a/examples/showcase/src/main.rs b/examples/showcase/src/main.rs index 5f3a9d89b24..1bba324c44b 100644 --- a/examples/showcase/src/main.rs +++ b/examples/showcase/src/main.rs @@ -91,6 +91,10 @@ impl Component for Model { } } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/std_web/counter/src/lib.rs b/examples/std_web/counter/src/lib.rs index 430d9e6ad9e..c61857d0683 100644 --- a/examples/std_web/counter/src/lib.rs +++ b/examples/std_web/counter/src/lib.rs @@ -48,6 +48,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/std_web/inner_html/src/lib.rs b/examples/std_web/inner_html/src/lib.rs index 1427fc88fde..8d572a6d9f1 100644 --- a/examples/std_web/inner_html/src/lib.rs +++ b/examples/std_web/inner_html/src/lib.rs @@ -33,6 +33,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { let js_svg = js! { var div = document.createElement("div"); diff --git a/examples/std_web/mount_point/src/lib.rs b/examples/std_web/mount_point/src/lib.rs index 29c728b1ba3..37f268aad5f 100644 --- a/examples/std_web/mount_point/src/lib.rs +++ b/examples/std_web/mount_point/src/lib.rs @@ -29,6 +29,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/std_web/node_refs/src/input.rs b/examples/std_web/node_refs/src/input.rs index 3aac8257b5c..561aa0b3fa2 100644 --- a/examples/std_web/node_refs/src/input.rs +++ b/examples/std_web/node_refs/src/input.rs @@ -31,6 +31,11 @@ impl Component for InputComponent { false } + fn change(&mut self, props: Self::Properties) -> ShouldRender { + self.props = props; + true + } + fn view(&self) -> Html { html! { ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/std_web/npm_and_rest/src/lib.rs b/examples/std_web/npm_and_rest/src/lib.rs index 27d646ae315..ddac427af70 100644 --- a/examples/std_web/npm_and_rest/src/lib.rs +++ b/examples/std_web/npm_and_rest/src/lib.rs @@ -67,6 +67,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { let view_exchange = |exchange| { html! { diff --git a/examples/std_web/todomvc/src/lib.rs b/examples/std_web/todomvc/src/lib.rs index dffea6676e1..920e9de1779 100644 --- a/examples/std_web/todomvc/src/lib.rs +++ b/examples/std_web/todomvc/src/lib.rs @@ -121,6 +121,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/std_web/two_apps/src/lib.rs b/examples/std_web/two_apps/src/lib.rs index 17975a948bc..7424cc444b9 100644 --- a/examples/std_web/two_apps/src/lib.rs +++ b/examples/std_web/two_apps/src/lib.rs @@ -57,6 +57,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/textarea/src/lib.rs b/examples/textarea/src/lib.rs index 60a330c6a2c..c22ec0c46a9 100644 --- a/examples/textarea/src/lib.rs +++ b/examples/textarea/src/lib.rs @@ -35,6 +35,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/timer/src/lib.rs b/examples/timer/src/lib.rs index a27a2a8169d..87dddaac3d0 100644 --- a/examples/timer/src/lib.rs +++ b/examples/timer/src/lib.rs @@ -97,6 +97,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { let view_message = |message| { html! {

{ message }

} diff --git a/examples/web_sys/counter/src/lib.rs b/examples/web_sys/counter/src/lib.rs index 7bf99358801..eb7953481b8 100644 --- a/examples/web_sys/counter/src/lib.rs +++ b/examples/web_sys/counter/src/lib.rs @@ -48,6 +48,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/web_sys/inner_html/src/lib.rs b/examples/web_sys/inner_html/src/lib.rs index 160290adafe..bd52d12829a 100644 --- a/examples/web_sys/inner_html/src/lib.rs +++ b/examples/web_sys/inner_html/src/lib.rs @@ -30,6 +30,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { let js_svg = { let div = web_sys::window() diff --git a/examples/web_sys/mount_point/src/lib.rs b/examples/web_sys/mount_point/src/lib.rs index 29c728b1ba3..37f268aad5f 100644 --- a/examples/web_sys/mount_point/src/lib.rs +++ b/examples/web_sys/mount_point/src/lib.rs @@ -29,6 +29,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/web_sys/node_refs/src/input.rs b/examples/web_sys/node_refs/src/input.rs index 3aac8257b5c..561aa0b3fa2 100644 --- a/examples/web_sys/node_refs/src/input.rs +++ b/examples/web_sys/node_refs/src/input.rs @@ -31,6 +31,11 @@ impl Component for InputComponent { false } + fn change(&mut self, props: Self::Properties) -> ShouldRender { + self.props = props; + true + } + fn view(&self) -> Html { html! { ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/web_sys/npm_and_rest/src/lib.rs b/examples/web_sys/npm_and_rest/src/lib.rs index 97b6a16c116..4ee652d19a1 100644 --- a/examples/web_sys/npm_and_rest/src/lib.rs +++ b/examples/web_sys/npm_and_rest/src/lib.rs @@ -64,6 +64,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { let view_exchange = |exchange| { html! { diff --git a/examples/web_sys/todomvc/src/lib.rs b/examples/web_sys/todomvc/src/lib.rs index fb0760ab248..f7e43fd5859 100644 --- a/examples/web_sys/todomvc/src/lib.rs +++ b/examples/web_sys/todomvc/src/lib.rs @@ -121,6 +121,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/examples/web_sys/two_apps/src/lib.rs b/examples/web_sys/two_apps/src/lib.rs index 17975a948bc..7424cc444b9 100644 --- a/examples/web_sys/two_apps/src/lib.rs +++ b/examples/web_sys/two_apps/src/lib.rs @@ -57,6 +57,10 @@ impl Component for Model { true } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + fn view(&self) -> Html { html! {
diff --git a/src/components/select.rs b/src/components/select.rs index d9fd01e6ab4..bae1b08c9ea 100644 --- a/src/components/select.rs +++ b/src/components/select.rs @@ -14,6 +14,7 @@ //!# type Message = ();type Properties = (); //!# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} //!# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} +//!# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} //!# fn view(&self) -> Html {unimplemented!()}} //! impl ToString for Scene { //! fn to_string(&self) -> String { diff --git a/src/html/mod.rs b/src/html/mod.rs index d776d947c49..dc442d60d06 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -31,13 +31,41 @@ cfg_if! { /// This type indicates that component should be rendered again. pub type ShouldRender = bool; -/// An interface of a UI-component. Uses `self` as a model. +/// Components are the basic building blocks of the UI in a Yew app. Each Component +/// chooses how to display itself using received props and self-managed state. +/// Components can be dynamic and interactive by declaring messages that are +/// triggered and handled asynchronously. This async update mechanism is inspired by +/// Elm and the actor model used in the Actix framework. pub trait Component: Sized + 'static { - /// Control message type which `update` loop get. + /// Messages are used to make Components dynamic and interactive. Simple + /// Component's can declare their Message type to be `()`. Complex Component's + /// commonly use an enum to declare multiple Message types. type Message: 'static; - /// Properties type of component implementation. + + /// Properties are the inputs to a Component and should not mutated within a + /// Component. They are passed to a Component using a JSX-style syntax. + /// ``` + ///# use yew::{Html, Component, Properties, ComponentLink, html}; + ///# struct Model; + ///# #[derive(Clone, Properties)] + ///# struct Props { + ///# prop: String, + ///# } + ///# impl Component for Model { + ///# type Message = ();type Properties = Props; + ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} + ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} + ///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} + ///# fn view(&self) -> Html { + /// html! { + /// + /// } + ///# }} + /// ``` type Properties: Properties; - /// Initialization routine which could use a context. + + /// Components are created with their properties as well as a `ComponentLink` which + /// can be used to send messages and create callbacks for triggering updates. fn create(props: Self::Properties, link: ComponentLink) -> Self; /// Called after the component has been attached to the VDOM and it is safe to receive messages /// from agents but before the browser updates the screen. If true is returned, the view will @@ -48,15 +76,36 @@ pub trait Component: Sized + 'static { /// Called everytime when a messages of `Msg` type received. It also takes a /// reference to a context. fn update(&mut self, msg: Self::Message) -> ShouldRender; - /// Called when the component's parent component re-renders and the - /// component's place in the DOM tree remains unchanged. If the component's - /// place in the DOM tree changes, calling this method is unnecessary as the - /// component is recreated from scratch. It defaults to true if not implemented - /// and Self::Properties is not the unit type `()`. - fn change(&mut self, _props: Self::Properties) -> ShouldRender { - TypeId::of::() != TypeId::of::<()>() - } - /// Called by rendering loop. + + /// When the parent of a Component is re-rendered, it will either be re-created or + /// receive new properties in the `change` lifecycle method. Component's can choose + /// to re-render if the new properties are different than the previously + /// received properties. Most Component's will use props with a `PartialEq` + /// impl and will be implemented like this: + /// ``` + ///# use yew::{Html, Component, ComponentLink, html, ShouldRender}; + ///# struct Model{props: ()}; + ///# impl Component for Model { + ///# type Message = ();type Properties = (); + ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} + ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} + ///# fn view(&self) -> Html {unimplemented!()} + /// fn change(&mut self, props: Self::Properties) -> ShouldRender { + /// if self.props != props { + /// self.props = props; + /// true + /// } else { + /// false + /// } + /// } + ///# } + /// ``` + /// Components which don't have properties should always return false. + fn change(&mut self, _props: Self::Properties) -> ShouldRender; + + /// Components define their visual layout using a JSX-style syntax through the use of the + /// `html!` procedural macro. The full guide to using the macro can be found in [Yew's + /// documentation](https://yew.rs/docs/concepts/html). fn view(&self) -> Html; /// Called for finalization on the final point of the component's lifetime. fn destroy(&mut self) {} // TODO(#941): Replace with `Drop` @@ -83,6 +132,7 @@ pub type Html = VNode; ///# type Properties = WrapperProps; ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} +///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# // This is not a valid implementation. This is done for space convenience. ///# fn view(&self) -> Html { /// html! { @@ -113,6 +163,7 @@ pub type Html = VNode; ///# type Properties = WrapperProps; ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} +///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} /// fn view(&self) -> Html { /// html! { ///
@@ -143,6 +194,7 @@ pub type Children = ChildrenRenderer; ///# type Properties = ListProps; ///# fn create(props: Self::Properties, link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self, msg: Self::Message) -> bool {unimplemented!()} +///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# #[derive(Clone, Properties)] @@ -155,6 +207,7 @@ pub type Children = ChildrenRenderer; ///# type Properties = ListItemProps; ///# fn create(props: Self::Properties, link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self, msg: Self::Message) -> bool {unimplemented!()} +///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# fn view() -> Html { @@ -186,6 +239,7 @@ pub type Children = ChildrenRenderer; ///# type Properties = ListProps; ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} +///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} /// // ... /// fn view(&self) -> Html { /// html!{{ @@ -209,6 +263,7 @@ pub type Children = ChildrenRenderer; ///# type Properties = ListItemProps; ///# fn create(props: Self::Properties, link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self, msg: Self::Message) -> bool {unimplemented!()} +///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } /// ``` @@ -311,6 +366,10 @@ where /// false /// } /// +/// fn change(&mut self, _: Self::Properties) -> ShouldRender { +/// false +/// } +/// /// fn update(&mut self, _: Self::Message) -> ShouldRender { /// false /// } diff --git a/src/lib.rs b/src/lib.rs index 0d612bfcce0..d788171a1c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,10 @@ //! true //! } //! +//! fn change(&mut self, _: Self::Properties) -> ShouldRender { +//! false +//! } +//! //! fn view(&self) -> Html { //! html! { //!
diff --git a/src/services/fetch/std_web.rs b/src/services/fetch/std_web.rs index e9cb8070f13..4fc657d2c42 100644 --- a/src/services/fetch/std_web.rs +++ b/src/services/fetch/std_web.rs @@ -185,7 +185,7 @@ impl FetchService { /// .expect("Failed to build request."); /// ``` /// - /// The callback function can build a loop message by passing or analizing the + /// The callback function can build a loop message by passing or analyzing the /// response body and metadata. /// /// ``` @@ -197,6 +197,7 @@ impl FetchService { ///# type Message = Msg;type Properties = (); ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} + ///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# enum Msg { @@ -236,6 +237,7 @@ impl FetchService { ///# type Message = Msg;type Properties = (); ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} + ///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# enum Msg { @@ -289,6 +291,7 @@ impl FetchService { ///# type Properties = (); ///# fn create(props: Self::Properties, link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self, msg: Self::Message) -> bool {unimplemented!()} + ///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# pub enum Msg { } diff --git a/src/services/fetch/web_sys.rs b/src/services/fetch/web_sys.rs index a2d37dcbe56..960b199c6ab 100644 --- a/src/services/fetch/web_sys.rs +++ b/src/services/fetch/web_sys.rs @@ -199,6 +199,7 @@ impl FetchService { ///# type Message = Msg;type Properties = (); ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} + ///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# enum Msg { @@ -239,6 +240,7 @@ impl FetchService { ///# type Message = Msg;type Properties = (); ///# fn create(props: Self::Properties,link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self,msg: Self::Message) -> bool {unimplemented!()} + ///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# enum Msg { @@ -293,6 +295,7 @@ impl FetchService { ///# type Properties = (); ///# fn create(props: Self::Properties, link: ComponentLink) -> Self {unimplemented!()} ///# fn update(&mut self, msg: Self::Message) -> bool {unimplemented!()} + ///# fn change(&mut self, _: Self::Properties) -> bool {unimplemented!()} ///# fn view(&self) -> Html {unimplemented!()} ///# } ///# pub enum Msg {} diff --git a/src/virtual_dom/vcomp.rs b/src/virtual_dom/vcomp.rs index c6cd0ee5fb5..1f27eebacc2 100644 --- a/src/virtual_dom/vcomp.rs +++ b/src/virtual_dom/vcomp.rs @@ -346,6 +346,10 @@ mod tests { unimplemented!(); } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!(); + } + fn view(&self) -> Html { unimplemented!(); } diff --git a/src/virtual_dom/vlist.rs b/src/virtual_dom/vlist.rs index eb64c9bae55..6450a44f2d6 100644 --- a/src/virtual_dom/vlist.rs +++ b/src/virtual_dom/vlist.rs @@ -146,6 +146,10 @@ mod tests { unimplemented!(); } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!(); + } + fn view(&self) -> Html { unimplemented!(); } diff --git a/src/virtual_dom/vtag.rs b/src/virtual_dom/vtag.rs index 0b86acac8ec..eab39872833 100644 --- a/src/virtual_dom/vtag.rs +++ b/src/virtual_dom/vtag.rs @@ -575,6 +575,10 @@ mod tests { unimplemented!(); } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!(); + } + fn view(&self) -> Html { unimplemented!(); } @@ -594,6 +598,10 @@ mod tests { unimplemented!(); } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!(); + } + fn view(&self) -> Html { unimplemented!(); } @@ -613,6 +621,10 @@ mod tests { unimplemented!(); } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!(); + } + fn view(&self) -> Html { unimplemented!(); } diff --git a/src/virtual_dom/vtext.rs b/src/virtual_dom/vtext.rs index fb840346612..7202369d2b6 100644 --- a/src/virtual_dom/vtext.rs +++ b/src/virtual_dom/vtext.rs @@ -148,6 +148,10 @@ mod test { unimplemented!(); } + fn change(&mut self, _: Self::Properties) -> ShouldRender { + unimplemented!(); + } + fn view(&self) -> Html { unimplemented!(); }