Add disabled and invalid statuses to input (#35)

* Add disabled and invalid statuses to input

* pref: input component theme and style

---------

Co-authored-by: Cristobal Andrada <kandrelczyk@gmail.com>
Co-authored-by: luoxiao <luoxiaozero@163.com>
This commit is contained in:
kandrelczyk 2023-12-04 12:19:47 +00:00 committed by GitHub
parent d0133191ec
commit 00e42b94a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 187 additions and 11 deletions

View file

@ -52,6 +52,32 @@ pub fn AutoCompletePage() -> impl IntoView {
</DemoCode>
</Demo>
<h3>"disabled"</h3>
<Demo>
<AutoComplete value options placeholder="Email" disabled=true/>
<DemoCode slot>
{highlight_str!(
r#"
<AutoComplete value options placeholder="Email" disabled=true/>
"#,
"rust"
)}
</DemoCode>
</Demo>
<h3>"invalid"</h3>
<Demo>
<AutoComplete value options placeholder="Email" invalid=true/>
<DemoCode slot>
{highlight_str!(
r#"
<AutoComplete value options placeholder="Email" invalid=true/>
"#,
"rust"
)}
</DemoCode>
</Demo>
<h3>"AutoComplete Props"</h3>
<Table single_column=true>
<thead>
@ -81,6 +107,18 @@ pub fn AutoCompletePage() -> impl IntoView {
<td>"Vec::new()"</td>
<td>"Options to autocomplete from."</td>
</tr>
<tr>
<td>"disabled"</td>
<td>"MaybeSignal<bool>"</td>
<td>"false"</td>
<td>"Whether the input is disabled."</td>
</tr>
<tr>
<td>"invalid"</td>
<td>"MaybeSignal<bool>"</td>
<td>"false"</td>
<td>"Whether the input is invalid."</td>
</tr>
<tr>
<td>"clear_after_select"</td>
<td>"MaybeSignal<bool>"</td>

View file

@ -269,7 +269,7 @@ fn LoadingButton() -> impl IntoView {
);
};
view! {
<h3>"Loading"</h3>
<h3>"loading"</h3>
<Demo>
<Space>
<Button loading on_click icon=icondata::AiIcon::AiCloseOutlined>

View file

@ -21,7 +21,7 @@ pub fn ComponentsPage() -> impl IntoView {
_ = select_name.watch(move |name| {
let pathname = loaction.pathname.get_untracked();
if !pathname.starts_with(&format!("/thaw/components/{name}")) {
if !pathname.eq(&format!("/thaw/components/{name}")) {
navigate(&format!("/components/{name}"), Default::default());
}
});

View file

@ -32,6 +32,38 @@ pub fn InputPage() -> impl IntoView {
</DemoCode>
</Demo>
<h3>disabled</h3>
<Demo>
<Space vertical=true>
<Input value disabled=true/>
</Space>
<DemoCode slot>
{highlight_str!(
r#"
<Input value disabled=true/>
"#,
"rust"
)}
</DemoCode>
</Demo>
<h3>invalid</h3>
<Demo>
<Space vertical=true>
<Input value invalid=true/>
</Space>
<DemoCode slot>
{highlight_str!(
r#"
<Input value invalid=true/>
"#,
"rust"
)}
</DemoCode>
</Demo>
<h1>"Prefix & Suffix"</h1>
<Demo>
<Space vertical=true>
@ -101,7 +133,7 @@ pub fn InputPage() -> impl IntoView {
<td>"variant"</td>
<td>"MaybeSignal<InputVariant>"</td>
<td>"InputVariant::Text"</td>
<td>"Button's variant."</td>
<td>"Input's variant."</td>
</tr>
<tr>
<td>"placeholder"</td>
@ -109,6 +141,18 @@ pub fn InputPage() -> impl IntoView {
<td>"Default::default()"</td>
<td>"Placeholder of input."</td>
</tr>
<tr>
<td>"disabled"</td>
<td>"MaybeSignal<bool>"</td>
<td>"false"</td>
<td>"Whether the input is disabled."</td>
</tr>
<tr>
<td>"invalid"</td>
<td>"MaybeSignal<bool>"</td>
<td>"false"</td>
<td>"Whether the input is invalid."</td>
</tr>
<tr>
<td>"allow_value"</td>
<td>"Option<Callback<String, bool>>"</td>

View file

@ -33,6 +33,38 @@ pub fn InputNumberPage() -> impl IntoView {
</DemoCode>
</Demo>
<h3>"disabled"</h3>
<Demo>
<Space vertical=true>
<InputNumber value step=1 disabled=true/>
</Space>
<DemoCode slot>
{highlight_str!(
r#"
<InputNumber value step=1 disabled=true/>
"#,
"rust"
)}
</DemoCode>
</Demo>
<h3>"invalid"</h3>
<Demo>
<Space vertical=true>
<InputNumber value step=1 invalid=true/>
</Space>
<DemoCode slot>
{highlight_str!(
r#"
<InputNumber value step=1 invalid=true/>
"#,
"rust"
)}
</DemoCode>
</Demo>
<h3>"InputNumber Props"</h3>
<Table single_column=true>
<thead>
@ -64,6 +96,18 @@ pub fn InputNumberPage() -> impl IntoView {
"The number which the current value is increased or decreased on key or button press."
</td>
</tr>
<tr>
<td>"disabled"</td>
<td>"MaybeSignal<bool>"</td>
<td>"false"</td>
<td>"Whether the input is disabled."</td>
</tr>
<tr>
<td>"invalid"</td>
<td>"MaybeSignal<bool>"</td>
<td>"false"</td>
<td>"Whether the input is invalid."</td>
</tr>
</tbody>
</Table>
<h3>"T impl"</h3>

View file

@ -22,6 +22,8 @@ pub fn AutoComplete(
#[prop(optional, into)] options: MaybeSignal<Vec<AutoCompleteOption>>,
#[prop(optional, into)] clear_after_select: MaybeSignal<bool>,
#[prop(optional, into)] on_select: Option<Callback<String>>,
#[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] invalid: MaybeSignal<bool>,
) -> impl IntoView {
mount_style("auto-complete", include_str!("./auto-complete.css"));
let theme = use_theme(Theme::light);
@ -111,6 +113,8 @@ pub fn AutoComplete(
<Input
value
placeholder
disabled
invalid
on_focus=move |_| open_menu()
on_blur=move |_| is_show_menu.set(false)
allow_value

View file

@ -13,18 +13,33 @@
}
.thaw-input--focus,
.thaw-input:hover {
.thaw-input:hover:not(.thaw-input--disabled, .thaw-input--invalid) {
border-color: var(--thaw-border-color-hover);
}
.thaw-input--focus {
.thaw-input--disabled,
.thaw-input--disabled .thaw-input__input-el {
cursor: not-allowed;
background-color: var(--thaw-background-color-disabled);
color: var(--thaw-font-color-disabled);
}
.thaw-input--invalid {
border-color: var(--thaw-border-color-error);
}
.thaw-input--focus:not(.thaw-input--invalid) {
box-shadow: 0 0 0 2px var(--thaw-box-shadow-color);
}
.thaw-input--focus.thaw-input--invalid {
box-shadow: 0 0 0 2px var(--thaw-box-shadow-color-invalid);
}
.thaw-input__input-el {
width: 100%;
height: 30px;
background-color: transparent;
background-color: transparent !important;
color: var(--thaw-font-color);
line-height: 30px;
font-size: inherit;

View file

@ -41,6 +41,8 @@ pub fn Input(
#[prop(optional, into)] placeholder: MaybeSignal<String>,
#[prop(optional, into)] on_focus: Option<Callback<ev::FocusEvent>>,
#[prop(optional, into)] on_blur: Option<Callback<ev::FocusEvent>>,
#[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] invalid: MaybeSignal<bool>,
#[prop(optional)] input_prefix: Option<InputPrefix>,
#[prop(optional)] input_suffix: Option<InputSuffix>,
) -> impl IntoView {
@ -89,10 +91,26 @@ pub fn Input(
"--thaw-border-color: {};",
theme.input.border_color
));
css_vars.push_str(&format!(
"--thaw-border-color-error: {};",
theme.common.color_error
));
css_vars.push_str(&format!(
"--thaw-placeholder-color: {};",
theme.input.placeholder_color
));
css_vars.push_str(&format!(
"--thaw-background-color-disabled: {};",
theme.input.background_color_disabled
));
css_vars.push_str(&format!(
"--thaw-font-color-disabled: {};",
theme.input.font_color_disabled
));
css_vars.push_str(&format!(
"--thaw-box-shadow-color-invalid: {}33;",
theme.common.color_error
));
});
css_vars
});
@ -100,6 +118,8 @@ pub fn Input(
<div
class="thaw-input"
class=("thaw-input--focus", move || is_focus.get())
class=("thaw-input--disabled", move || disabled.get())
class=("thaw-input--invalid", move || invalid.get())
style=move || css_vars.get()
>
{if let Some(prefix) = input_prefix {
@ -119,6 +139,7 @@ pub fn Input(
on:focus=on_internal_focus
on:blur=on_internal_blur
class="thaw-input__input-el"
disabled=move || disabled.get()
placeholder=move || placeholder.get()
/>

View file

@ -6,6 +6,8 @@ pub struct InputTheme {
pub placeholder_color: String,
pub border_color: String,
pub background_color: String,
pub font_color_disabled: String,
pub background_color_disabled: String,
}
impl ThemeMethod for InputTheme {
@ -15,6 +17,8 @@ impl ThemeMethod for InputTheme {
placeholder_color: "#c2c2c2".into(),
border_color: "#e0e0e6".into(),
background_color: "#fff".into(),
font_color_disabled: "#c2c2c2".into(),
background_color_disabled: "#fafafc".into(),
}
}
@ -24,6 +28,8 @@ impl ThemeMethod for InputTheme {
placeholder_color: "#c2c2c2".into(),
border_color: "#0000".into(),
background_color: "#ffffff1a".into(),
font_color_disabled: "#ffffff61".into(),
background_color_disabled: "#ffffff0f".into(),
}
}
}

View file

@ -9,6 +9,8 @@ pub fn InputNumber<T>(
#[prop(optional, into)] value: RwSignal<T>,
#[prop(optional, into)] placeholder: MaybeSignal<String>,
#[prop(into)] step: MaybeSignal<T>,
#[prop(optional, into)] disabled: MaybeSignal<bool>,
#[prop(optional, into)] invalid: MaybeSignal<bool>,
) -> impl IntoView
where
T: Add<Output = T> + Sub<Output = T>,
@ -35,19 +37,21 @@ where
});
let step: StoredMaybeSignal<_> = step.into();
let add = Callback::<ev::MouseEvent>::new(move |_| {
let add = Callback::<ev::MouseEvent>::new(move |e: ev::MouseEvent| {
e.prevent_default();
value.set(value.get_untracked() + step.get_untracked());
});
let sub = Callback::<ev::MouseEvent>::new(move |_| {
let sub = Callback::<ev::MouseEvent>::new(move |e: ev::MouseEvent| {
e.prevent_default();
value.set(value.get_untracked() - step.get_untracked());
});
view! {
<Input value=input_value allow_value placeholder>
<Input value=input_value allow_value placeholder disabled invalid>
<InputSuffix slot>
<Button variant=ButtonVariant::Link on_click=sub>
<Button disabled variant=ButtonVariant::Link on_click=sub>
<Icon icon=Icon::from(AiIcon::AiMinusOutlined) style="font-size: 18px"/>
</Button>
<Button variant=ButtonVariant::Link on_click=add>
<Button disabled variant=ButtonVariant::Link on_click=add>
<Icon icon=Icon::from(AiIcon::AiPlusOutlined) style="font-size: 18px"/>
</Button>
</InputSuffix>