Implements Text component with doc example (#40)

This commit is contained in:
Benoit Chassignol 2020-10-02 18:44:32 +02:00 committed by GitHub
parent 3149778317
commit 8fdd788d24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 233 additions and 26 deletions

View file

@ -4,6 +4,7 @@ use crate::card::*;
use crate::collapse::*; use crate::collapse::*;
use crate::icon::*; use crate::icon::*;
use crate::progressbar::*; use crate::progressbar::*;
use crate::text::*;
use crate::tree::*; use crate::tree::*;
use yew::prelude::*; use yew::prelude::*;
@ -137,6 +138,11 @@ impl Component for App {
text={html!("Switch")} text={html!("Switch")}
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Switch)) onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Switch))
/> />
<MenuItem
text={html!("Text")}
onclick=self.link
.callback(|_| Msg::GoToMenu(DocMenu::Text))
/>
<MenuItem <MenuItem
text={html!("Tree")} text={html!("Tree")}
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tree)) onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tree))
@ -164,6 +170,7 @@ impl Component for App {
DocMenu::Callout => html!(<CalloutDoc />), DocMenu::Callout => html!(<CalloutDoc />),
DocMenu::Card => html!(<CardDoc />), DocMenu::Card => html!(<CardDoc />),
DocMenu::Collapse => html!(<CollapseDoc />), DocMenu::Collapse => html!(<CollapseDoc />),
DocMenu::Text => html!(<TextDoc />),
DocMenu::Tree => html!(<TreeDoc />), DocMenu::Tree => html!(<TreeDoc />),
DocMenu::Icon => html!(<IconDoc />), DocMenu::Icon => html!(<IconDoc />),
DocMenu::ProgressBar => html!(<ProgressBarDoc />), DocMenu::ProgressBar => html!(<ProgressBarDoc />),
@ -197,6 +204,8 @@ pub enum DocMenu {
ProgressBar, ProgressBar,
#[to = "/#switch"] #[to = "/#switch"]
Switch, Switch,
#[to = "/#text"]
Text,
#[to = "/#tree"] #[to = "/#tree"]
Tree, Tree,
#[to = "/"] #[to = "/"]

View file

@ -68,7 +68,7 @@ crate::build_example_prop_component! {
<div> <div>
<H5>{"Props"}</H5> <H5>{"Props"}</H5>
<Switch <Switch
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
minimal: !props.minimal, minimal: !props.minimal,
..props ..props
}) })
@ -76,7 +76,7 @@ crate::build_example_prop_component! {
label="Minimal" label="Minimal"
/> />
<Switch <Switch
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
fill: !props.fill, fill: !props.fill,
..props ..props
}) })

View file

@ -68,7 +68,7 @@ crate::build_example_prop_component! {
<H5>{"Props"}</H5> <H5>{"Props"}</H5>
<div> <div>
<Switch <Switch
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
show_icon: !props.show_icon, show_icon: !props.show_icon,
..props ..props
}) })
@ -76,7 +76,7 @@ crate::build_example_prop_component! {
label="Show/hide icon" label="Show/hide icon"
/> />
<Switch <Switch
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
show_title: !props.show_title, show_title: !props.show_title,
..props ..props
}) })
@ -86,14 +86,14 @@ crate::build_example_prop_component! {
<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
}) })
@ -101,7 +101,7 @@ crate::build_example_prop_component! {
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
}) })
@ -109,7 +109,7 @@ crate::build_example_prop_component! {
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
}) })
@ -117,7 +117,7 @@ crate::build_example_prop_component! {
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
}) })

View file

@ -67,7 +67,7 @@ crate::build_example_prop_component! {
<H5>{"Props"}</H5> <H5>{"Props"}</H5>
<div> <div>
<Switch <Switch
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
interactive: !props.interactive, interactive: !props.interactive,
..props ..props
}) })
@ -77,35 +77,35 @@ crate::build_example_prop_component! {
<p>{"Elevation:"}</p> <p>{"Elevation:"}</p>
<Menu> <Menu>
<MenuItem <MenuItem
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
elevation: Elevation::Level0, elevation: Elevation::Level0,
..props ..props
}) })
text=html!{"Level 0"} text=html!{"Level 0"}
/> />
<MenuItem <MenuItem
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
elevation: Elevation::Level1, elevation: Elevation::Level1,
..props ..props
}) })
text=html!{"Level 1"} text=html!{"Level 1"}
/> />
<MenuItem <MenuItem
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
elevation: Elevation::Level2, elevation: Elevation::Level2,
..props ..props
}) })
text=html!{"Level 2"} text=html!{"Level 2"}
/> />
<MenuItem <MenuItem
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
elevation: Elevation::Level3, elevation: Elevation::Level3,
..props ..props
}) })
text=html!{"Level 3"} text=html!{"Level 3"}
/> />
<MenuItem <MenuItem
onclick=self.update_props(|props| ExampleProps { onclick=self.update_props(|props, _| ExampleProps {
elevation: Elevation::Level4, elevation: Elevation::Level4,
..props ..props
}) })

