From 03ea9496995c5d5e3286012df4657c6e26f5c266 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Mon, 28 Sep 2020 15:24:04 +0200 Subject: [PATCH] Example props (#25) --- .gitignore | 2 +- Cargo.lock | 26 ++++ README.md | 2 +- static/index.html | 12 +- yewprint-doc/src/buttons/example.rs | 36 ++++-- yewprint-doc/src/buttons/mod.rs | 76 +++++++++-- yewprint-doc/src/callout/example.rs | 64 ++++------ yewprint-doc/src/callout/mod.rs | 119 ++++++++++++++++-- yewprint-doc/src/collapse/example.rs | 2 +- yewprint-doc/src/collapse/mod.rs | 16 ++- yewprint-doc/src/example.rs | 87 +++++++++---- yewprint-doc/src/icon/mod.rs | 16 ++- yewprint-doc/src/lib.rs | 27 ++-- yewprint-doc/src/switch/mod.rs | 4 +- yewprint-doc/src/tree/example.rs | 4 +- yewprint-doc/src/tree/mod.rs | 16 ++- yewprint/Cargo.toml | 1 + yewprint/src/{buttons/mod.rs => buttons.rs} | 0 yewprint/src/{callout/mod.rs => callout.rs} | 0 yewprint/src/{collapse/mod.rs => collapse.rs} | 0 yewprint/src/html_elements.rs | 40 ++++++ yewprint/src/{icon/mod.rs => icon.rs} | 2 +- yewprint/src/lib.rs | 4 +- yewprint/src/{menu/mod.rs => menu.rs} | 2 +- yewprint/src/{switch/mod.rs => switch.rs} | 0 yewprint/src/{tree/mod.rs => tree.rs} | 0 26 files changed, 426 insertions(+), 132 deletions(-) rename yewprint/src/{buttons/mod.rs => buttons.rs} (100%) rename yewprint/src/{callout/mod.rs => callout.rs} (100%) rename yewprint/src/{collapse/mod.rs => collapse.rs} (100%) create mode 100644 yewprint/src/html_elements.rs rename yewprint/src/{icon/mod.rs => icon.rs} (96%) rename yewprint/src/{menu/mod.rs => menu.rs} (97%) rename yewprint/src/{switch/mod.rs => switch.rs} (100%) rename yewprint/src/{tree/mod.rs => tree.rs} (100%) diff --git a/.gitignore b/.gitignore index 71584b9..3a5f858 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/target +target /public /*.tgz diff --git a/Cargo.lock b/Cargo.lock index c77f0c0..dcbecf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -690,6 +690,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c" dependencies = [ "cfg-if", + "serde", + "serde_json", "wasm-bindgen-macro", ] @@ -854,6 +856,7 @@ dependencies = [ "regex", "web-sys", "yew", + "yewtil", ] [[package]] @@ -866,3 +869,26 @@ dependencies = [ "yew", "yewprint", ] + +[[package]] +name = "yewtil" +version = "0.3.1" +source = "git+https://github.com/yewstack/yew.git?rev=1507c21b#1507c21b39e7941f7b9fe8ff5af792cf55be1f6f" +dependencies = [ + "futures", + "log", + "wasm-bindgen", + "wasm-bindgen-futures", + "yew", + "yewtil-macro", +] + +[[package]] +name = "yewtil-macro" +version = "0.1.0" +source = "git+https://github.com/yewstack/yew.git?rev=1507c21b#1507c21b39e7941f7b9fe8ff5af792cf55be1f6f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/README.md b/README.md index d6bda6c..3f52761 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Roadmap - [ ] AnchorButton - [ ] [ButtonGroup](https://blueprintjs.com/docs/#core/components/button-group) - depends on: Button - - [ ] [Callout](https://blueprintjs.com/docs/#core/components/callout) + - [x] [Callout](https://blueprintjs.com/docs/#core/components/callout) - [ ] [Card](https://blueprintjs.com/docs/#core/components/card) - [x] [Collapse](https://blueprintjs.com/docs/#core/components/collapse) - [ ] [CollapsibleList](https://blueprintjs.com/docs/#core/components/collapsible-list) diff --git a/static/index.html b/static/index.html index fe6349a..9d636b0 100644 --- a/static/index.html +++ b/static/index.html @@ -49,7 +49,7 @@ white-space: pre-wrap; } - .docs-example-wrapper .bp3-code-block > pre { + .docs-example-wrapper .bp3-code-block pre { margin: 0; white-space: pre-wrap; } @@ -64,25 +64,25 @@ background-color: #293742; } - .docs-example-wrapper > .docs-source > .bp3-button { + .docs-source > .bp3-button { background-color: #ebf1f5; } - .bp3-dark .docs-example-wrapper > .docs-source > .bp3-button { + .bp3-dark .docs-source > .bp3-button { background-color: #394b59; } - .docs-example-wrapper > .docs-source { + .docs-source { margin-bottom: 40px; margin-top: 10px; } - .docs-example-wrapper > .docs-source .bp3-code-block { + .docs-source .bp3-code-block { filter: invert(1) hue-rotate(180deg) contrast(2); background-color: #002b36; } - .bp3-dark .docs-example-wrapper > .docs-source .bp3-code-block { + .bp3-dark .docs-source .bp3-code-block { filter: inherit; } diff --git a/yewprint-doc/src/buttons/example.rs b/yewprint-doc/src/buttons/example.rs index 762d75c..36b39ad 100644 --- a/yewprint-doc/src/buttons/example.rs +++ b/yewprint-doc/src/buttons/example.rs @@ -4,6 +4,13 @@ use yewprint::Button; pub struct Example { link: ComponentLink, counter: i64, + props: ExampleProps, +} + +#[derive(Clone, PartialEq, Properties)] +pub struct ExampleProps { + pub minimal: bool, + pub fill: bool, } pub enum Msg { @@ -12,10 +19,14 @@ pub enum Msg { impl Component for Example { type Message = Msg; - type Properties = (); + type Properties = ExampleProps; - fn create(_: Self::Properties, link: ComponentLink) -> Self { - Example { counter: 0, link } + fn create(props: Self::Properties, link: ComponentLink) -> Self { + Example { + counter: 0, + link, + props, + } } fn update(&mut self, msg: Self::Message) -> ShouldRender { @@ -25,16 +36,27 @@ impl Component for Example { true } - fn change(&mut self, _props: Self::Properties) -> ShouldRender { - true + fn change(&mut self, props: Self::Properties) -> ShouldRender { + if self.props != props { + self.props = props; + true + } else { + false + } } fn view(&self) -> Html { html! {
-

{"Counter: "} { self.counter }

+

{"Counter: "}{self.counter}

- +
} diff --git a/yewprint-doc/src/buttons/mod.rs b/yewprint-doc/src/buttons/mod.rs index 6290b82..5595ac6 100644 --- a/yewprint-doc/src/buttons/mod.rs +++ b/yewprint-doc/src/buttons/mod.rs @@ -1,16 +1,31 @@ -use yew::prelude::*; +mod example; -pub struct ButtonDoc; +use crate::ExampleContainer; +use example::*; +use yew::prelude::*; +use yewprint::{Switch, H1, H5}; + +pub struct ButtonDoc { + callback: Callback, + state: ExampleProps, +} impl Component for ButtonDoc { - type Message = (); + type Message = ExampleProps; type Properties = (); - fn create(_: Self::Properties, _link: ComponentLink) -> Self { - ButtonDoc + fn create(_: Self::Properties, link: ComponentLink) -> Self { + ButtonDoc { + callback: link.callback(|x| x), + state: ExampleProps { + minimal: false, + fill: false, + }, + } } - fn update(&mut self, _msg: Self::Message) -> ShouldRender { + fn update(&mut self, msg: Self::Message) -> ShouldRender { + self.state = msg; true } @@ -19,13 +34,56 @@ impl Component for ButtonDoc { } fn view(&self) -> Html { - let source = crate::include_example!(); + let example_props = self.state.clone(); + let source = crate::include_raw_html!( + concat!(env!("OUT_DIR"), "/", file!(), ".html"), + "bp3-code-block" + ); html! {
-

{"Button"}

-
{source}
+

{"Button"}

+
+ + }) + > + + +
} } } + +crate::build_example_prop_component! { + ButtonProps for ExampleProps => + fn view(&self) -> Html { + html! { +
+
{"Props"}
+ + +
+ } + } +} diff --git a/yewprint-doc/src/callout/example.rs b/yewprint-doc/src/callout/example.rs index 367776e..d87e053 100644 --- a/yewprint-doc/src/callout/example.rs +++ b/yewprint-doc/src/callout/example.rs @@ -1,66 +1,48 @@ use yew::prelude::*; -use yewprint::{Callout, Intent, Menu, MenuItem, Switch}; +use yewprint::{Callout, Intent}; pub struct Example { - link: ComponentLink, - intent: Option, - show_icon: bool, - show_title: bool, + props: ExampleProps, } -pub enum Msg { - ChangeIntent(Option), - ToggleIcon, - ToggleTitle, +#[derive(Clone, PartialEq, Properties)] +pub struct ExampleProps { + pub intent: Option, + pub show_icon: bool, + pub show_title: bool, } impl Component for Example { - type Message = Msg; - type Properties = (); + type Message = (); + type Properties = ExampleProps; - fn create(_: Self::Properties, link: ComponentLink) -> Self { - Example { - link, - intent: None, - show_icon: false, - show_title: true, - } + fn create(props: Self::Properties, _link: ComponentLink) -> Self { + Example { props } } - fn update(&mut self, msg: Self::Message) -> ShouldRender { - match msg { - Msg::ChangeIntent(new_intent) => self.intent = new_intent, - Msg::ToggleIcon => self.show_icon = !self.show_icon, - Msg::ToggleTitle => self.show_title = !self.show_title, - } + fn update(&mut self, _msg: Self::Message) -> ShouldRender { true } - fn change(&mut self, _props: Self::Properties) -> ShouldRender { - true + fn change(&mut self, props: Self::Properties) -> ShouldRender { + if self.props != props { + self.props = props; + true + } else { + false + } } fn view(&self) -> Html { - let title = if self.show_title { + let title = if self.props.show_title { Some("Visually important content") } else { None }; + html! { - -

{"The Callout element's background reflects its intent, if any."}

-
- - -

{"Select intent:"}

- - - - - - - -
+ +

{"The Callout element's background reflects its intent, if any."}

} } diff --git a/yewprint-doc/src/callout/mod.rs b/yewprint-doc/src/callout/mod.rs index 88d8f82..bc45c53 100644 --- a/yewprint-doc/src/callout/mod.rs +++ b/yewprint-doc/src/callout/mod.rs @@ -1,16 +1,32 @@ -use yew::prelude::*; +mod example; -pub struct CalloutDoc; +use crate::ExampleContainer; +use example::*; +use yew::prelude::*; +use yewprint::{Intent, Menu, MenuItem, Switch, H1, H5}; + +pub struct CalloutDoc { + callback: Callback, + state: ExampleProps, +} impl Component for CalloutDoc { - type Message = (); + type Message = ExampleProps; type Properties = (); - fn create(_: Self::Properties, _link: ComponentLink) -> Self { - CalloutDoc + fn create(_: Self::Properties, link: ComponentLink) -> Self { + CalloutDoc { + callback: link.callback(|x| x), + state: ExampleProps { + show_icon: false, + intent: None, + show_title: true, + }, + } } - fn update(&mut self, _msg: Self::Message) -> ShouldRender { + fn update(&mut self, msg: Self::Message) -> ShouldRender { + self.state = msg; true } @@ -19,13 +35,98 @@ impl Component for CalloutDoc { } fn view(&self) -> Html { - let source = crate::include_example!(); + let example_props = self.state.clone(); + let source = crate::include_raw_html!( + concat!(env!("OUT_DIR"), "/", file!(), ".html"), + "bp3-code-block" + ); html! {
-

{"Callout"}

-
{source}
+

{"Callout"}

+ + }) + > + +
} } } + +crate::build_example_prop_component! { + CalloutProps for ExampleProps => + fn view(&self) -> Html { + html! { +
+
{"Props"}
+
+ + +

{"Select intent:"}

+ + + + + + + +
+
+ } + } +} diff --git a/yewprint-doc/src/collapse/example.rs b/yewprint-doc/src/collapse/example.rs index 20e9cfc..0f3343d 100644 --- a/yewprint-doc/src/collapse/example.rs +++ b/yewprint-doc/src/collapse/example.rs @@ -1,5 +1,5 @@ use yew::prelude::*; -use yewprint::{Button,Collapse}; +use yewprint::{Button, Collapse}; pub struct Example { link: ComponentLink, diff --git a/yewprint-doc/src/collapse/mod.rs b/yewprint-doc/src/collapse/mod.rs index 0dc537b..f57b67a 100644 --- a/yewprint-doc/src/collapse/mod.rs +++ b/yewprint-doc/src/collapse/mod.rs @@ -1,4 +1,9 @@ +mod example; + +use crate::ExampleContainer; +use example::*; use yew::prelude::*; +use yewprint::H1; pub struct CollapseDoc; @@ -19,12 +24,17 @@ impl Component for CollapseDoc { } fn view(&self) -> Html { - let source = crate::include_example!(); + let source = crate::include_raw_html!( + concat!(env!("OUT_DIR"), "/", file!(), ".html"), + "bp3-code-block" + ); html! {
-

{"Tree"}

-
{source}
+

{"Collapse"}

+ + +
} } diff --git a/yewprint-doc/src/example.rs b/yewprint-doc/src/example.rs index fb94860..76779c4 100644 --- a/yewprint-doc/src/example.rs +++ b/yewprint-doc/src/example.rs @@ -15,6 +15,8 @@ pub enum Msg { pub struct Props { pub source: yew::virtual_dom::VNode, pub children: html::Children, + #[prop_or_default] + pub props: Option, } impl Component for ExampleContainer { @@ -36,16 +38,33 @@ impl Component for ExampleContainer { true } - fn change(&mut self, _props: Self::Properties) -> ShouldRender { - // TODO: never re-render this component? How to optimize this - false + fn change(&mut self, props: Self::Properties) -> ShouldRender { + if self.props != props { + self.props = props; + true + } else { + false + } } fn view(&self) -> Html { html! {
-
- {self.props.children.clone()} +
+
+ {self.props.children.clone()} +
+ { + if let Some(props) = self.props.props.clone() { + html! { +
+ {props} +
+ } + } else { + html!() + } + }