From 208c7b9839f1b67b9d0c343f4019354e4e9768fa Mon Sep 17 00:00:00 2001 From: Xu Shaohua Date: Fri, 24 Nov 2023 16:02:21 +0800 Subject: [PATCH] zu: Impl Checkbox --- .../zu-docs/src/views/inputs/checkbox_page.rs | 4 +- crates/zu/src/checkbox/mod.rs | 61 ++++++++++++++++--- crates/zu/src/checkbox/style.scss | 58 +++++++++++++----- crates/zu/src/switch_base/mod.rs | 2 +- 4 files changed, 99 insertions(+), 26 deletions(-) diff --git a/crates/zu-docs/src/views/inputs/checkbox_page.rs b/crates/zu-docs/src/views/inputs/checkbox_page.rs index 8ca1e7355..9ea139516 100644 --- a/crates/zu-docs/src/views/inputs/checkbox_page.rs +++ b/crates/zu-docs/src/views/inputs/checkbox_page.rs @@ -17,8 +17,8 @@ use crate::components::demo_box::DemoBox; #[function_component(CheckboxPage)] pub fn checkbox_page() -> Html { - let handle_change = Callback::from(|()| { - log::info!("on change"); + let handle_change = Callback::from(|checked: bool| { + log::info!("handle change, is checked: {checked}"); }); html! { diff --git a/crates/zu/src/checkbox/mod.rs b/crates/zu/src/checkbox/mod.rs index 3f3f801ec..47fef3a4c 100644 --- a/crates/zu/src/checkbox/mod.rs +++ b/crates/zu/src/checkbox/mod.rs @@ -5,13 +5,18 @@ mod color; use yew::{classes, function_component, html, AttrValue, Callback, Classes, Html, Properties}; -use zu_util::prop::ToAttr; +use crate::internal::svg_icons::{CheckBox, CheckBoxOutlineBlank, IntermediateCheckBox}; use crate::styles::color::Color; use crate::styles::size::Size; +use crate::switch_base::{SwitchBase, Variant}; #[derive(Debug, Clone, PartialEq, Properties)] pub struct Props { + #[prop_or_default] + pub aria_label: AttrValue, + + /// If `true`, the component is checked. #[prop_or(false)] pub checked: bool, @@ -21,9 +26,11 @@ pub struct Props { #[prop_or_default] pub checked_icon: Option, + /// Override or extend the styles applied to the component. #[prop_or_default] pub classes: Classes, + /// The color of the component. #[prop_or_default] pub color: Color, @@ -31,9 +38,11 @@ pub struct Props { #[prop_or(false)] pub default_checked: bool, + /// If `true`, the component is disabled. #[prop_or(false)] pub disabled: bool, + /// If `true`, the ripple effect is disabled. #[prop_or(false)] pub disable_ripple: bool, @@ -57,18 +66,26 @@ pub struct Props { /// Callback fired when the state is changed. #[prop_or_default] - pub on_change: Option>, + pub on_change: Option>, /// If true, the input element is required. #[prop_or(false)] pub required: bool, - #[prop_or_default] + /// The size of the component. + /// + /// `Size::small` is equivalent to the dense checkbox styling. + #[prop_or(Size::Medium)] pub size: Size, #[prop_or_default] pub style: AttrValue, - //pub value: T, + + /// The value of the component. + /// + /// The browser uses "on" as the default value. + #[prop_or_default] + pub value: String, } #[function_component(Checkbox)] @@ -89,10 +106,38 @@ pub fn checkbox(props: &Props) -> Html { props.classes.clone(), ); - // TODO(Shaohua): Add SwitchBase. - // TODO(Shaohua): Add default icons. + let root_input_cls = ""; + + let icon = props + .icon + .as_ref() + .map_or_else(|| html! {}, Clone::clone); + + let checked_icon = if props.indeterminate { + props + .indeterminate_icon + .as_ref() + .map_or_else(|| html! {}, Clone::clone) + } else { + html! {} + }; + + // TODO(Shaohua): Support indeterminate + html! { -
-
+ + } } diff --git a/crates/zu/src/checkbox/style.scss b/crates/zu/src/checkbox/style.scss index 8dd532fa1..22d2394b9 100644 --- a/crates/zu/src/checkbox/style.scss +++ b/crates/zu/src/checkbox/style.scss @@ -3,15 +3,14 @@ // Styles applied to the root element. .ZuCheckbox-root { - color: var(--zu-palette-text-secondary); - + color: $zu-palette-text-secondary; } .ZuCheckbox-enableRipple { &:hover { &.ZuCheckbox-colorDefault { - background-color: var(--zu-palette-action-active); + background-color: change-color($zu-palette-action-active, $alpha: $zu-palette-action-hoverOpacity); } &.ZuCheckbox-colorPrimary { background-color: change-color($zu-palette-primary-main, $alpha: $zu-palette-action-hoverOpacity); @@ -55,32 +54,61 @@ } .ZuCheckbox-colorPrimary { - &.ZuCheckbox-checked, &.ZuCheckbox-indeterminate { - color: var(--zu-palette-primary-main); + &.ZuSwitchBase-checked, &.ZuCheckbox-indeterminate { + color: $zu-palette-primary-main; + } + + &.ZuCheckbox-disabled { + color: $zu-palette-action-disabled; } } + .ZuCheckbox-colorSecondary { - &.ZuCheckbox-checked, &.ZuCheckbox-indeterminate { - color: var(--zu-palette-secondary-main); + &.ZuSwitchBase-checked, &.ZuCheckbox-indeterminate { + color: $zu-palette-secondary-main; + } + + &.ZuCheckbox-disabled { + color: $zu-palette-action-disabled; } } + .ZuCheckbox-colorSuccess { - &.ZuCheckbox-checked, &.ZuCheckbox-indeterminate { - color: var(--zu-palette-success-main); + &.ZuSwitchBase-checked, &.ZuCheckbox-indeterminate { + color: $zu-palette-success-main; + } + + &.ZuCheckbox-disabled { + color: $zu-palette-action-disabled; } } + .ZuCheckbox-colorInfo { - &.ZuCheckbox-checked, &.ZuCheckbox-indeterminate { - color: var(--zu-palette-info-main); + &.ZuSwitchBase-checked, &.ZuCheckbox-indeterminate { + color: $zu-palette-info-main; + } + + &.ZuCheckbox-disabled { + color: $zu-palette-action-disabled; } } + .ZuCheckbox-colorWarning { - &.ZuCheckbox-checked, &.ZuCheckbox-indeterminate { - color: var(--zu-palette-warning-main); + &.ZuSwitchBase-checked, &.ZuCheckbox-indeterminate { + color: $zu-palette-warning-main; + } + + &.ZuCheckbox-disabled { + color: $zu-palette-action-disabled; } } + .ZuCheckbox-colorError { - &.ZuCheckbox-checked, &.ZuCheckbox-indeterminate { - color: var(--zu-palette-error-main); + &.ZuSwitchBase-checked, &.ZuCheckbox-indeterminate { + color: $zu-palette-error-main; + } + + &.ZuCheckbox-disabled { + color: $zu-palette-action-disabled; } } \ No newline at end of file diff --git a/crates/zu/src/switch_base/mod.rs b/crates/zu/src/switch_base/mod.rs index a6c539bd5..ab1e87913 100644 --- a/crates/zu/src/switch_base/mod.rs +++ b/crates/zu/src/switch_base/mod.rs @@ -174,7 +174,7 @@ pub fn switch_base(props: &Props) -> Html { type={props.variant.name()} {value} /> - if props.checked { + if *checked_state { {props.checked_icon.clone()} } else { {props.icon.clone()}