mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
refactor: input
This commit is contained in:
parent
ed425b90f0
commit
824ca9c4b1
6 changed files with 120 additions and 110 deletions
|
@ -1,7 +1,7 @@
|
|||
# Input
|
||||
|
||||
```rust demo
|
||||
let value = create_rw_signal(String::from("o"));
|
||||
let value = RwSignal::new(String::from("o"));
|
||||
|
||||
view! {
|
||||
<Space vertical=true>
|
||||
|
@ -12,10 +12,35 @@ view! {
|
|||
}
|
||||
```
|
||||
|
||||
## Prefix & Suffix
|
||||
|
||||
```rust demo
|
||||
let value = RwSignal::new(String::from("o"));
|
||||
|
||||
view! {
|
||||
<Space vertical=true>
|
||||
<Input value>
|
||||
<InputPrefix slot>
|
||||
<Icon icon=icondata::AiUserOutlined/>
|
||||
</InputPrefix>
|
||||
</Input>
|
||||
<Input value>
|
||||
<InputSuffix slot>
|
||||
<Icon icon=icondata::AiGithubOutlined/>
|
||||
</InputSuffix>
|
||||
</Input>
|
||||
<Input value>
|
||||
<InputPrefix slot>"$"</InputPrefix>
|
||||
<InputSuffix slot>".00"</InputSuffix>
|
||||
</Input>
|
||||
</Space>
|
||||
}
|
||||
```
|
||||
|
||||
### Disabled
|
||||
|
||||
```rust demo
|
||||
let value = create_rw_signal(String::from("o"));
|
||||
let value = RwSignal::new(String::from("o"));
|
||||
|
||||
view! {
|
||||
<Space vertical=true>
|
||||
|
@ -25,6 +50,14 @@ view! {
|
|||
}
|
||||
```
|
||||
|
||||
### Placeholder
|
||||
|
||||
```rust demo
|
||||
view! {
|
||||
<Input placeholder="This is a placeholder"/>
|
||||
}
|
||||
```
|
||||
|
||||
### Invalid
|
||||
|
||||
```rust demo
|
||||
|
@ -78,29 +111,7 @@ view! {
|
|||
}
|
||||
```
|
||||
|
||||
## Prefix & Suffix
|
||||
|
||||
```rust demo
|
||||
let value = create_rw_signal(String::from("o"));
|
||||
|
||||
view! {
|
||||
<Space vertical=true>
|
||||
<Input value>
|
||||
<InputPrefix slot>
|
||||
<Icon icon=icondata::AiUserOutlined/>
|
||||
</InputPrefix>
|
||||
</Input>
|
||||
<Input value>
|
||||
<InputSuffix slot>"$"</InputSuffix>
|
||||
</Input>
|
||||
<Input value>
|
||||
<InputSuffix slot>
|
||||
<Icon icon=icondata::AiGithubOutlined/>
|
||||
</InputSuffix>
|
||||
</Input>
|
||||
</Space>
|
||||
}
|
||||
```
|
||||
|
||||
### Input Props
|
||||
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
border: 1px solid var(--colorNeutralStroke1);
|
||||
border-bottom-color: var(--colorNeutralStrokeAccessible);
|
||||
border-radius: var(--borderRadiusMedium);
|
||||
|
||||
cursor: text;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.thaw-input:hover {
|
||||
|
@ -26,7 +23,12 @@
|
|||
border-bottom-color: var(--colorNeutralStrokeAccessibleHover);
|
||||
}
|
||||
|
||||
.thaw-input:active .thaw-input:focus-within {
|
||||
.thaw-input:focus-within {
|
||||
outline: transparent solid 2px;
|
||||
}
|
||||
|
||||
.thaw-input:active,
|
||||
.thaw-input:focus-within {
|
||||
border-color: var(--colorNeutralStroke1Pressed);
|
||||
border-bottom-color: var(--colorNeutralStrokeAccessiblePressed);
|
||||
}
|
||||
|
@ -56,7 +58,11 @@
|
|||
transition-delay: var(--curveDecelerateMid);
|
||||
}
|
||||
|
||||
.thaw-input__input-el {
|
||||
.r1qp7m7v:focus-within:active::after {
|
||||
border-bottom-color: var(--colorCompoundBrandStrokePressed);
|
||||
}
|
||||
|
||||
.thaw-input__input {
|
||||
align-self: stretch;
|
||||
box-sizing: border-box;
|
||||
flex-grow: 1;
|
||||
|
@ -72,44 +78,51 @@
|
|||
line-height: inherit;
|
||||
}
|
||||
|
||||
.thaw-input--focus,
|
||||
.thaw-input:hover:not(.thaw-input--disabled, .thaw-input--invalid) {
|
||||
border-color: var(--thaw-border-color-hover);
|
||||
.thaw-input__input::placeholder {
|
||||
color: var(--colorNeutralForeground4);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.thaw-input--disabled,
|
||||
.thaw-input--disabled .thaw-input__input-el {
|
||||
.thaw-input--prefix {
|
||||
padding-left: var(--spacingHorizontalMNudge);
|
||||
}
|
||||
|
||||
.thaw-input--prefix > .thaw-input__input {
|
||||
padding-left: var(--spacingHorizontalXXS);
|
||||
}
|
||||
|
||||
.thaw-input--suffix {
|
||||
padding-right: var(--spacingHorizontalMNudge);
|
||||
}
|
||||
|
||||
.thaw-input--suffix > .thaw-input__input {
|
||||
padding-right: var(--spacingHorizontalXXS);
|
||||
}
|
||||
|
||||
.thaw-input__prefix,
|
||||
.thaw-input__suffix {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.thaw-input.thaw-input--disabled {
|
||||
border-color: var(--colorNeutralStrokeDisabled);
|
||||
border-bottom-color: var(--colorNeutralStrokeDisabled);
|
||||
background-color: var(--colorTransparentBackground);
|
||||
cursor: not-allowed;
|
||||
background-color: var(--thaw-background-color-disabled);
|
||||
color: var(--thaw-font-color-disabled);
|
||||
}
|
||||
|
||||
.thaw-input--disabled > .thaw-input__input {
|
||||
background-color: var(--colorTransparentBackground);
|
||||
color: var(--colorNeutralForegroundDisabled);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.thaw-input--disabled > .thaw-input__input::placeholder {
|
||||
color: var(--colorNeutralForegroundDisabled);
|
||||
}
|
||||
|
||||
.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::placeholder {
|
||||
color: var(--thaw-placeholder-color);
|
||||
}
|
||||
|
||||
.thaw-input__prefix {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.thaw-input__suffix {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ mod theme;
|
|||
pub use text_area::{TextArea, TextAreaRef};
|
||||
pub use theme::InputTheme;
|
||||
|
||||
use crate::theme::{use_theme, Theme};
|
||||
use leptos::*;
|
||||
use thaw_utils::{class_list, mount_style, ComponentRef, Model, OptionalProp};
|
||||
|
||||
|
@ -54,10 +53,9 @@ pub fn Input(
|
|||
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
||||
#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
|
||||
) -> impl IntoView {
|
||||
let theme = use_theme(Theme::light);
|
||||
mount_style("input", include_str!("./input.css"));
|
||||
|
||||
let value_trigger = create_trigger();
|
||||
let value_trigger = Trigger::new();
|
||||
let on_input = move |ev| {
|
||||
let input_value = event_target_value(&ev);
|
||||
if let Some(allow_value) = allow_value.as_ref() {
|
||||
|
@ -68,7 +66,7 @@ pub fn Input(
|
|||
}
|
||||
value.set(input_value);
|
||||
};
|
||||
let is_focus = create_rw_signal(false);
|
||||
let is_focus = RwSignal::new(false);
|
||||
let on_internal_focus = move |ev| {
|
||||
is_focus.set(true);
|
||||
if let Some(on_focus) = on_focus.as_ref() {
|
||||
|
@ -82,47 +80,7 @@ pub fn Input(
|
|||
}
|
||||
};
|
||||
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
theme.with(|theme| {
|
||||
let border_color_hover = theme.common.color_primary.clone();
|
||||
css_vars.push_str(&format!("--thaw-border-color-hover: {border_color_hover};"));
|
||||
css_vars.push_str(&format!("--thaw-box-shadow-color: {border_color_hover}33;"));
|
||||
let border_radius = theme.common.border_radius.clone();
|
||||
css_vars.push_str(&format!("--thaw-border-radius: {border_radius};"));
|
||||
css_vars.push_str(&format!(
|
||||
"--thaw-background-color: {};",
|
||||
theme.input.background_color
|
||||
));
|
||||
css_vars.push_str(&format!("--thaw-font-color: {};", theme.input.font_color));
|
||||
css_vars.push_str(&format!(
|
||||
"--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
|
||||
});
|
||||
let input_ref = create_node_ref::<html::Input>();
|
||||
let input_ref = NodeRef::<html::Input>::new();
|
||||
input_ref.on_load(move |_| {
|
||||
comp_ref.load(InputRef { input_ref });
|
||||
});
|
||||
|
@ -166,12 +124,13 @@ pub fn Input(
|
|||
view! {
|
||||
<span
|
||||
class=class_list![
|
||||
"thaw-input", ("thaw-input--focus", move || is_focus.get()),
|
||||
"thaw-input",
|
||||
("thaw-input--prefix", input_prefix.as_ref().map_or(false, |prefix| prefix.if_)),
|
||||
("thaw-input--suffix", input_suffix.as_ref().map_or(false, |suffix| suffix.if_)),
|
||||
("thaw-input--disabled", move || disabled.get()), ("thaw-input--invalid", move ||
|
||||
invalid.get()), class.map(| c | move || c.get())
|
||||
]
|
||||
|
||||
style=move || css_vars.get()
|
||||
on:mousedown=on_mousedown
|
||||
>
|
||||
{if let Some(prefix) = input_prefix.and_then(|prefix| prefix.if_.then_some(prefix)) {
|
||||
|
@ -192,7 +151,7 @@ pub fn Input(
|
|||
on:input=on_input
|
||||
on:focus=on_internal_focus
|
||||
on:blur=on_internal_blur
|
||||
class="thaw-input__input-el"
|
||||
class="thaw-input__input"
|
||||
disabled=move || disabled.get()
|
||||
placeholder=placeholder.map(|p| move || p.get())
|
||||
ref=input_ref
|
||||
|
|
|
@ -16,6 +16,7 @@ pub struct ColorTheme {
|
|||
pub color_neutral_foreground_2_pressed: String,
|
||||
pub color_neutral_foreground_2_brand_hover: String,
|
||||
pub color_neutral_foreground_2_brand_pressed: String,
|
||||
pub color_neutral_foreground_4: String,
|
||||
pub color_neutral_foreground_on_brand: String,
|
||||
|
||||
pub color_neutral_stroke_disabled: String,
|
||||
|
@ -23,6 +24,8 @@ pub struct ColorTheme {
|
|||
pub color_neutral_stroke_1_hover: String,
|
||||
pub color_neutral_stroke_1_pressed: String,
|
||||
pub color_neutral_stroke_accessible: String,
|
||||
pub color_neutral_stroke_accessible_hover: String,
|
||||
pub color_neutral_stroke_accessible_pressed: String,
|
||||
|
||||
pub color_compound_brand_stroke: String,
|
||||
|
||||
|
@ -53,6 +56,7 @@ impl ColorTheme {
|
|||
color_neutral_foreground_2_pressed: "#242424".into(),
|
||||
color_neutral_foreground_2_brand_hover: "#0f6cbd".into(),
|
||||
color_neutral_foreground_2_brand_pressed: "#115ea3".into(),
|
||||
color_neutral_foreground_4: "#707070".into(),
|
||||
color_neutral_foreground_on_brand: "#fff".into(),
|
||||
|
||||
color_neutral_stroke_disabled: "#e0e0e0".into(),
|
||||
|
@ -60,6 +64,8 @@ impl ColorTheme {
|
|||
color_neutral_stroke_1_hover: "#c7c7c7".into(),
|
||||
color_neutral_stroke_1_pressed: "#b3b3b3".into(),
|
||||
color_neutral_stroke_accessible: "#616161".into(),
|
||||
color_neutral_stroke_accessible_hover: "#575757".into(),
|
||||
color_neutral_stroke_accessible_pressed: "#4d4d4d".into(),
|
||||
|
||||
color_compound_brand_stroke: "#0f6cbd".into(),
|
||||
|
||||
|
@ -90,6 +96,7 @@ impl ColorTheme {
|
|||
color_neutral_foreground_2_pressed: "#fff".into(),
|
||||
color_neutral_foreground_2_brand_hover: "#479ef5".into(),
|
||||
color_neutral_foreground_2_brand_pressed: "#2886de".into(),
|
||||
color_neutral_foreground_4: "#999999".into(),
|
||||
color_neutral_foreground_on_brand: "#fff".into(),
|
||||
|
||||
color_neutral_stroke_disabled: "#424242".into(),
|
||||
|
@ -97,6 +104,8 @@ impl ColorTheme {
|
|||
color_neutral_stroke_1_hover: "#757575".into(),
|
||||
color_neutral_stroke_1_pressed: "#6b6b6b".into(),
|
||||
color_neutral_stroke_accessible: "#adadad".into(),
|
||||
color_neutral_stroke_accessible_hover: "#bdbdbd".into(),
|
||||
color_neutral_stroke_accessible_pressed: "#b3b3b3".into(),
|
||||
|
||||
color_compound_brand_stroke: "#479ef5".into(),
|
||||
|
||||
|
|
|
@ -38,14 +38,18 @@ pub struct CommonTheme {
|
|||
pub border_radius_medium: String,
|
||||
pub border_radius_circular: String,
|
||||
|
||||
pub spacing_horizontal_x_x_s: String,
|
||||
pub spacing_horizontal_s_nudge: String,
|
||||
pub spacing_horizontal_s: String,
|
||||
pub spacing_horizontal_m_nudge: String,
|
||||
pub spacing_horizontal_m: String,
|
||||
pub spacing_horizontal_l: String,
|
||||
|
||||
pub duration_ultra_fast: String,
|
||||
pub duration_faster: String,
|
||||
pub duration_normal: String,
|
||||
pub curve_accelerate_mid: String,
|
||||
pub curve_decelerate_mid: String,
|
||||
pub curve_easy_ease: String,
|
||||
|
||||
pub height_tiny: String,
|
||||
|
@ -95,14 +99,18 @@ impl CommonTheme {
|
|||
border_radius_medium: "4px".into(),
|
||||
border_radius_circular: "10000px".into(),
|
||||
|
||||
spacing_horizontal_x_x_s: "2px".into(),
|
||||
spacing_horizontal_s_nudge: "6px".into(),
|
||||
spacing_horizontal_s: "8px".into(),
|
||||
spacing_horizontal_m_nudge: "10px".into(),
|
||||
spacing_horizontal_m: "12px".into(),
|
||||
spacing_horizontal_l: "16px".into(),
|
||||
|
||||
duration_ultra_fast: "50ms".into(),
|
||||
duration_faster: "100ms".into(),
|
||||
duration_normal: "200ms".into(),
|
||||
curve_accelerate_mid: "cubic-bezier(1,0,1,1)".into(),
|
||||
curve_decelerate_mid: "cubic-bezier(0,0,0,1)".into(),
|
||||
curve_easy_ease: "cubic-bezier(0.33,0,0.67,1)".into(),
|
||||
|
||||
height_tiny: "22px".into(),
|
||||
|
|
|
@ -163,6 +163,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoClass for (&'static str, bool) {
|
||||
fn into_class(self) -> Class {
|
||||
if self.1 {
|
||||
Class::String(self.0.into())
|
||||
} else {
|
||||
Class::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoClass for (&'static str, Memo<bool>) {
|
||||
fn into_class(self) -> Class {
|
||||
Class::Fn(self.0.into(), Box::new(move || self.1.get()))
|
||||
|
|
Loading…
Add table
Reference in a new issue