mirror of
https://github.com/yewprint/yewprint
synced 2024-11-22 03:23:03 +00:00
Input group & Control group (#68)
This commit is contained in:
parent
2f8cd1f358
commit
0a0b0b2a94
14 changed files with 607 additions and 41 deletions
2
build.sh
2
build.sh
|
@ -7,7 +7,7 @@ else
|
|||
fi
|
||||
|
||||
if ! [ -f core.tgz ]; then
|
||||
curl -o core.tgz https://registry.npmjs.org/@blueprintjs/core/-/core-3.30.0.tgz
|
||||
curl -o core.tgz https://registry.npmjs.org/@blueprintjs/core/-/core-3.36.0.tgz
|
||||
fi
|
||||
|
||||
if ! [ -f docs-theme.tgz ]; then
|
||||
|
|
|
@ -3,9 +3,11 @@ use crate::buttons::*;
|
|||
use crate::callout::*;
|
||||
use crate::card::*;
|
||||
use crate::collapse::*;
|
||||
use crate::control_group::*;
|
||||
use crate::divider::*;
|
||||
use crate::html_select::*;
|
||||
use crate::icon::*;
|
||||
use crate::input_group::*;
|
||||
use crate::menu::*;
|
||||
use crate::progressbar::*;
|
||||
use crate::switch::*;
|
||||
|
@ -105,13 +107,15 @@ impl Component for App {
|
|||
<Menu>
|
||||
<MenuItem
|
||||
text={html!(go_to_theme_label)}
|
||||
onclick=self.link.callback(|_| Msg::ToggleLight)
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::ToggleLight)
|
||||
icon=go_to_theme_icon
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Button")}
|
||||
href="#button"
|
||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Button))
|
||||
text={html!("Button")}
|
||||
href="#button"
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Button))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("ButtonGroup")}
|
||||
|
@ -137,6 +141,12 @@ impl Component for App {
|
|||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Collapse))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("ControlGroup")}
|
||||
href="#control-group"
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::ControlGroup))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Divider")}
|
||||
href="#divider"
|
||||
|
@ -145,18 +155,27 @@ impl Component for App {
|
|||
/>
|
||||
<MenuItem
|
||||
text={html!("HtmlSelect")}
|
||||
href="#html-select"
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::HtmlSelect))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Icon")}
|
||||
href="#icon"
|
||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Icon))
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Icon))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("InputGroup")}
|
||||
href="#input-group"
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::InputGroup))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Menu")}
|
||||
href="#menu"
|
||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Menu))
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Menu))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("ProgressBar")}
|
||||
|
@ -167,17 +186,20 @@ impl Component for App {
|
|||
<MenuItem
|
||||
text={html!("Switch")}
|
||||
href="#switch"
|
||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Switch))
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Switch))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Tabs")}
|
||||
href="#tabs"
|
||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tabs))
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Tabs))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Tag")}
|
||||
href="#tag"
|
||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tag))
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Tag))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Text")}
|
||||
|
@ -188,7 +210,8 @@ impl Component for App {
|
|||
<MenuItem
|
||||
text={html!("Tree")}
|
||||
href="#tree"
|
||||
onclick=self.link.callback(|_| Msg::GoToMenu(DocMenu::Tree))
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Tree))
|
||||
/>
|
||||
// NOTE: thanks to keep this list of <MenuItem> sorted
|
||||
// alphabetically (except for the light switch)
|
||||
|
@ -213,16 +236,18 @@ impl Component for App {
|
|||
DocMenu::Callout => html!(<CalloutDoc />),
|
||||
DocMenu::Card => html!(<CardDoc />),
|
||||
DocMenu::Collapse => html!(<CollapseDoc />),
|
||||
DocMenu::HtmlSelect => html!(<HtmlSelectDoc />),
|
||||
DocMenu::Text => html!(<TextDoc />),
|
||||
DocMenu::ControlGroup => html!(<ControlGroupDoc />),
|
||||
DocMenu::Divider => html!(<DividerDoc />),
|
||||
DocMenu::Tree => html!(<TreeDoc />),
|
||||
DocMenu::HtmlSelect => html!(<HtmlSelectDoc />),
|
||||
DocMenu::Icon => html!(<IconDoc />),
|
||||
DocMenu::InputGroup => html!(<InputGroupDoc />),
|
||||
DocMenu::Menu => html!(<MenuDoc />),
|
||||
DocMenu::ProgressBar => html!(<ProgressBarDoc />),
|
||||
DocMenu::Switch => html!(<SwitchDoc />),
|
||||
DocMenu::Tabs => html!(<TabsDoc />),
|
||||
DocMenu::Tag => html!(<TagDoc />),
|
||||
DocMenu::Menu => html!(<MenuDoc />),
|
||||
DocMenu::Text => html!(<TextDoc />),
|
||||
DocMenu::Tree => html!(<TreeDoc />),
|
||||
}
|
||||
})
|
||||
/>
|
||||
|
@ -246,12 +271,16 @@ pub enum DocMenu {
|
|||
Card,
|
||||
#[to = "/#collapse"]
|
||||
Collapse,
|
||||
#[to = "/#control-group"]
|
||||
ControlGroup,
|
||||
#[to = "/#html-select"]
|
||||
HtmlSelect,
|
||||
#[to = "/#divider"]
|
||||
Divider,
|
||||
#[to = "/#icon"]
|
||||
Icon,
|
||||
#[to = "/#input-group"]
|
||||
InputGroup,
|
||||
#[to = "/#menu"]
|
||||
Menu,
|
||||
#[to = "/#progress-bar"]
|
||||
|
|
|
@ -11,6 +11,7 @@ pub struct Example {
|
|||
pub struct ExampleProps {
|
||||
pub minimal: bool,
|
||||
pub fill: bool,
|
||||
pub disabled: bool,
|
||||
}
|
||||
|
||||
pub enum Msg {
|
||||
|
@ -54,6 +55,7 @@ impl Component for Example {
|
|||
onclick=self.link.callback(|_| Msg::AddOne)
|
||||
minimal=self.props.minimal
|
||||
fill=self.props.fill
|
||||
disabled=self.props.disabled
|
||||
>
|
||||
{"Add 1"}
|
||||
</Button>
|
||||
|
|
|
@ -20,6 +20,7 @@ impl Component for ButtonDoc {
|
|||
state: ExampleProps {
|
||||
minimal: false,
|
||||
fill: false,
|
||||
disabled: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -63,27 +64,35 @@ impl Component for ButtonDoc {
|
|||
|
||||
crate::build_example_prop_component! {
|
||||
ButtonProps for ExampleProps =>
|
||||
fn view(&self) -> Html {
|
||||
html! {
|
||||
<div>
|
||||
<H5>{"Props"}</H5>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
minimal: !props.minimal,
|
||||
..props
|
||||
})
|
||||
checked=self.props.minimal
|
||||
label=html!("Minimal")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
fill: !props.fill,
|
||||
..props
|
||||
})
|
||||
checked=self.props.fill
|
||||
label=html!("Fill")
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
fn view(&self) -> Html {
|
||||
html! {
|
||||
<div>
|
||||
<H5>{"Props"}</H5>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
minimal: !props.minimal,
|
||||
..props
|
||||
})
|
||||
checked=self.props.minimal
|
||||
label=html!("Minimal")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
fill: !props.fill,
|
||||
..props
|
||||
})
|
||||
checked=self.props.fill
|
||||
label=html!("Fill")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
disabled: !props.disabled,
|
||||
..props
|
||||
})
|
||||
checked=self.props.disabled
|
||||
label=html!("Disabled")
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
63
yewprint-doc/src/control_group/example.rs
Normal file
63
yewprint-doc/src/control_group/example.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use yew::prelude::*;
|
||||
use yewprint::{Button, ControlGroup, HtmlSelect, IconName, InputGroup};
|
||||
|
||||
pub struct Example {
|
||||
props: ExampleProps,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct ExampleProps {
|
||||
pub fill: bool,
|
||||
pub vertical: 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! {
|
||||
<ControlGroup
|
||||
fill=self.props.fill
|
||||
vertical=self.props.vertical
|
||||
>
|
||||
<HtmlSelect<Option<Sorting>>
|
||||
options={vec![
|
||||
(None, "Filter".to_string()),
|
||||
(Some(Sorting::NameAscending), "Name - ascending".to_string()),
|
||||
(Some(Sorting::NameDescending), "Name - descending".to_string()),
|
||||
(Some(Sorting::PriceAscending), "Price - ascending".to_string()),
|
||||
(Some(Sorting::PriceDescending), "Price - descending".to_string()),
|
||||
]}
|
||||
/>
|
||||
<InputGroup placeholder="Find filters..." />
|
||||
<Button icon=IconName::ArrowRight />
|
||||
</ControlGroup>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq)]
|
||||
pub enum Sorting {
|
||||
NameAscending,
|
||||
NameDescending,
|
||||
PriceAscending,
|
||||
PriceDescending,
|
||||
}
|
88
yewprint-doc/src/control_group/mod.rs
Normal file
88
yewprint-doc/src/control_group/mod.rs
Normal file
|
@ -0,0 +1,88 @@
|
|||
mod example;
|
||||
|
||||
use crate::ExampleContainer;
|
||||
use example::*;
|
||||
use yew::prelude::*;
|
||||
use yewprint::{Switch, H1, H5};
|
||||
|
||||
pub struct ControlGroupDoc {
|
||||
callback: Callback<ExampleProps>,
|
||||
state: ExampleProps,
|
||||
}
|
||||
|
||||
impl Component for ControlGroupDoc {
|
||||
type Message = ExampleProps;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
ControlGroupDoc {
|
||||
callback: link.callback(|x| x),
|
||||
state: ExampleProps {
|
||||
fill: false,
|
||||
vertical: 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">{"ControlGroup"}</H1>
|
||||
<ExampleContainer
|
||||
source=source
|
||||
props=Some(html! {
|
||||
<ControlGroupProps
|
||||
callback={self.callback.clone()}
|
||||
props=example_props.clone()
|
||||
>
|
||||
</ControlGroupProps>
|
||||
})
|
||||
>
|
||||
<Example with example_props />
|
||||
</ExampleContainer>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate::build_example_prop_component! {
|
||||
ControlGroupProps for ExampleProps =>
|
||||
fn view(&self) -> Html {
|
||||
html! {
|
||||
<div>
|
||||
<H5>{"Props"}</H5>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
fill: !props.fill,
|
||||
..props
|
||||
})
|
||||
checked=self.props.fill
|
||||
label=html!("Fill")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
vertical: !props.vertical,
|
||||
..props
|
||||
})
|
||||
checked=self.props.vertical
|
||||
label=html!("Vertical")
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
85
yewprint-doc/src/input_group/example.rs
Normal file
85
yewprint-doc/src/input_group/example.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
use yew::prelude::*;
|
||||
use yewprint::{Button, IconName, InputGroup, Tag};
|
||||
|
||||
pub struct Example {
|
||||
props: ExampleProps,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct ExampleProps {
|
||||
pub disabled: bool,
|
||||
pub fill: bool,
|
||||
pub large: bool,
|
||||
pub small: bool,
|
||||
pub round: 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! {
|
||||
<>
|
||||
<InputGroup
|
||||
fill=self.props.fill
|
||||
large=self.props.large
|
||||
small=self.props.small
|
||||
round=self.props.round
|
||||
disabled=self.props.disabled
|
||||
left_icon=IconName::Filter
|
||||
placeholder={"Filter histogram..."}
|
||||
/>
|
||||
<InputGroup
|
||||
fill=self.props.fill
|
||||
large=self.props.large
|
||||
small=self.props.small
|
||||
round=self.props.round
|
||||
disabled=self.props.disabled
|
||||
placeholder={"Enter your password..."}
|
||||
right_element=html! {
|
||||
<Button
|
||||
icon=IconName::Lock
|
||||
minimal=true
|
||||
disabled=self.props.disabled
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<InputGroup
|
||||
fill=self.props.fill
|
||||
large=self.props.large
|
||||
small=self.props.small
|
||||
round=self.props.round
|
||||
disabled=self.props.disabled
|
||||
left_icon=IconName::Tag
|
||||
placeholder={"Find tags"}
|
||||
right_element=html! {
|
||||
<Tag
|
||||
minimal=true
|
||||
round=self.props.round
|
||||
>
|
||||
{"10000"}
|
||||
</Tag>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
}
|
||||
}
|
115
yewprint-doc/src/input_group/mod.rs
Normal file
115
yewprint-doc/src/input_group/mod.rs
Normal file
|
@ -0,0 +1,115 @@
|
|||
mod example;
|
||||
|
||||
use crate::ExampleContainer;
|
||||
use example::*;
|
||||
use yew::prelude::*;
|
||||
use yewprint::{Switch, H1, H5};
|
||||
|
||||
pub struct InputGroupDoc {
|
||||
callback: Callback<ExampleProps>,
|
||||
state: ExampleProps,
|
||||
}
|
||||
|
||||
impl Component for InputGroupDoc {
|
||||
type Message = ExampleProps;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
InputGroupDoc {
|
||||
callback: link.callback(|x| x),
|
||||
state: ExampleProps {
|
||||
disabled: false,
|
||||
fill: false,
|
||||
large: false,
|
||||
small: false,
|
||||
round: 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">{"InputGroup"}</H1>
|
||||
<ExampleContainer
|
||||
source=source
|
||||
props=Some(html! {
|
||||
<InputGroupProps
|
||||
callback={self.callback.clone()}
|
||||
props=example_props.clone()
|
||||
>
|
||||
</InputGroupProps>
|
||||
})
|
||||
>
|
||||
<Example with example_props />
|
||||
</ExampleContainer>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate::build_example_prop_component! {
|
||||
InputGroupProps for ExampleProps =>
|
||||
fn view(&self) -> Html {
|
||||
html! {
|
||||
<div>
|
||||
<H5>{"Props"}</H5>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
disabled: !props.disabled,
|
||||
..props
|
||||
})
|
||||
checked=self.props.disabled
|
||||
label=html!("Disabled")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
fill: !props.fill,
|
||||
..props
|
||||
})
|
||||
checked=self.props.fill
|
||||
label=html!("Fill")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
large: !props.large,
|
||||
..props
|
||||
})
|
||||
checked=self.props.large
|
||||
label=html!("Large")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
small: !props.small,
|
||||
..props
|
||||
})
|
||||
checked=self.props.small
|
||||
label=html!("Small")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
round: !props.round,
|
||||
..props
|
||||
})
|
||||
checked=self.props.round
|
||||
label=html!("Round")
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,10 +4,12 @@ mod buttons;
|
|||
mod callout;
|
||||
mod card;
|
||||
mod collapse;
|
||||
mod control_group;
|
||||
mod divider;
|
||||
mod example;
|
||||
mod html_select;
|
||||
mod icon;
|
||||
mod input_group;
|
||||
mod menu;
|
||||
mod progressbar;
|
||||
mod switch;
|
||||
|
|
|
@ -13,6 +13,8 @@ pub struct Props {
|
|||
#[prop_or_default]
|
||||
pub minimal: bool,
|
||||
#[prop_or_default]
|
||||
pub disabled: bool,
|
||||
#[prop_or_default]
|
||||
pub icon: Option<IconName>,
|
||||
#[prop_or_default]
|
||||
pub intent: Option<Intent>,
|
||||
|
@ -22,6 +24,7 @@ pub struct Props {
|
|||
pub onclick: Callback<MouseEvent>,
|
||||
#[prop_or_default]
|
||||
pub class: String,
|
||||
#[prop_or_default]
|
||||
pub children: html::Children,
|
||||
}
|
||||
|
||||
|
@ -53,6 +56,7 @@ impl Component for Button {
|
|||
"bp3-button",
|
||||
self.props.fill.as_some("bp3-fill"),
|
||||
self.props.minimal.as_some("bp3-minimal"),
|
||||
self.props.disabled.as_some("bp3-disabled"),
|
||||
self.props.intent,
|
||||
self.props.class.clone(),
|
||||
)
|
||||
|
@ -67,9 +71,17 @@ impl Component for Button {
|
|||
html!()
|
||||
}
|
||||
}
|
||||
<span class="bp3-button-text">
|
||||
{self.props.children.clone()}
|
||||
</span>
|
||||
{
|
||||
if self.props.children.is_empty() {
|
||||
html! ()
|
||||
} else {
|
||||
html! {
|
||||
<span class="bp3-button-text">
|
||||
{self.props.children.clone()}
|
||||
</span>
|
||||
}
|
||||
}
|
||||
}
|
||||
</button>
|
||||
}
|
||||
}
|
||||
|
|
52
yewprint/src/control_group.rs
Normal file
52
yewprint/src/control_group.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use boolinator::Boolinator;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct ControlGroup {
|
||||
props: ControlGroupProps,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct ControlGroupProps {
|
||||
#[prop_or_default]
|
||||
pub fill: bool,
|
||||
#[prop_or_default]
|
||||
pub vertical: bool,
|
||||
#[prop_or_default]
|
||||
pub children: html::Children,
|
||||
}
|
||||
|
||||
impl Component for ControlGroup {
|
||||
type Message = ();
|
||||
type Properties = ControlGroupProps;
|
||||
|
||||
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
|
||||
Self { props }
|
||||
}
|
||||
|
||||
fn update(&mut self, _: 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
|
||||
class=(
|
||||
"bp3-control-group",
|
||||
self.props.fill.as_some("bp3-fill"),
|
||||
self.props.vertical.as_some("bp3-vertical"),
|
||||
)
|
||||
>
|
||||
{self.props.children.clone()}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
104
yewprint/src/input_group.rs
Normal file
104
yewprint/src/input_group.rs
Normal file
|
@ -0,0 +1,104 @@
|
|||
use crate::{Icon, IconName};
|
||||
use boolinator::Boolinator;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct InputGroup {
|
||||
props: InputGroupProps,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct InputGroupProps {
|
||||
#[prop_or_default]
|
||||
pub disabled: bool,
|
||||
#[prop_or_default]
|
||||
pub fill: bool,
|
||||
#[prop_or_default]
|
||||
pub large: bool,
|
||||
#[prop_or_default]
|
||||
pub small: bool,
|
||||
#[prop_or_default]
|
||||
pub round: bool,
|
||||
#[prop_or_default]
|
||||
pub placeholder: String,
|
||||
#[prop_or_default]
|
||||
pub left_icon: Option<IconName>,
|
||||
#[prop_or_default]
|
||||
pub left_element: Option<yew::virtual_dom::VNode>,
|
||||
#[prop_or_default]
|
||||
pub right_element: Option<yew::virtual_dom::VNode>,
|
||||
}
|
||||
|
||||
impl Component for InputGroup {
|
||||
type Message = ();
|
||||
type Properties = InputGroupProps;
|
||||
|
||||
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
|
||||
Self { props }
|
||||
}
|
||||
|
||||
fn update(&mut self, _: 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
|
||||
class=(
|
||||
"bp3-input-group",
|
||||
self.props.disabled.as_some("bp3-disabled"),
|
||||
self.props.fill.as_some("bp3-fill"),
|
||||
self.props.large.as_some("bp3-large"),
|
||||
self.props.small.as_some("bp3-small"),
|
||||
self.props.round.as_some("bp3-round"),
|
||||
self.props.placeholder.clone()
|
||||
)
|
||||
>
|
||||
{
|
||||
if let Some(left_element) = self.props.left_element.clone() {
|
||||
html! {
|
||||
<span class="bp3-input-left-container">
|
||||
{left_element}
|
||||
</span>
|
||||
}
|
||||
} else {
|
||||
html!()
|
||||
}
|
||||
}
|
||||
{
|
||||
if let Some(icon) = self.props.left_icon {
|
||||
html! {
|
||||
<Icon icon=icon />
|
||||
}
|
||||
} else {
|
||||
html!()
|
||||
}
|
||||
}
|
||||
<input
|
||||
class="bp3-input"
|
||||
placeholder=&self.props.placeholder
|
||||
disabled=self.props.disabled
|
||||
/>
|
||||
{
|
||||
if let Some(right_element) = self.props.right_element.clone() {
|
||||
html! {
|
||||
<span class="bp3-input-action">
|
||||
{right_element}
|
||||
</span>
|
||||
}
|
||||
} else {
|
||||
html!()
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,10 +3,12 @@ mod buttons;
|
|||
mod callout;
|
||||
mod card;
|
||||
mod collapse;
|
||||
mod control_group;
|
||||
mod divider;
|
||||
mod html_elements;
|
||||
mod html_select;
|
||||
mod icon;
|
||||
mod input_group;
|
||||
mod menu;
|
||||
mod progressbar;
|
||||
mod switch;
|
||||
|
@ -21,12 +23,14 @@ pub use buttons::*;
|
|||
pub use callout::*;
|
||||
pub use card::*;
|
||||
pub use collapse::*;
|
||||
pub use control_group::*;
|
||||
pub use divider::*;
|
||||
pub use html_elements::*;
|
||||
pub use html_select::*;
|
||||
pub use icon::*;
|
||||
#[cfg(feature = "tree")]
|
||||
pub use id_tree;
|
||||
pub use input_group::*;
|
||||
pub use menu::*;
|
||||
pub use progressbar::*;
|
||||
pub use switch::*;
|
||||
|
|
|
@ -8,7 +8,8 @@ pub struct Tag {
|
|||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub children: Children,
|
||||
#[prop_or_default]
|
||||
pub children: html::Children,
|
||||
#[prop_or_default]
|
||||
// FIXME Not clear that this field has any effect without `interactive` on.
|
||||
pub active: bool,
|
||||
|
|
Loading…
Reference in a new issue