View file

@ -123,12 +123,12 @@ macro_rules! build_example_prop_component {
} }
impl $name { impl $name {
fn update_props( fn update_props<T>(
&self, &self,
updater: impl Fn($prop_component) -> $prop_component + 'static, updater: impl Fn($prop_component, T) -> $prop_component + 'static,
) -> Callback<MouseEvent> { ) -> Callback<T> {
let props = self.props.clone(); let props = self.props.clone();
self.callback.clone().reform(move |_| updater(props.clone())) self.callback.clone().reform(move |event| updater(props.clone(), event))
} }
} }
}; };

View file

@ -7,6 +7,7 @@ mod example;
mod icon; mod icon;
mod progressbar; mod progressbar;
mod switch; mod switch;
mod text;
mod tree; mod tree;
pub use app::*; pub use app::*;

View file

@ -68,7 +68,7 @@ crate::build_example_prop_component! {
<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
}) })
@ -76,7 +76,7 @@ crate::build_example_prop_component! {
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
}) })
@ -86,14 +86,14 @@ crate::build_example_prop_component! {
<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
}) })
@ -101,7 +101,7 @@ crate::build_example_prop_component! {
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
}) })
@ -109,7 +109,7 @@ crate::build_example_prop_component! {
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
}) })
@ -117,7 +117,7 @@ crate::build_example_prop_component! {
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
}) })

View file

@ -0,0 +1,45 @@
use yew::prelude::*;
use yewprint::Text;
pub struct Example {
props: ExampleProps,
}
#[derive(Clone, PartialEq, Properties)]
pub struct ExampleProps {
pub ellipsize: bool,
pub text: String,
}
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! {
<div style="width: 150px; height: 20px">
<Text
ellipsize=self.props.ellipsize
text=&self.props.text
/>
</div>
}
}
}

View file

@ -0,0 +1,101 @@
mod example;
use crate::ExampleContainer;
use example::*;
use yew::prelude::*;
use yewprint::{Switch, H1, H5};
pub struct TextDoc {
callback: Callback<ExampleProps>,
state: ExampleProps,
}
impl Component for TextDoc {
type Message = ExampleProps;
type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
TextDoc {
callback: link.callback(|x| x),
state: ExampleProps {
ellipsize: false,
text: String::from("Hello, world!"),
},
}
}
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">{"Text"}</H1>
<div>
<ExampleContainer
source=source
props=Some(html! {
<TextProps
callback={self.callback.clone()}
props=example_props.clone()
/>
})
>
<Example with example_props />
</ExampleContainer>
</div>
</div>
}
}
}
crate::build_example_prop_component! {
TextProps for ExampleProps =>
fn view(&self) -> Html {
html! {
<div>
<H5>{"Props"}</H5>
<Switch
onclick=self.update_props(|props, _| ExampleProps {
ellipsize: !props.ellipsize,
..props
})
checked=self.props.ellipsize
label="Ellipsize"
/>
<input
class="bp3-input"
onchange=self.update_props(|props, e|
match e {
ChangeData::Value(text) => {
ExampleProps {
text,
..props
}
},
_ => {
ExampleProps {
text: "Hello, world!".to_string(),
..props
}
}
})
type="text"
value={&self.props.text}
/>
</div>
}
}
}

View file

@ -7,6 +7,7 @@ mod icon;
mod menu; mod menu;
mod progressbar; mod progressbar;
mod switch; mod switch;
mod text;
#[cfg(feature = "tree")] #[cfg(feature = "tree")]
mod tree; mod tree;
@ -21,6 +22,7 @@ pub use id_tree;
pub use menu::*; pub use menu::*;
pub use progressbar::*; pub use progressbar::*;
pub use switch::*; pub use switch::*;
pub use text::*;
#[cfg(feature = "tree")] #[cfg(feature = "tree")]
pub use tree::*; pub use tree::*;

49
yewprint/src/text.rs Normal file
View file

@ -0,0 +1,49 @@
use crate::ConditionalClass;
use yew::prelude::*;
pub struct Text {
props: Props,
}
#[derive(Clone, PartialEq, Properties)]
pub struct Props {
#[prop_or_default]
pub ellipsize: ConditionalClass,
#[prop_or_default]
pub text: String,
}
impl Component for Text {
type Message = ();
type Properties = Props;
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
Text { 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! {
<p
class=(
"bp3-text",
self.props.ellipsize.map_some("bp3-text-overflow-ellipsis"),
)
>
{self.props.text.clone()}
</p>
}
}
}