Skip to content

Commit

Permalink
ported use_textarea_autosize
Browse files Browse the repository at this point in the history
  • Loading branch information
maccesch committed Sep 15, 2024
1 parent 406b7b2 commit 49f89bc
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 73 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.14.0-beta4] - 2024-09-15

- Latest changes from version 0.13.4 and 0.13.5 ported

## [0.14.0-beta3] - 2024-09-02

### Breaking Changes 🛠
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "leptos-use"
version = "0.14.0-beta3"
version = "0.14.0-beta4"
edition = "2021"
authors = ["Marc-Stefan Cassola"]
categories = ["gui", "web-programming", "wasm"]
Expand All @@ -27,7 +27,7 @@ http0_2 = { version = "0.2", optional = true, package = "http" }
js-sys = "0.3"
lazy_static = "1"
leptos = "0.7.0-beta5"
leptos_axum = { version = "0.7.0-beta5", optional = true, }
leptos_axum = { version = "0.7.0-beta5", optional = true }
leptos_actix = { version = "0.7.0-beta5", optional = true }
leptos-spin = { version = "0.2", optional = true }
num = { version = "0.4", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion examples/use_textarea_autosize/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[dependencies]
leptos = { version = "0.6", features = ["nightly", "csr"] }
leptos = { workspace = true, features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
Expand Down
14 changes: 8 additions & 6 deletions examples/use_textarea_autosize/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use leptos::*;
use leptos::prelude::*;
use leptos_use::docs::demo_or_body;
use leptos_use::{use_textarea_autosize, UseTextareaAutosizeReturn};

#[component]
fn Demo() -> impl IntoView {
let textarea = create_node_ref::<html::Textarea>();
let textarea = NodeRef::new();

let UseTextareaAutosizeReturn {
content,
Expand All @@ -15,7 +15,7 @@ fn Demo() -> impl IntoView {
view! {
<div class="mb-4">Type, the textarea will grow:</div>
<textarea
value=content
prop:value=content
on:input=move |evt| set_content.set(event_target_value(&evt))
node_ref=textarea
class="resize-none box-border"
Expand All @@ -28,7 +28,9 @@ fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();

mount_to(demo_or_body(), || {
view! { <Demo /> }
})
let unmount_handle = leptos::mount::mount_to(demo_or_body(), || {
view! { <Demo/> }
});

unmount_handle.forget();
}
109 changes: 47 additions & 62 deletions src/use_textarea_autosize.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::core::{ElementMaybeSignal, MaybeRwSignal};
use crate::core::{ElementMaybeSignal, IntoElementMaybeSignal, MaybeRwSignal};
use default_struct_builder::DefaultBuilder;
use leptos::*;
use std::rc::Rc;
use leptos::prelude::*;
use std::sync::Arc;

/// Automatically update the height of a textarea depending on the content.
///
Expand All @@ -14,13 +14,13 @@ use std::rc::Rc;
/// ### Simple example
///
/// ```
/// # use leptos::*;
/// # use leptos::prelude::*;
/// # use leptos::html::Textarea;
/// # use leptos_use::{use_textarea_autosize, UseTextareaAutosizeReturn};
/// #
/// # #[component]
/// # fn Demo() -> impl IntoView {
/// let textarea = create_node_ref::<Textarea>();
/// let textarea = NodeRef::new();
///
/// let UseTextareaAutosizeReturn {
/// content,
Expand All @@ -30,7 +30,7 @@ use std::rc::Rc;
///
/// view! {
/// <textarea
/// value=content
/// prop:value=content
/// on:input=move |evt| set_content.set(event_target_value(&evt))
/// node_ref=textarea
/// class="resize-none"
Expand Down Expand Up @@ -62,13 +62,13 @@ use std::rc::Rc;
/// `style_prop` option to `"min-height"`.
///
/// ```
/// # use leptos::*;
/// # use leptos::prelude::*;
/// # use leptos::html::Textarea;
/// # use leptos_use::{use_textarea_autosize_with_options, UseTextareaAutosizeOptions, UseTextareaAutosizeReturn};
/// #
/// # #[component]
/// # fn Demo() -> impl IntoView {
/// let textarea = create_node_ref::<Textarea>();
/// let textarea = NodeRef::new();
///
/// let UseTextareaAutosizeReturn {
/// content,
Expand All @@ -81,7 +81,7 @@ use std::rc::Rc;
///
/// view! {
/// <textarea
/// value=content
/// prop:value=content
/// on:input=move |evt| set_content.set(event_target_value(&evt))
/// node_ref=textarea
/// class="resize-none"
Expand All @@ -96,36 +96,30 @@ use std::rc::Rc;
///
/// On the server this will always return an empty string as ´content` and a no-op `trigger_resize`.
// #[doc(cfg(feature = "use_textarea_autosize"))]
pub fn use_textarea_autosize<El, T>(el: El) -> UseTextareaAutosizeReturn<impl Fn() + Clone>
pub fn use_textarea_autosize<El, M>(el: El) -> UseTextareaAutosizeReturn<impl Fn() + Clone>
where
El: Into<ElementMaybeSignal<T, web_sys::Element>> + Clone,
T: Into<web_sys::Element> + Clone + 'static,
El: IntoElementMaybeSignal<web_sys::Element, M> + Clone,
{
use_textarea_autosize_with_options::<El, T, web_sys::Element>(
el,
UseTextareaAutosizeOptions::default(),
)
use_textarea_autosize_with_options::<El, M>(el, UseTextareaAutosizeOptions::default())
}

/// Version of [`fn@crate::use_textarea_autosize`] that takes a `UseTextareaAutosizeOptions`. See [`fn@crate::use_textarea_autosize`] for how to use.
// #[doc(cfg(feature = "use_textarea_autosize"))]
pub fn use_textarea_autosize_with_options<El, T, StyleT>(
pub fn use_textarea_autosize_with_options<El, M>(
el: El,
options: UseTextareaAutosizeOptions<StyleT>,
options: UseTextareaAutosizeOptions,
) -> UseTextareaAutosizeReturn<impl Fn() + Clone>
where
El: Into<ElementMaybeSignal<T, web_sys::Element>> + Clone,
T: Into<web_sys::Element> + Clone + 'static,
StyleT: Into<web_sys::Element> + Clone + 'static,
El: IntoElementMaybeSignal<web_sys::Element, M> + Clone,
{
#[cfg(not(feature = "ssr"))]
{
use wasm_bindgen::JsCast;

let el = el.into();
let textarea = Signal::derive(move || {
let el = el.into_element_maybe_signal();
let textarea = Signal::derive_local(move || {
el.get()
.map(|el| el.into().unchecked_into::<web_sys::HtmlTextAreaElement>())
.map(|el| el.unchecked_into::<web_sys::HtmlTextAreaElement>())
});

let UseTextareaAutosizeOptions {
Expand All @@ -138,11 +132,11 @@ where

let (content, set_content) = content.into_signal();

let (textarea_scroll_height, set_textarea_scroll_height) = create_signal(1);
let (textarea_old_width, set_textarea_old_width) = create_signal(0.0);
let (textarea_scroll_height, set_textarea_scroll_height) = signal(1);
let (textarea_old_width, set_textarea_old_width) = signal(0.0);

let trigger_resize = move || {
textarea.with(|textarea| {
textarea.with_untracked(|textarea| {
if let Some(textarea) = textarea {
let mut height = "".to_string();

Expand All @@ -161,13 +155,14 @@ where
0
};

textarea.style().set_property(&style_prop, "1px").ok();
web_sys::HtmlElement::style(textarea)
.set_property(&style_prop, "1px")
.ok();
set_textarea_scroll_height.set(textarea.scroll_height() + border_offset + 1);

if let Some(style_target) = style_target.get() {
// If style target is provided update its height
style_target
.into()
.unchecked_into::<web_sys::HtmlElement>()
.style()
.set_property(
Expand All @@ -180,15 +175,17 @@ where
height = format!("{}px", textarea_scroll_height.get_untracked());
}

textarea.style().set_property(&style_prop, &height).ok();
web_sys::HtmlElement::style(textarea)
.set_property(&style_prop, &height)
.ok();
}
})
};

let _ = watch(
Effect::watch(
move || {
content.track();
textarea.track();
content.with(|_| ());
textarea.with(|_| ());
},
{
let trigger_resize = trigger_resize.clone();
Expand All @@ -200,7 +197,7 @@ where
true,
);

let _ = watch(
Effect::watch(
move || textarea_scroll_height.track(),
move |_, _, _| {
on_resize();
Expand All @@ -223,7 +220,7 @@ where
}
});

let _ = watch(
Effect::watch(
move || watch_fn(),
{
let trigger_resize = trigger_resize.clone();
Expand All @@ -247,7 +244,7 @@ where
let _ = el;
let _ = options;

let (content, set_content) = create_signal("".to_string());
let (content, set_content) = signal("".to_string());

UseTextareaAutosizeReturn {
content: content.into(),
Expand All @@ -261,62 +258,50 @@ where
// #[doc(cfg(feature = "use_textarea_autosize"))]
#[derive(DefaultBuilder)]
#[cfg_attr(feature = "ssr", allow(dead_code))]
pub struct UseTextareaAutosizeOptions<T>
where
T: Into<web_sys::Element> + Clone + 'static,
{
pub struct UseTextareaAutosizeOptions {
/// Textarea content
#[builder(into)]
content: MaybeRwSignal<String>,

/// Watch sources that should trigger a textarea resize
watch: Rc<dyn Fn()>,
watch: Arc<dyn Fn() + Send + Sync>,

/// Function called when the textarea size changes
on_resize: Rc<dyn Fn()>,
on_resize: Arc<dyn Fn() + Send + Sync>,

/// Specify style target to apply the height based on textarea content.
/// If not provided it will use textarea it self.
#[builder(skip)]
style_target: ElementMaybeSignal<T, web_sys::Element>,
style_target: ElementMaybeSignal<web_sys::Element>,

/// Specify the style property that will be used to manipulate height.
/// Should be `"height"` or `"min-height"`. Default value is `"height"`.
#[builder(into)]
style_prop: String,
}

impl Default for UseTextareaAutosizeOptions<web_sys::Element> {
impl Default for UseTextareaAutosizeOptions {
fn default() -> Self {
Self {
content: MaybeRwSignal::default(),
watch: Rc::new(|| ()),
on_resize: Rc::new(|| ()),
watch: Arc::new(|| ()),
on_resize: Arc::new(|| ()),
style_target: Default::default(),
style_prop: "height".to_string(),
}
}
}

impl<T> UseTextareaAutosizeOptions<T>
where
T: Into<web_sys::Element> + Clone + 'static,
{
impl UseTextareaAutosizeOptions {
/// List of elementss that should not trigger the callback. Defaults to `[]`.
#[cfg_attr(feature = "ssr", allow(dead_code))]
pub fn style_target<NewT>(
pub fn style_target<M>(
self,
style_target: impl Into<ElementMaybeSignal<NewT, web_sys::Element>>,
) -> UseTextareaAutosizeOptions<NewT>
where
NewT: Into<web_sys::Element> + Clone + 'static,
{
UseTextareaAutosizeOptions {
content: self.content,
watch: self.watch,
on_resize: self.on_resize,
style_target: style_target.into(),
style_prop: self.style_prop,
style_target: impl IntoElementMaybeSignal<web_sys::Element, M>,
) -> Self {
Self {
style_target: style_target.into_element_maybe_signal(),
..self
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/use_websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ where

let (ready_state, set_ready_state) = signal(ConnectionReadyState::Closed);
let (message, set_message) = signal(None);
let ws_signal = RwSignal::new(None::<WebSocket>);
let ws_signal = RwSignal::new_local(None::<WebSocket>);

let reconnect_timer_ref: StoredValue<Option<TimeoutHandle>> = StoredValue::new(None);

Expand Down Expand Up @@ -716,7 +716,7 @@ where
/// Latest message received from `WebSocket`.
pub message: Signal<Option<Rx>>,
/// The `WebSocket` instance.
pub ws: Signal<Option<WebSocket>>,
pub ws: Signal<Option<WebSocket>, LocalStorage>,
/// Opens the `WebSocket` connection
pub open: OpenFn,
/// Closes the `WebSocket` connection
Expand Down

0 comments on commit 49f89bc

Please sign in to comment.