mirror of
https://github.com/yewprint/yewprint
synced 2024-11-22 03:23:03 +00:00
parent
1a2594049c
commit
357e0fefde
7 changed files with 379 additions and 0 deletions
|
@ -10,6 +10,7 @@ use crate::icon::*;
|
|||
use crate::input_group::*;
|
||||
use crate::menu::*;
|
||||
use crate::progressbar::*;
|
||||
use crate::radio::*;
|
||||
use crate::slider::*;
|
||||
use crate::spinner::*;
|
||||
use crate::switch::*;
|
||||
|
@ -185,6 +186,12 @@ impl Component for App {
|
|||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::ProgressBar))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Radio")}
|
||||
href=Cow::Borrowed("#radio")
|
||||
onclick=self.link
|
||||
.callback(|_| Msg::GoToMenu(DocMenu::Radio))
|
||||
/>
|
||||
<MenuItem
|
||||
text={html!("Slider")}
|
||||
href=Cow::Borrowed("#slider")
|
||||
|
@ -256,6 +263,7 @@ impl Component for App {
|
|||
DocMenu::InputGroup => html!(<InputGroupDoc />),
|
||||
DocMenu::Menu => html!(<MenuDoc />),
|
||||
DocMenu::ProgressBar => html!(<ProgressBarDoc />),
|
||||
DocMenu::Radio => html!(<RadioDoc />),
|
||||
DocMenu::Slider => html!(<SliderDoc />),
|
||||
DocMenu::Spinner => html!(<SpinnerDoc />),
|
||||
DocMenu::Switch => html!(<SwitchDoc />),
|
||||
|
@ -300,6 +308,8 @@ pub enum DocMenu {
|
|||
Menu,
|
||||
#[to = "/#progress-bar"]
|
||||
ProgressBar,
|
||||
#[to = "/#radio"]
|
||||
Radio,
|
||||
#[to = "/#slider"]
|
||||
Slider,
|
||||
#[to = "/#spinner"]
|
||||
|
|
|
@ -14,6 +14,7 @@ mod icon;
|
|||
mod input_group;
|
||||
mod menu;
|
||||
mod progressbar;
|
||||
mod radio;
|
||||
mod slider;
|
||||
mod spinner;
|
||||
mod switch;
|
||||
|
|
99
yewprint-doc/src/radio/example.rs
Normal file
99
yewprint-doc/src/radio/example.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
use yew::prelude::*;
|
||||
use yewprint::{Label, Radio, RadioGroup};
|
||||
|
||||
pub struct Example {
|
||||
props: ExampleProps,
|
||||
link: ComponentLink<Self>,
|
||||
selected_value: Lunch,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct ExampleProps {
|
||||
pub disabled: bool,
|
||||
pub inline: bool,
|
||||
pub large: bool,
|
||||
}
|
||||
|
||||
pub enum Msg {
|
||||
ValueUpdate(Lunch),
|
||||
}
|
||||
|
||||
impl Component for Example {
|
||||
type Message = Msg;
|
||||
type Properties = ExampleProps;
|
||||
|
||||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
Example {
|
||||
props,
|
||||
selected_value: Lunch::Salad,
|
||||
link,
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||
match msg {
|
||||
Msg::ValueUpdate(value) => {
|
||||
self.selected_value = value;
|
||||
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>
|
||||
<Radio
|
||||
label=html!("Blue pill")
|
||||
inline=self.props.inline
|
||||
disabled=self.props.disabled
|
||||
large=self.props.large
|
||||
name="group".to_string()
|
||||
/>
|
||||
<Radio
|
||||
label=html!("Red pill")
|
||||
inline=self.props.inline
|
||||
disabled=self.props.disabled
|
||||
large=self.props.large
|
||||
name="group".to_string()
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<RadioGroup<Lunch>
|
||||
label=Some(html!(
|
||||
<Label>
|
||||
{"Determine Lunch"}
|
||||
</Label>
|
||||
))
|
||||
options=vec![
|
||||
(Lunch::Soup, "Soup".to_string()),
|
||||
(Lunch::Salad, "Salad".to_string()),
|
||||
(Lunch::Sandwich, "Sandwich".to_string()),
|
||||
]
|
||||
value=self.selected_value
|
||||
onchange=self.link.callback(|v| Msg::ValueUpdate(v))
|
||||
inline=self.props.inline
|
||||
disabled=self.props.disabled
|
||||
large=self.props.large
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq)]
|
||||
pub enum Lunch {
|
||||
Soup,
|
||||
Salad,
|
||||
Sandwich,
|
||||
}
|
96
yewprint-doc/src/radio/mod.rs
Normal file
96
yewprint-doc/src/radio/mod.rs
Normal file
|
@ -0,0 +1,96 @@
|
|||
mod example;
|
||||
|
||||
use crate::ExampleContainer;
|
||||
use example::*;
|
||||
use yew::prelude::*;
|
||||
use yewprint::{Switch, H1, H5};
|
||||
|
||||
pub struct RadioDoc {
|
||||
callback: Callback<ExampleProps>,
|
||||
state: ExampleProps,
|
||||
}
|
||||
|
||||
impl Component for RadioDoc {
|
||||
type Message = ExampleProps;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
RadioDoc {
|
||||
callback: link.callback(|x| x),
|
||||
state: ExampleProps {
|
||||
disabled: false,
|
||||
inline: false,
|
||||
large: 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=classes!("docs-title")>{"Radio"}</H1>
|
||||
<ExampleContainer
|
||||
source=source
|
||||
props=Some(html! {
|
||||
<RadioProps
|
||||
callback={self.callback.clone()}
|
||||
props=example_props.clone()
|
||||
/>
|
||||
})
|
||||
>
|
||||
<Example with example_props />
|
||||
</ExampleContainer>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate::build_example_prop_component! {
|
||||
RadioProps 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 {
|
||||
inline: !props.inline,
|
||||
..props
|
||||
})
|
||||
checked=self.props.inline
|
||||
label=html!("Inline")
|
||||
/>
|
||||
<Switch
|
||||
onclick=self.update_props(|props, _| ExampleProps {
|
||||
large: !props.large,
|
||||
..props
|
||||
})
|
||||
checked=self.props.large
|
||||
label=html!("Large")
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@ mod icon;
|
|||
mod input_group;
|
||||
mod menu;
|
||||
mod progressbar;
|
||||
mod radio;
|
||||
mod radio_group;
|
||||
mod slider;
|
||||
mod spinner;
|
||||
mod switch;
|
||||
|
@ -41,6 +43,8 @@ pub use id_tree;
|
|||
pub use input_group::*;
|
||||
pub use menu::*;
|
||||
pub use progressbar::*;
|
||||
pub use radio::*;
|
||||
pub use radio_group::*;
|
||||
pub use slider::*;
|
||||
pub use spinner::*;
|
||||
pub use switch::*;
|
||||
|
|
75
yewprint/src/radio.rs
Normal file
75
yewprint/src/radio.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use yew::prelude::*;
|
||||
|
||||
pub struct Radio {
|
||||
props: RadioProps,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct RadioProps {
|
||||
#[prop_or_default]
|
||||
pub disabled: bool,
|
||||
#[prop_or_default]
|
||||
pub inline: bool,
|
||||
#[prop_or_default]
|
||||
pub large: bool,
|
||||
#[prop_or_default]
|
||||
pub checked: Option<bool>,
|
||||
#[prop_or_default]
|
||||
pub name: Option<String>,
|
||||
#[prop_or_default]
|
||||
pub onchange: Option<Callback<ChangeData>>,
|
||||
#[prop_or_default]
|
||||
pub label: yew::virtual_dom::VNode,
|
||||
#[prop_or_default]
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
impl Component for Radio {
|
||||
type Message = ();
|
||||
type Properties = RadioProps;
|
||||
|
||||
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 {
|
||||
html! {
|
||||
<label
|
||||
class=classes!(
|
||||
"bp3-control",
|
||||
"bp3-radio",
|
||||
self.props.disabled.then(|| "bp3-disabled"),
|
||||
self.props.inline.then(|| "bp3-inline"),
|
||||
self.props.large.then(|| "bp3-large"),
|
||||
)
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
onchange={self.props.onchange.clone().unwrap_or_default()}
|
||||
disabled=self.props.disabled
|
||||
value={self.props.value.clone().unwrap_or_default()}
|
||||
checked=self.props.checked.unwrap_or(false)
|
||||
name={self.props.name.clone().unwrap_or_default()}
|
||||
/>
|
||||
<span
|
||||
class=classes!("bp3-control-indicator")
|
||||
>
|
||||
</span>
|
||||
{self.props.label.clone()}
|
||||
</label>
|
||||
}
|
||||
}
|
||||
}
|
94
yewprint/src/radio_group.rs
Normal file
94
yewprint/src/radio_group.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
use crate::Radio;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct RadioGroup<T: Clone + PartialEq + 'static> {
|
||||
props: RadioGroupProps<T>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct RadioGroupProps<T: Clone + PartialEq + 'static> {
|
||||
#[prop_or_default]
|
||||
pub label: Option<yew::virtual_dom::VNode>,
|
||||
#[prop_or_default]
|
||||
pub disabled: bool,
|
||||
#[prop_or_default]
|
||||
pub inline: bool,
|
||||
#[prop_or_default]
|
||||
pub large: bool,
|
||||
pub options: Vec<(T, String)>,
|
||||
#[prop_or_default]
|
||||
pub value: Option<T>,
|
||||
#[prop_or_default]
|
||||
pub onchange: Callback<T>,
|
||||
#[prop_or_default]
|
||||
pub class: Classes,
|
||||
}
|
||||
|
||||
impl<T: Clone + PartialEq + 'static> Component for RadioGroup<T> {
|
||||
type Message = ();
|
||||
type Properties = RadioGroupProps<T>;
|
||||
|
||||
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 {
|
||||
let option_children = self
|
||||
.props
|
||||
.options
|
||||
.iter()
|
||||
.map(|(value, label)| {
|
||||
let checked = self
|
||||
.props
|
||||
.value
|
||||
.as_ref()
|
||||
.map(|x| value == x)
|
||||
.unwrap_or_default();
|
||||
let value = value.clone();
|
||||
|
||||
html! {
|
||||
<Radio
|
||||
value="".to_string()
|
||||
label=html!(label)
|
||||
checked=checked
|
||||
onchange=self.props.onchange.reform(move |_| value.clone())
|
||||
inline=self.props.inline
|
||||
disabled=self.props.disabled
|
||||
large=self.props.large
|
||||
/>
|
||||
}
|
||||
})
|
||||
.collect::<Html>();
|
||||
|
||||
html! {
|
||||
<div
|
||||
class=classes!(
|
||||
"bp3-radio-group",
|
||||
self.props.class.clone(),
|
||||
)
|
||||
>
|
||||
{
|
||||
if let Some(label) = self.props.label.clone() {
|
||||
label
|
||||
} else {
|
||||
html!()
|
||||
}
|
||||
}
|
||||
{option_children}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue