use dioxus::prelude::*;
#[derive(Clone, PartialEq)]
pub enum CheckboxSize {
Large,
Default,
Small,
}
impl CheckboxSize {
pub fn as_class(&self) -> &'static str {
match self {
CheckboxSize::Large => "el-checkbox--large",
CheckboxSize::Default => "",
CheckboxSize::Small => "el-checkbox--small",
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct CheckboxProps {
#[props(default)]
pub children: Option<Element>,
#[props(default)]
pub label: Option<String>,
#[props(default = false)]
pub model_value: bool,
#[props(default = false)]
pub disabled: bool,
#[props(default = false)]
pub indeterminate: bool,
#[props(default = CheckboxSize::Default)]
pub size: CheckboxSize,
#[props(default)]
pub value: Option<String>,
#[props(default)]
pub name: Option<String>,
#[props(default)]
pub on_change: Option<EventHandler<bool>>,
#[props(default)]
pub class: Option<String>,
#[props(default)]
pub style: Option<String>,
}
#[component]
pub fn Checkbox(props: CheckboxProps) -> Element {
let mut class_names = vec!["el-checkbox".to_string()];
let size_class = props.size.as_class();
if !size_class.is_empty() {
class_names.push(size_class.to_string());
}
if props.model_value {
class_names.push("is-checked".to_string());
}
if props.disabled {
class_names.push("is-disabled".to_string());
}
if props.indeterminate {
class_names.push("is-indeterminate".to_string());
}
if let Some(ref custom_class) = props.class {
class_names.push(custom_class.clone());
}
let class_string = class_names.join(" ");
let style_string = props.style.clone().unwrap_or_default();
rsx! {
label {
class: "{class_string}",
style: "{style_string}",
role: "checkbox",
aria_checked: "{props.model_value}",
span {
class: "el-checkbox__input",
if props.model_value || props.indeterminate {
span {
class: "el-checkbox__inner",
if props.indeterminate {
i { class: "el-checkbox__indeterminate" }
}
}
} else {
span { class: "el-checkbox__inner" }
}
if let Some(ref name) = props.name {
input {
r#type: "checkbox",
class: "el-checkbox__original",
name: "{name}",
checked: props.model_value,
onchange: move |_| {
if !props.disabled {
if let Some(handler) = props.on_change {
handler.call(!props.model_value);
}
}
},
}
}
}
span {
class: "el-checkbox__label",
onclick: move |_| {
if !props.disabled {
if let Some(handler) = props.on_change {
handler.call(!props.model_value);
}
}
},
if let Some(ref label) = props.label {
"{label}"
}
{props.children}
}
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct CheckboxGroupProps {
#[props(default)]
pub children: Element,
#[props(default = false)]
pub disabled: bool,
#[props(default)]
pub min: Option<u32>,
#[props(default)]
pub max: Option<u32>,
#[props(default)]
pub name: Option<String>,
#[props(default)]
pub on_change: Option<EventHandler<Vec<String>>>,
#[props(default)]
pub class: Option<String>,
#[props(default)]
pub style: Option<String>,
}
#[component]
pub fn CheckboxGroup(props: CheckboxGroupProps) -> Element {
let mut class_names = vec!["el-checkbox-group".to_string()];
if props.disabled {
class_names.push("is-disabled".to_string());
}
if let Some(ref custom_class) = props.class {
class_names.push(custom_class.clone());
}
let class_string = class_names.join(" ");
let style_string = props.style.clone().unwrap_or_default();
rsx! {
div {
class: "{class_string}",
style: "{style_string}",
role: "group",
{props.children}
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct CheckboxButtonProps {
#[props(default)]
pub children: Option<Element>,
#[props(default)]
pub label: Option<String>,
#[props(default = false)]
pub model_value: bool,
#[props(default = false)]
pub disabled: bool,
#[props(default)]
pub on_change: Option<EventHandler<bool>>,
#[props(default)]
pub class: Option<String>,
#[props(default)]
pub style: Option<String>,
}
#[component]
pub fn CheckboxButton(props: CheckboxButtonProps) -> Element {
let mut class_names = vec!["el-checkbox-button".to_string()];
if props.model_value {
class_names.push("is-checked".to_string());
}
if props.disabled {
class_names.push("is-disabled".to_string());
}
if let Some(ref custom_class) = props.class {
class_names.push(custom_class.clone());
}
let class_string = class_names.join(" ");
let style_string = props.style.clone().unwrap_or_default();
rsx! {
label {
class: "{class_string}",
style: "{style_string}",
span {
class: "el-checkbox-button__inner",
onclick: move |_| {
if !props.disabled {
if let Some(handler) = props.on_change {
handler.call(!props.model_value);
}
}
},
if let Some(ref label) = props.label {
"{label}"
}
{props.children}
}
}
}
}