yew_bs/components/
button.rs1use yew::prelude::*;
2use crate::components::common::{Size, Variant};
3#[derive(Clone, Copy, PartialEq, Debug)]
4pub enum ButtonGroupSize {
5 Small,
6 Large,
7}
8impl ButtonGroupSize {
9 pub fn as_str(&self) -> &'static str {
10 match self {
11 ButtonGroupSize::Small => "btn-group-sm",
12 ButtonGroupSize::Large => "btn-group-lg",
13 }
14 }
15}
16#[derive(Properties, PartialEq)]
18pub struct ButtonProps {
19 #[prop_or_default]
21 pub children: Children,
22 #[prop_or(Variant::Primary)]
24 pub variant: Variant,
25 #[prop_or_default]
27 pub size: Option<Size>,
28 #[prop_or_default]
30 pub outline: bool,
31 #[prop_or_default]
33 pub button_type: Option<String>,
34 #[prop_or_default]
36 pub disabled: bool,
37 #[prop_or_default]
39 pub active: bool,
40 #[prop_or_default]
42 pub onclick: Option<Callback<MouseEvent>>,
43 #[prop_or_default]
45 pub class: Option<AttrValue>,
46 #[prop_or_default]
48 pub node_ref: NodeRef,
49}
50#[function_component(Button)]
52pub fn button(props: &ButtonProps) -> Html {
53 let mut classes = Classes::new();
54 classes.push("btn");
55 if props.outline {
56 classes.push(format!("btn-outline-{}", props.variant.as_str()));
57 } else {
58 classes.push(format!("btn-{}", props.variant.as_str()));
59 }
60 if let Some(size) = &props.size {
61 let size_str = size.as_str();
62 if !size_str.is_empty() {
63 classes.push(format!("btn-{}", size_str));
64 }
65 }
66 if props.active {
67 classes.push("active");
68 }
69 if let Some(class) = &props.class {
70 classes.push(class.to_string());
71 }
72 let button_type = props.button_type.clone().unwrap_or_else(|| "button".to_string());
73 html! {
74 < button type = { button_type } class = { classes } disabled = { props.disabled }
75 onclick = { props.onclick.clone() } ref = { props.node_ref.clone() } > { for
76 props.children.iter() } </ button >
77 }
78}
79#[derive(Properties, PartialEq)]
81pub struct ButtonGroupProps {
82 #[prop_or_default]
84 pub children: Children,
85 #[prop_or_default]
87 pub vertical: bool,
88 #[prop_or_default]
90 pub size: Option<ButtonGroupSize>,
91 #[prop_or_default]
93 pub class: Option<AttrValue>,
94 #[prop_or_default]
96 pub aria_label: Option<AttrValue>,
97 #[prop_or_default]
99 pub role: Option<String>,
100}
101#[function_component(ButtonGroup)]
103pub fn button_group(props: &ButtonGroupProps) -> Html {
104 let mut classes = Classes::new();
105 if props.vertical {
106 classes.push("btn-group-vertical");
107 } else {
108 classes.push("btn-group");
109 }
110 if let Some(size) = &props.size {
111 classes.push(size.as_str());
112 }
113 if let Some(class) = &props.class {
114 classes.push(class.to_string());
115 }
116 let role = props.role.clone().unwrap_or_else(|| "group".to_string());
117 html! {
118 < div class = { classes } role = { role } aria - label = { props.aria_label
119 .clone() } > { for props.children.iter() } </ div >
120 }
121}
122#[derive(Properties, PartialEq)]
124pub struct ButtonToolbarProps {
125 #[prop_or_default]
127 pub children: Children,
128 #[prop_or_default]
130 pub class: Option<AttrValue>,
131 #[prop_or_default]
133 pub aria_label: Option<AttrValue>,
134 #[prop_or_default]
136 pub role: Option<String>,
137}
138#[function_component(ButtonToolbar)]
140pub fn button_toolbar(props: &ButtonToolbarProps) -> Html {
141 let mut classes = Classes::new();
142 classes.push("btn-toolbar");
143 if let Some(class) = &props.class {
144 classes.push(class.to_string());
145 }
146 let role = props.role.clone().unwrap_or_else(|| "toolbar".to_string());
147 html! {
148 < div class = { classes } role = { role } aria - label = { props.aria_label
149 .clone() } > { for props.children.iter() } </ div >
150 }
151}