diff --git a/demo_markdown/docs/textarea/mod.md b/demo_markdown/docs/textarea/mod.md index e1c6417..bf8160f 100644 --- a/demo_markdown/docs/textarea/mod.md +++ b/demo_markdown/docs/textarea/mod.md @@ -22,5 +22,18 @@ view! { } ``` +### Resize + +```rust demo +view! { + + - - } -} - -#[derive(Clone)] -pub struct TextAreaRef { - textarea_ref: NodeRef, -} - -impl TextAreaRef { - pub fn focus(&self) { - if let Some(textarea_el) = self.textarea_ref.get_untracked() { - _ = textarea_el.focus(); - } - } - - pub fn blur(&self) { - if let Some(textarea_el) = self.textarea_ref.get_untracked() { - _ = textarea_el.blur(); - } - } -} diff --git a/thaw/src/textarea/mod.rs b/thaw/src/textarea/mod.rs index ab7515c..d114405 100644 --- a/thaw/src/textarea/mod.rs +++ b/thaw/src/textarea/mod.rs @@ -1,22 +1,23 @@ use leptos::*; -use thaw_utils::{class_list, mount_style, ComponentRef, Model, OptionalProp}; +use thaw_utils::{class_list, mount_style, ComponentRef, Model}; #[component] pub fn Textarea( #[prop(optional, into)] value: Model, #[prop(optional, into)] allow_value: Option>, - #[prop(optional, into)] placeholder: OptionalProp>, + #[prop(optional, into)] placeholder: MaybeProp, #[prop(optional, into)] on_focus: Option>, #[prop(optional, into)] on_blur: Option>, #[prop(optional, into)] disabled: MaybeSignal, - #[prop(optional, into)] invalid: MaybeSignal, - #[prop(optional)] comp_ref: ComponentRef, - #[prop(optional, into)] class: OptionalProp>, + /// Which direction the Textarea is allowed to be resized. + #[prop(optional, into)] resize: MaybeSignal, + #[prop(optional)] comp_ref: ComponentRef, + #[prop(optional, into)] class: MaybeProp, #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>, ) -> impl IntoView { mount_style("textarea", include_str!("./textarea.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() { @@ -27,23 +28,20 @@ pub fn Textarea( } value.set(input_value); }; - let is_focus = create_rw_signal(false); let on_internal_focus = move |ev| { - is_focus.set(true); if let Some(on_focus) = on_focus.as_ref() { on_focus.call(ev); } }; let on_internal_blur = move |ev| { - is_focus.set(false); if let Some(on_blur) = on_blur.as_ref() { on_blur.call(ev); } }; - let textarea_ref = create_node_ref::(); + let textarea_ref = NodeRef::::new(); textarea_ref.on_load(move |_| { - comp_ref.load(TextAreaRef { textarea_ref }); + comp_ref.load(TextareaRef { textarea_ref }); }); #[cfg(debug_assertions)] @@ -62,9 +60,10 @@ pub fn Textarea( view! { @@ -87,11 +86,11 @@ pub fn Textarea( } #[derive(Clone)] -pub struct TextAreaRef { +pub struct TextareaRef { textarea_ref: NodeRef, } -impl TextAreaRef { +impl TextareaRef { pub fn focus(&self) { if let Some(textarea_el) = self.textarea_ref.get_untracked() { _ = textarea_el.focus(); @@ -104,3 +103,23 @@ impl TextAreaRef { } } } + +#[derive(Clone, Default)] +pub enum TextareaResize { + #[default] + None, + Both, + Horizontal, + Vertical, +} + +impl TextareaResize { + pub fn as_str(&self) -> &'static str { + match self { + TextareaResize::None => "none", + TextareaResize::Both => "both", + TextareaResize::Horizontal => "horizontal", + TextareaResize::Vertical => "vertical", + } + } +} diff --git a/thaw/src/textarea/textarea.css b/thaw/src/textarea/textarea.css index c2341e0..f0bafdc 100644 --- a/thaw/src/textarea/textarea.css +++ b/thaw/src/textarea/textarea.css @@ -5,8 +5,8 @@ padding: 0 0 var(--strokeWidthThick) 0; background-color: var(--colorNeutralBackground1); border-radius: var(--borderRadiusMedium); - border-bottom-color: var(--colorNeutralStrokeAccessible); border: var(--strokeWidthThin) solid var(--colorNeutralStroke1); + border-bottom-color: var(--colorNeutralStrokeAccessible); box-sizing: border-box; } @@ -28,18 +28,6 @@ border-bottom-color: var(--colorNeutralStrokeAccessiblePressed); } -/* .thaw-textarea--focus, -.thaw-textarea:hover:not(.thaw-textarea--disabled, .thaw-textarea--invalid) { - border-color: var(--thaw-border-color-hover); -} - -.thaw-textarea--disabled, -.thaw-textarea--disabled .thaw-textarea__textarea-el { - cursor: not-allowed; - background-color: var(--thaw-background-color-disabled); - color: var(--thaw-font-color-disabled); -} */ - .thaw-textarea::after { content: ""; position: absolute; @@ -93,3 +81,30 @@ .thaw-textarea__textarea-el::placeholder { color: var(--thaw-placeholder-color); } + +.thaw-textarea.thaw-textarea--disabled { + background-color: var(--colorTransparentBackground); + border: var(--strokeWidthThin) solid var(--colorNeutralStrokeDisabled); +} + +.thaw-textarea--disabled > .thaw-textarea__textarea { + background-color: var(--colorTransparentBackground); + color: var(--colorNeutralForegroundDisabled); + cursor: not-allowed; +} + +.thaw-textarea--disabled > .thaw-textarea__textarea::placeholder { + color: var(--colorNeutralForegroundDisabled); +} + +.thaw-textarea--resize-vertical > .thaw-textarea__textarea { + resize: vertical; +} + +.thaw-textarea--resize-horizontal > .thaw-textarea__textarea { + resize: horizontal; +} + +.thaw-textarea--resize-both > .thaw-textarea__textarea { + resize: both; +}