diff --git a/README.md b/README.md index 720760f..15dda34 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Roadmap - [ ] [Navbar](https://blueprintjs.com/docs/#core/components/navbar) - [ ] [OverflowList](https://blueprintjs.com/docs/#core/components/overflow-list) - [ ] [PanelStack](https://blueprintjs.com/docs/#core/components/panel-stack) - - [ ] [ProgressBar](https://blueprintjs.com/docs/#core/components/progress-bar) + - [x] [ProgressBar](https://blueprintjs.com/docs/#core/components/progress-bar) - [ ] [ResizeSensor](https://blueprintjs.com/docs/#core/components/resize-sensor) - [ ] [Skeleton](https://blueprintjs.com/docs/#core/components/skeleton) - [ ] [Spinner](https://blueprintjs.com/docs/#core/components/spinner) @@ -131,5 +131,5 @@ Roadmap - [ ] [MultiSelect](https://blueprintjs.com/docs/#select/multi-select) - [ ] [Omnibar](https://blueprintjs.com/docs/#select/omnibar) - [ ] [QueryList](https://blueprintjs.com/docs/#select/query-list) - - [ ] [Table](https://blueprintjs.com/docs/#select/query-list) + - [ ] [Table](https://blueprintjs.com/docs/#table) - [ ] [TimezonePicker](https://blueprintjs.com/docs/#timezone) diff --git a/yewprint-doc/src/app.rs b/yewprint-doc/src/app.rs index 69aa49d..dc77afa 100644 --- a/yewprint-doc/src/app.rs +++ b/yewprint-doc/src/app.rs @@ -4,6 +4,8 @@ use crate::collapse::*; use crate::icon::*; use crate::switch::*; use crate::tree::*; +use crate::progressbar::*; + use yew::prelude::*; use yewprint::{ConditionalClass, IconName, Menu, MenuItem}; @@ -123,6 +125,10 @@ impl Component for App { text={html!("Tree")} onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tree)) /> +
@@ -147,6 +153,7 @@ impl Component for App { DocMenu::Collapse => html!(), DocMenu::Tree => html!(), DocMenu::Icon => html!(), + DocMenu::ProgressBar => html!(), DocMenu::Menu => html!(), } } @@ -167,4 +174,5 @@ pub enum DocMenu { Menu, Switch, Tree, + ProgressBar, } diff --git a/yewprint-doc/src/lib.rs b/yewprint-doc/src/lib.rs index 45bf960..4f1101a 100644 --- a/yewprint-doc/src/lib.rs +++ b/yewprint-doc/src/lib.rs @@ -6,6 +6,7 @@ mod example; mod icon; mod switch; mod tree; +mod progressbar; pub use app::*; pub use example::*; diff --git a/yewprint-doc/src/progressbar/example.rs b/yewprint-doc/src/progressbar/example.rs new file mode 100644 index 0000000..2ed7d74 --- /dev/null +++ b/yewprint-doc/src/progressbar/example.rs @@ -0,0 +1,43 @@ +use yew::prelude::*; +use yewprint::{ProgressBar, Intent}; + +pub struct Example { + props: ExampleProps, +} + +#[derive(Clone, PartialEq, Properties)] +pub struct ExampleProps { + pub intent: Option, + pub animate: bool, + pub stripes: bool, +} + +impl Component for Example { + type Message = (); + type Properties = ExampleProps; + + fn create(props: Self::Properties, _link: ComponentLink) -> Self { + Example { props } + } + fn update(&mut self, _msg: Self::Message) -> 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! { + + } + } +} diff --git a/yewprint-doc/src/progressbar/mod.rs b/yewprint-doc/src/progressbar/mod.rs new file mode 100644 index 0000000..254893e --- /dev/null +++ b/yewprint-doc/src/progressbar/mod.rs @@ -0,0 +1,133 @@ +mod example; + +use crate::ExampleContainer; +use example::*; +use yew::prelude::*; +use yewprint::{Intent, Menu, MenuItem, Switch, H1, H5}; + + +pub struct ProgressBarDoc { + callback: Callback, + state: ExampleProps, +} + +impl Component for ProgressBarDoc { + type Message = ExampleProps; + type Properties = (); + + fn create(_: Self::Properties, link: ComponentLink) -> Self { + ProgressBarDoc { + callback: link.callback(|x| x), + state: ExampleProps { + intent: None, + animate: false, + stripes: false + }, + } + } + + fn update(&mut self, msg: Self::Message) -> ShouldRender { + self.state = msg; + true + } + + fn change(&mut self, _props: Self::Properties) -> ShouldRender { + true + } + + fn view(&self) -> Html { + let example_props = self.state.clone(); + let source = crate::include_raw_html!( + concat!(env!("OUT_DIR"), "/", file!(), ".html"), + "bp3-code-block" + ); + + html! { +
+

{"ProgressBar"}

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

{"Select intent:"}

+ + + + + + + +
+
+ } + } +} diff --git a/yewprint/src/lib.rs b/yewprint/src/lib.rs index 8a1e3b4..cd1fb86 100644 --- a/yewprint/src/lib.rs +++ b/yewprint/src/lib.rs @@ -4,6 +4,7 @@ mod collapse; mod html_elements; mod icon; mod menu; +mod progressbar; mod switch; mod tree; @@ -14,10 +15,11 @@ pub use html_elements::*; pub use icon::*; pub use id_tree; pub use menu::*; +pub use progressbar::*; pub use switch::*; pub use tree::*; -use std::ops::{Deref, DerefMut}; +use std::ops::{Deref, DerefMut, Not}; use yew::virtual_dom::{Classes, Transformer, VComp}; // NOTE: this class needs to become deprecated when the feature bool_to_option lands in stable @@ -68,6 +70,14 @@ impl DerefMut for ConditionalClass { } } +impl Not for ConditionalClass { + type Output = ConditionalClass; + + fn not(self) -> Self::Output { + ConditionalClass(!self.0) + } +} + #[derive(Debug, Copy, Clone, PartialEq)] pub enum Intent { Primary, diff --git a/yewprint/src/progressbar.rs b/yewprint/src/progressbar.rs new file mode 100644 index 0000000..88b0c57 --- /dev/null +++ b/yewprint/src/progressbar.rs @@ -0,0 +1,63 @@ +use crate::{ConditionalClass, Intent}; +use yew::prelude::*; + +pub struct ProgressBar { + props: Props, +} + +#[derive(Clone, PartialEq, Properties)] +pub struct Props { + #[prop_or_default] + pub animate: ConditionalClass, + #[prop_or_default] + pub stripes: ConditionalClass, + #[prop_or_default] + pub value: Option, + #[prop_or_default] + pub intent: Option, +} + +impl Component for ProgressBar { + type Message = (); + type Properties = Props; + + fn create(props: Self::Properties, _link: ComponentLink) -> Self { + Self { props } + } + + fn update(&mut self, _msg: Self::Message) -> 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 width = if let Some(value) = self.props.value { + // NOTE: nightly, issue #44095 for f32::clamp + // let percent = ((1000. * value).ceil() / 10.).clamp(0.,100.); + let percent = ((1000. * value).ceil() / 10.).max(0.).min(100.); + format!("width: {}%;", percent) + } else { + "".into() + }; + html! { +
+
+
+ } + } +}