This commit is contained in:
Cecile Tonglet 2020-09-29 18:47:33 +02:00 committed by GitHub
parent e433e11db7
commit 1e840c81ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 361 additions and 262 deletions

View file

@ -16,7 +16,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: rustfmt --check **/*.rs - run: cargo fmt -- --check
if: ${{ github.event_name == 'pull_request' }} if: ${{ github.event_name == 'pull_request' }}
- uses: actions-rs/clippy-check@v1 - uses: actions-rs/clippy-check@v1
with: with:

3
.rustfmt.toml Normal file
View file

@ -0,0 +1,3 @@
error_on_line_overflow = true
error_on_unformatted = true
newline_style = "Unix"

82
Cargo.lock generated
View file

@ -18,6 +18,12 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344"
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.0.1"
@ -359,6 +365,19 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lexical-core"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if",
"ryu",
"static_assertions",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.77" version = "0.2.77"
@ -405,6 +424,17 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"lexical-core",
"memchr",
"version_check",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.43" version = "0.1.43"
@ -607,6 +637,12 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27207bb65232eda1f588cf46db2fee75c0808d557f6b3cf19a75f5d6d7c94df1" checksum = "27207bb65232eda1f588cf46db2fee75c0808d557f6b3cf19a75f5d6d7c94df1"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.39" version = "1.0.39"
@ -672,6 +708,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]] [[package]]
name = "walkdir" name = "walkdir"
version = "2.3.1" version = "2.3.1"
@ -847,6 +889,45 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "yew-router"
version = "0.14.0"
source = "git+https://github.com/yewstack/yew.git?rev=1507c21b#1507c21b39e7941f7b9fe8ff5af792cf55be1f6f"
dependencies = [
"cfg-if",
"cfg-match",
"gloo",
"js-sys",
"log",
"nom",
"serde",
"serde_json",
"wasm-bindgen",
"web-sys",
"yew",
"yew-router-macro",
"yew-router-route-parser",
]
[[package]]
name = "yew-router-macro"
version = "0.14.0"
source = "git+https://github.com/yewstack/yew.git?rev=1507c21b#1507c21b39e7941f7b9fe8ff5af792cf55be1f6f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"yew-router-route-parser",
]
[[package]]
name = "yew-router-route-parser"
version = "0.14.0"
source = "git+https://github.com/yewstack/yew.git?rev=1507c21b#1507c21b39e7941f7b9fe8ff5af792cf55be1f6f"
dependencies = [
"nom",
]
[[package]] [[package]]
name = "yewprint" name = "yewprint"
version = "0.1.0" version = "0.1.0"
@ -867,6 +948,7 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
"yew", "yew",
"yew-router",
"yewprint", "yewprint",
] ]

View file

@ -14,6 +14,7 @@ wasm-bindgen = "^0.2"
yew = { git = "https://github.com/yewstack/yew.git", rev = "1507c21b" } yew = { git = "https://github.com/yewstack/yew.git", rev = "1507c21b" }
web-sys = { version = "0.3", features = ["Window", "MediaQueryList"] } web-sys = { version = "0.3", features = ["Window", "MediaQueryList"] }
yewprint = { path = "../yewprint" } yewprint = { path = "../yewprint" }
yew-router = { git = "https://github.com/yewstack/yew.git", rev = "1507c21b" }
[build-dependencies] [build-dependencies]
syntect = "4.4.0" syntect = "4.4.0"

View file

@ -2,17 +2,21 @@ use crate::buttons::*;
use crate::callout::*; use crate::callout::*;
use crate::collapse::*; use crate::collapse::*;
use crate::icon::*; use crate::icon::*;
use crate::switch::*;
use crate::tree::*;
use crate::progressbar::*; use crate::progressbar::*;
use crate::tree::*;
use yew::prelude::*; use yew::prelude::*;
use yew_router::{
agent::{RouteAgentDispatcher, RouteRequest},
router::Router,
Switch,
};
use yewprint::{ConditionalClass, IconName, Menu, MenuItem}; use yewprint::{ConditionalClass, IconName, Menu, MenuItem};
pub struct App { pub struct App {
link: ComponentLink<Self>, link: ComponentLink<Self>,
doc_menu: DocMenu,
dark_theme: ConditionalClass, dark_theme: ConditionalClass,
route_dispatcher: RouteAgentDispatcher,
} }
pub enum Msg { pub enum Msg {
@ -31,8 +35,8 @@ impl Component for App {
.map(|x| x.matches()) .map(|x| x.matches())
.unwrap_or(true) .unwrap_or(true)
.into(), .into(),
doc_menu: DocMenu::Button,
link, link,
route_dispatcher: RouteAgentDispatcher::new(),
} }
} }
@ -40,7 +44,8 @@ impl Component for App {
match msg { match msg {
Msg::ToggleLight => *self.dark_theme ^= true, Msg::ToggleLight => *self.dark_theme ^= true,
Msg::GoToMenu(doc_menu) => { Msg::GoToMenu(doc_menu) => {
self.doc_menu = doc_menu; self.route_dispatcher
.send(RouteRequest::ChangeRoute(doc_menu.into()));
} }
} }
true true
@ -142,21 +147,20 @@ impl Component for App {
</div> </div>
<main class="docs-content-wrapper" role="main"> <main class="docs-content-wrapper" role="main">
<div class="docs-page"> <div class="docs-page">
{ <Router<DocMenu, ()>
match self.doc_menu { render=Router::render(|switch: DocMenu| {
DocMenu::Button => html! (<ButtonDoc />), match switch {
DocMenu::Switch => html! (<SwitchDoc DocMenu::Button | DocMenu::Home => html! (<ButtonDoc />),
dark_theme=self.dark_theme DocMenu::Switch => html! (),
onclick=self.link.callback(|_| Msg::ToggleLight) DocMenu::Callout => html!(<CalloutDoc />),
/>), DocMenu::Collapse => html!(<CollapseDoc />),
DocMenu::Callout => html!(<CalloutDoc />), DocMenu::Tree => html!(<TreeDoc />),
DocMenu::Collapse => html!(<CollapseDoc />), DocMenu::Icon => html!(<IconDoc />),
DocMenu::Tree => html!(<TreeDoc />), DocMenu::ProgressBar => html!(<ProgressBarDoc />),
DocMenu::Icon => html!(<IconDoc />), DocMenu::Menu => html!(),
DocMenu::ProgressBar => html!(<ProgressBarDoc />), }
DocMenu::Menu => html!(), })
} />
}
</div> </div>
</main> </main>
</div> </div>
@ -165,14 +169,24 @@ impl Component for App {
} }
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone, Switch)]
pub enum DocMenu { pub enum DocMenu {
#[to = "/#button"]
Button, Button,
#[to = "/#callout"]
Callout, Callout,
#[to = "/#collapse"]
Collapse, Collapse,
#[to = "/#icon"]
Icon, Icon,
#[to = "/#menu"]
Menu, Menu,
#[to = "/#switch"]
Switch, Switch,
#[to = "/#tree"]
Tree, Tree,
#[to = "/#progress-bar"]
ProgressBar, ProgressBar,
#[to = "/"]
Home,
} }

View file

@ -4,9 +4,9 @@ mod callout;
mod collapse; mod collapse;
mod example; mod example;
mod icon; mod icon;
mod progressbar;
mod switch; mod switch;
mod tree; mod tree;
mod progressbar;
pub use app::*; pub use app::*;
pub use example::*; pub use example::*;

View file

@ -1,43 +1,43 @@
use yew::prelude::*; use yew::prelude::*;
use yewprint::{ProgressBar, Intent}; use yewprint::{Intent, ProgressBar};
pub struct Example { pub struct Example {
props: ExampleProps, props: ExampleProps,
} }
#[derive(Clone, PartialEq, Properties)] #[derive(Clone, PartialEq, Properties)]
pub struct ExampleProps { pub struct ExampleProps {
pub intent: Option<Intent>, pub intent: Option<Intent>,
pub animate: bool, pub animate: bool,
pub stripes: bool, pub stripes: bool,
} }
impl Component for Example { impl Component for Example {
type Message = (); type Message = ();
type Properties = ExampleProps; type Properties = ExampleProps;
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self { fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
Example { props } Example { props }
} }
fn update(&mut self, _msg: Self::Message) -> ShouldRender { fn update(&mut self, _msg: Self::Message) -> ShouldRender {
true true
} }
fn change(&mut self, props: Self::Properties) -> ShouldRender { fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != props { if self.props != props {
self.props = props; self.props = props;
true true
} else { } else {
false false
} }
} }
fn view(&self) -> Html { fn view(&self) -> Html {
html! { html! {
<ProgressBar <ProgressBar
animate=self.props.animate animate=self.props.animate
stripes=self.props.stripes stripes=self.props.stripes
intent=self.props.intent intent=self.props.intent
value=0.3 value=0.3
/> />
} }
} }
} }

View file

@ -1,133 +1,132 @@
mod example; mod example;
use crate::ExampleContainer; use crate::ExampleContainer;
use example::*; use example::*;
use yew::prelude::*; use yew::prelude::*;
use yewprint::{Intent, Menu, MenuItem, Switch, H1, H5}; use yewprint::{Intent, Menu, MenuItem, Switch, H1, H5};
pub struct ProgressBarDoc {
pub struct ProgressBarDoc { callback: Callback<ExampleProps>,
callback: Callback<ExampleProps>, state: ExampleProps,
state: ExampleProps, }
}
impl Component for ProgressBarDoc {
impl Component for ProgressBarDoc { type Message = ExampleProps;
type Message = ExampleProps; type Properties = ();
type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self { ProgressBarDoc {
ProgressBarDoc { callback: link.callback(|x| x),
callback: link.callback(|x| x), state: ExampleProps {
state: ExampleProps { intent: None,
intent: None, animate: false,
animate: false, stripes: false,
stripes: false },
}, }
} }
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
fn update(&mut self, msg: Self::Message) -> ShouldRender { self.state = msg;
self.state = msg; true
true }
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
fn change(&mut self, _props: Self::Properties) -> ShouldRender { true
true }
}
fn view(&self) -> Html {
fn view(&self) -> Html { let example_props = self.state.clone();
let example_props = self.state.clone(); let source = crate::include_raw_html!(
let source = crate::include_raw_html!( concat!(env!("OUT_DIR"), "/", file!(), ".html"),
concat!(env!("OUT_DIR"), "/", file!(), ".html"), "bp3-code-block"
"bp3-code-block" );
);
html! {
html! { <div>
<div> <H1 class="docs-title">{"ProgressBar"}</H1>
<H1 class="docs-title">{"ProgressBar"}</H1> <ExampleContainer
<ExampleContainer source=source
source=source props=Some(html! {
props=Some(html! { <ProgressBarProps
<ProgressBarProps callback={self.callback.clone()}
callback={self.callback.clone()} props=example_props.clone()
props=example_props.clone() />
/> })
}) >
> <Example with example_props />
<Example with example_props /> </ExampleContainer>
</ExampleContainer> </div>
</div> }
} }
} }
}
crate::build_example_prop_component! {
crate::build_example_prop_component! { ProgressBarProps for ExampleProps =>
ProgressBarProps for ExampleProps => fn view(&self) -> Html {
fn view(&self) -> Html { html! {
html! { <div>
<div> <H5>{"Props"}</H5>
<H5>{"Props"}</H5> <div>
<div> <Switch
<Switch onclick=self.update_props(|props| ExampleProps {
onclick=self.update_props(|props| ExampleProps { stripes: !props.stripes,
stripes: !props.stripes, ..props
..props })
}) checked=self.props.stripes
checked=self.props.stripes label="Stripes"
label="Stripes" />
/> <Switch
<Switch onclick=self.update_props(|props| ExampleProps {
onclick=self.update_props(|props| ExampleProps { animate: !props.animate,
animate: !props.animate, ..props
..props })
}) checked=self.props.animate
checked=self.props.animate label="animate"
label="animate" />
/> <p>{"Select intent:"}</p>
<p>{"Select intent:"}</p> <Menu>
<Menu> <MenuItem
<MenuItem onclick=self.update_props(|props| ExampleProps {
onclick=self.update_props(|props| ExampleProps { intent: None,
intent: None, ..props
..props })
}) text=html!{"None"}
text=html!{"None"} />
/> <MenuItem
<MenuItem onclick=self.update_props(|props| ExampleProps {
onclick=self.update_props(|props| ExampleProps { intent: Some(Intent::Primary),
intent: Some(Intent::Primary), ..props
..props })
}) text=html!{"Primary"}
text=html!{"Primary"} intent=Intent::Primary
intent=Intent::Primary />
/> <MenuItem
<MenuItem onclick=self.update_props(|props| ExampleProps {
onclick=self.update_props(|props| ExampleProps { intent: Some(Intent::Success),
intent: Some(Intent::Success), ..props
..props })
}) text=html!{"Success"}
text=html!{"Success"} intent=Intent::Success
intent=Intent::Success />
/> <MenuItem
<MenuItem onclick=self.update_props(|props| ExampleProps {
onclick=self.update_props(|props| ExampleProps { intent: Some(Intent::Warning),
intent: Some(Intent::Warning), ..props
..props })
}) text=html!{"Warning"}
text=html!{"Warning"} intent=Intent::Warning
intent=Intent::Warning />
/> <MenuItem
<MenuItem onclick=self.update_props(|props| ExampleProps {
onclick=self.update_props(|props| ExampleProps { intent: Some(Intent::Danger),
intent: Some(Intent::Danger), ..props
..props })
}) text=html!{"Danger"}
text=html!{"Danger"} intent=Intent::Danger
intent=Intent::Danger />
/> </Menu>
</Menu> </div>
</div> </div>
</div> }
} }
} }
}

View file

@ -1,63 +1,63 @@
use crate::{ConditionalClass, Intent}; use crate::{ConditionalClass, Intent};
use yew::prelude::*; use yew::prelude::*;
pub struct ProgressBar { pub struct ProgressBar {
props: Props, props: Props,
} }
#[derive(Clone, PartialEq, Properties)] #[derive(Clone, PartialEq, Properties)]
pub struct Props { pub struct Props {
#[prop_or_default] #[prop_or_default]
pub animate: ConditionalClass, pub animate: ConditionalClass,
#[prop_or_default] #[prop_or_default]
pub stripes: ConditionalClass, pub stripes: ConditionalClass,
#[prop_or_default] #[prop_or_default]
pub value: Option<f32>, pub value: Option<f32>,
#[prop_or_default] #[prop_or_default]
pub intent: Option<Intent>, pub intent: Option<Intent>,
} }
impl Component for ProgressBar { impl Component for ProgressBar {
type Message = (); type Message = ();
type Properties = Props; type Properties = Props;
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self { fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
Self { props } Self { props }
} }
fn update(&mut self, _msg: Self::Message) -> ShouldRender { fn update(&mut self, _msg: Self::Message) -> ShouldRender {
true true
} }
fn change(&mut self, props: Self::Properties) -> ShouldRender { fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != props { if self.props != props {
self.props = props; self.props = props;
true true
} else { } else {
false false
} }
} }
fn view(&self) -> Html { fn view(&self) -> Html {
let width = if let Some(value) = self.props.value { let width = if let Some(value) = self.props.value {
// NOTE: nightly, issue #44095 for f32::clamp // NOTE: nightly, issue #44095 for f32::clamp
// let percent = ((1000. * value).ceil() / 10.).clamp(0.,100.); // let percent = ((1000. * value).ceil() / 10.).clamp(0.,100.);
let percent = ((1000. * value).ceil() / 10.).max(0.).min(100.); let percent = ((1000. * value).ceil() / 10.).max(0.).min(100.);
format!("width: {}%;", percent) format!("width: {}%;", percent)
} else { } else {
"".into() "".into()
}; };
html! { html! {
<div <div
class=( class=(
"bp3-progress-bar", "bp3-progress-bar",
self.props.intent, self.props.intent,
(!self.props.animate).map_some("bp3-no-animation"), (!self.props.animate).map_some("bp3-no-animation"),
(!self.props.stripes).map_some("bp3-no-stripes") (!self.props.stripes).map_some("bp3-no-stripes")
) )
> >
<div class="bp3-progress-meter" style={{width}}/> <div class="bp3-progress-meter" style={{width}}/>
</div> </div>
} }
} }
} }