mirror of
https://github.com/adoyle0/leptos-use.git
synced 2025-01-23 00:59:22 -05:00
ported use_textarea_autosize
This commit is contained in:
parent
406b7b2e16
commit
49f89bcb36
6 changed files with 64 additions and 73 deletions
|
@ -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 🛠
|
||||
|
|
|
@ -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"]
|
||||
|
@ -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 }
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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();
|
||||
|
@ -200,7 +197,7 @@ where
|
|||
true,
|
||||
);
|
||||
|
||||
let _ = watch(
|
||||
Effect::watch(
|
||||
move || textarea_scroll_height.track(),
|
||||
move |_, _, _| {
|
||||
on_resize();
|
||||
|
@ -223,7 +220,7 @@ where
|
|||
}
|
||||
});
|
||||
|
||||
let _ = watch(
|
||||
Effect::watch(
|
||||
move || watch_fn(),
|
||||
{
|
||||
let trigger_resize = trigger_resize.clone();
|
||||
|
@ -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(),
|
||||
|
@ -261,24 +258,21 @@ 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"`.
|
||||
|
@ -286,37 +280,28 @@ where
|
|||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue