mirror of
https://github.com/yewprint/yewprint
synced 2024-11-22 03:23:03 +00:00
Progressbar (#27)
This commit is contained in:
parent
20a39e8107
commit
e433e11db7
7 changed files with 261 additions and 3 deletions
|
@ -79,7 +79,7 @@ Roadmap
|
||||||
- [ ] [Navbar](https://blueprintjs.com/docs/#core/components/navbar)
|
- [ ] [Navbar](https://blueprintjs.com/docs/#core/components/navbar)
|
||||||
- [ ] [OverflowList](https://blueprintjs.com/docs/#core/components/overflow-list)
|
- [ ] [OverflowList](https://blueprintjs.com/docs/#core/components/overflow-list)
|
||||||
- [ ] [PanelStack](https://blueprintjs.com/docs/#core/components/panel-stack)
|
- [ ] [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)
|
- [ ] [ResizeSensor](https://blueprintjs.com/docs/#core/components/resize-sensor)
|
||||||
- [ ] [Skeleton](https://blueprintjs.com/docs/#core/components/skeleton)
|
- [ ] [Skeleton](https://blueprintjs.com/docs/#core/components/skeleton)
|
||||||
- [ ] [Spinner](https://blueprintjs.com/docs/#core/components/spinner)
|
- [ ] [Spinner](https://blueprintjs.com/docs/#core/components/spinner)
|
||||||
|
@ -131,5 +131,5 @@ Roadmap
|
||||||
- [ ] [MultiSelect](https://blueprintjs.com/docs/#select/multi-select)
|
- [ ] [MultiSelect](https://blueprintjs.com/docs/#select/multi-select)
|
||||||
- [ ] [Omnibar](https://blueprintjs.com/docs/#select/omnibar)
|
- [ ] [Omnibar](https://blueprintjs.com/docs/#select/omnibar)
|
||||||
- [ ] [QueryList](https://blueprintjs.com/docs/#select/query-list)
|
- [ ] [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)
|
- [ ] [TimezonePicker](https://blueprintjs.com/docs/#timezone)
|
||||||
|
|
|
@ -4,6 +4,8 @@ use crate::collapse::*;
|
||||||
use crate::icon::*;
|
use crate::icon::*;
|
||||||
use crate::switch::*;
|
use crate::switch::*;
|
||||||
use crate::tree::*;
|
use crate::tree::*;
|
||||||
|
use crate::progressbar::*;
|
||||||
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yewprint::{ConditionalClass, IconName, Menu, MenuItem};
|
use yewprint::{ConditionalClass, IconName, Menu, MenuItem};
|
||||||
|
|
||||||
|
@ -123,6 +125,10 @@ impl Component for App {
|
||||||
text={html!("Tree")}
|
text={html!("Tree")}
|
||||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tree))
|
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tree))
|
||||||
/>
|
/>
|
||||||
|
<MenuItem
|
||||||
|
text={html!("ProgressBar")}
|
||||||
|
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::ProgressBar))
|
||||||
|
/>
|
||||||
</Menu>
|
</Menu>
|
||||||
<div class="docs-nav-sponsors">
|
<div class="docs-nav-sponsors">
|
||||||
<a href="https://www.netlify.com">
|
<a href="https://www.netlify.com">
|
||||||
|
@ -147,6 +153,7 @@ impl Component for App {
|
||||||
DocMenu::Collapse => html!(<CollapseDoc />),
|
DocMenu::Collapse => html!(<CollapseDoc />),
|
||||||
DocMenu::Tree => html!(<TreeDoc />),
|
DocMenu::Tree => html!(<TreeDoc />),
|
||||||
DocMenu::Icon => html!(<IconDoc />),
|
DocMenu::Icon => html!(<IconDoc />),
|
||||||
|
DocMenu::ProgressBar => html!(<ProgressBarDoc />),
|
||||||
DocMenu::Menu => html!(),
|
DocMenu::Menu => html!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,4 +174,5 @@ pub enum DocMenu {
|
||||||
Menu,
|
Menu,
|
||||||
Switch,
|
Switch,
|
||||||
Tree,
|
Tree,
|
||||||
|
ProgressBar,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ mod example;
|
||||||
mod icon;
|
mod icon;
|
||||||
mod switch;
|
mod switch;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
mod progressbar;
|
||||||
|
|
||||||
pub use app::*;
|
pub use app::*;
|
||||||
pub use example::*;
|
pub use example::*;
|
||||||
|
|
43
yewprint-doc/src/progressbar/example.rs
Normal file
43
yewprint-doc/src/progressbar/example.rs
Normal file
|
@ -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<Intent>,
|
||||||
|
pub animate: bool,
|
||||||
|
pub stripes: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for Example {
|
||||||
|
type Message = ();
|
||||||
|
type Properties = ExampleProps;
|
||||||
|
|
||||||
|
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> 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! {
|
||||||
|
<ProgressBar
|
||||||
|
animate=self.props.animate
|
||||||
|
stripes=self.props.stripes
|
||||||
|
intent=self.props.intent
|
||||||
|
value=0.3
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
133
yewprint-doc/src/progressbar/mod.rs
Normal file
133
yewprint-doc/src/progressbar/mod.rs
Normal file
|
@ -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<ExampleProps>,
|
||||||
|
state: ExampleProps,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for ProgressBarDoc {
|
||||||
|
type Message = ExampleProps;
|
||||||
|
type Properties = ();
|
||||||
|
|
||||||
|
fn create(_: Self::Properties, link: ComponentLink<Self>) -> 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! {
|
||||||
|
<div>
|
||||||
|
<H1 class="docs-title">{"ProgressBar"}</H1>
|
||||||
|
<ExampleContainer
|
||||||
|
source=source
|
||||||
|
props=Some(html! {
|
||||||
|
<ProgressBarProps
|
||||||
|
callback={self.callback.clone()}
|
||||||
|
props=example_props.clone()
|
||||||
|
/>
|
||||||
|
})
|
||||||
|
>
|
||||||
|
<Example with example_props />
|
||||||
|
</ExampleContainer>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::build_example_prop_component! {
|
||||||
|
ProgressBarProps for ExampleProps =>
|
||||||
|
fn view(&self) -> Html {
|
||||||
|
html! {
|
||||||
|
<div>
|
||||||
|
<H5>{"Props"}</H5>
|
||||||
|
<div>
|
||||||
|
<Switch
|
||||||
|
onclick=self.update_props(|props| ExampleProps {
|
||||||
|
stripes: !props.stripes,
|
||||||
|
..props
|
||||||
|
})
|
||||||
|
checked=self.props.stripes
|
||||||
|
label="Stripes"
|
||||||
|
/>
|
||||||
|
<Switch
|
||||||
|
onclick=self.update_props(|props| ExampleProps {
|
||||||
|
animate: !props.animate,
|
||||||
|
..props
|
||||||
|
})
|
||||||
|
checked=self.props.animate
|
||||||
|
label="animate"
|
||||||
|
/>
|
||||||
|
<p>{"Select intent:"}</p>
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
onclick=self.update_props(|props| ExampleProps {
|
||||||
|
intent: None,
|
||||||
|
..props
|
||||||
|
})
|
||||||
|
text=html!{"None"}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
onclick=self.update_props(|props| ExampleProps {
|
||||||
|
intent: Some(Intent::Primary),
|
||||||
|
..props
|
||||||
|
})
|
||||||
|
text=html!{"Primary"}
|
||||||
|
intent=Intent::Primary
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
onclick=self.update_props(|props| ExampleProps {
|
||||||
|
intent: Some(Intent::Success),
|
||||||
|
..props
|
||||||
|
})
|
||||||
|
text=html!{"Success"}
|
||||||
|
intent=Intent::Success
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
onclick=self.update_props(|props| ExampleProps {
|
||||||
|
intent: Some(Intent::Warning),
|
||||||
|
..props
|
||||||
|
})
|
||||||
|
text=html!{"Warning"}
|
||||||
|
intent=Intent::Warning
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
onclick=self.update_props(|props| ExampleProps {
|
||||||
|
intent: Some(Intent::Danger),
|
||||||
|
..props
|
||||||
|
})
|
||||||
|
text=html!{"Danger"}
|
||||||
|
intent=Intent::Danger
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ mod collapse;
|
||||||
mod html_elements;
|
mod html_elements;
|
||||||
mod icon;
|
mod icon;
|
||||||
mod menu;
|
mod menu;
|
||||||
|
mod progressbar;
|
||||||
mod switch;
|
mod switch;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
|
||||||
|
@ -14,10 +15,11 @@ pub use html_elements::*;
|
||||||
pub use icon::*;
|
pub use icon::*;
|
||||||
pub use id_tree;
|
pub use id_tree;
|
||||||
pub use menu::*;
|
pub use menu::*;
|
||||||
|
pub use progressbar::*;
|
||||||
pub use switch::*;
|
pub use switch::*;
|
||||||
pub use tree::*;
|
pub use tree::*;
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut, Not};
|
||||||
use yew::virtual_dom::{Classes, Transformer, VComp};
|
use yew::virtual_dom::{Classes, Transformer, VComp};
|
||||||
|
|
||||||
// NOTE: this class needs to become deprecated when the feature bool_to_option lands in stable
|
// 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)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub enum Intent {
|
pub enum Intent {
|
||||||
Primary,
|
Primary,
|
||||||
|
|
63
yewprint/src/progressbar.rs
Normal file
63
yewprint/src/progressbar.rs
Normal file
|
@ -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<f32>,
|
||||||
|
#[prop_or_default]
|
||||||
|
pub intent: Option<Intent>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for ProgressBar {
|
||||||
|
type Message = ();
|
||||||
|
type Properties = Props;
|
||||||
|
|
||||||
|
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> 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! {
|
||||||
|
<div
|
||||||
|
class=(
|
||||||
|
"bp3-progress-bar",
|
||||||
|
self.props.intent,
|
||||||
|
(!self.props.animate).map_some("bp3-no-animation"),
|
||||||
|
(!self.props.stripes).map_some("bp3-no-stripes")
|
||||||
|
)
|
||||||
|
>
|
||||||
|
<div class="bp3-progress-meter" style={{width}}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue