use dioxus::prelude::*;
use crate::types::{Color, Size};
#[derive(Clone, PartialEq, Props)]
pub struct ButtonProps {
#[props(default)]
pub color: Color,
#[props(default)]
pub outline: bool,
#[props(default)]
pub size: Size,
#[props(default)]
pub disabled: bool,
#[props(default)]
pub href: Option<String>,
#[props(default)]
pub target: Option<String>,
#[props(default)]
pub download: Option<String>,
#[props(default = "button".to_string())]
pub r#type: String,
#[props(default)]
pub onclick: Option<EventHandler<MouseEvent>>,
#[props(default)]
pub active: bool,
#[props(default)]
pub class: String,
#[props(extends = GlobalAttributes)]
attributes: Vec<Attribute>,
pub children: Element,
}
#[component]
pub fn Button(props: ButtonProps) -> Element {
let style = if props.outline { "btn-outline" } else { "btn" };
let color = props.color;
let color_class = format!("{style}-{color}");
let size_class = match props.size {
Size::Md => String::new(),
s => format!(" btn-{s}"),
};
let active_class = if props.active { " active" } else { "" };
let full_class = if props.class.is_empty() {
format!("btn {color_class}{size_class}{active_class}")
} else {
format!(
"btn {color_class}{size_class}{active_class} {}",
props.class
)
};
if let Some(href) = &props.href {
let disabled_class = if props.disabled { " disabled" } else { "" };
let link_class = format!("{full_class}{disabled_class}");
let target = props.target.clone();
let download = props.download.clone();
rsx! {
a {
class: "{link_class}",
href: "{href}",
role: "button",
target: target,
download: download,
onclick: move |evt| {
if let Some(handler) = &props.onclick {
handler.call(evt);
}
},
..props.attributes,
{props.children}
}
}
} else {
rsx! {
button {
class: "{full_class}",
r#type: "{props.r#type}",
disabled: props.disabled,
onclick: move |evt| {
if let Some(handler) = &props.onclick {
handler.call(evt);
}
},
..props.attributes,
{props.children}
}
}
}
}
#[derive(Clone, PartialEq, Props)]
pub struct ButtonGroupProps {
#[props(default)]
pub size: Size,
#[props(default)]
pub class: String,
pub children: Element,
}
#[component]
pub fn ButtonGroup(props: ButtonGroupProps) -> Element {
let size_class = match props.size {
Size::Md => String::new(),
s => format!(" btn-group-{s}"),
};
let full_class = if props.class.is_empty() {
format!("btn-group{size_class}")
} else {
format!("btn-group{size_class} {}", props.class)
};
rsx! {
div {
class: "{full_class}",
role: "group",
{props.children}
}
}
}
#[derive(Clone, PartialEq, Props)]
pub struct ButtonToolbarProps {
#[props(default)]
pub class: String,
pub children: Element,
}
#[component]
pub fn ButtonToolbar(props: ButtonToolbarProps) -> Element {
let full_class = if props.class.is_empty() {
"btn-toolbar".to_string()
} else {
format!("btn-toolbar {}", props.class)
};
rsx! {
div {
class: "{full_class}",
role: "toolbar",
{props.children}
}
}
}